mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-15 08:25:21 +01:00
Implement the Home System (Serenitea Pot)
This commit is contained in:
70
src/main/java/emu/grasscutter/game/home/GameHome.java
Normal file
70
src/main/java/emu/grasscutter/game/home/GameHome.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.IndexOptions;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Entity(value = "homes", useDiscriminator = false)
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Builder(builderMethodName = "of")
|
||||
public class GameHome {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
|
||||
@Indexed(options = @IndexOptions(unique = true))
|
||||
long ownerUid;
|
||||
|
||||
ConcurrentHashMap<Integer, HomeSceneItem> sceneMap;
|
||||
|
||||
public void save(){
|
||||
DatabaseHelper.saveHome(this);
|
||||
}
|
||||
|
||||
public static GameHome getByUid(Integer uid){
|
||||
var home = DatabaseHelper.getHomeByUid(uid);
|
||||
if (home == null) {
|
||||
home = GameHome.create(uid);
|
||||
}
|
||||
return home;
|
||||
}
|
||||
|
||||
public static GameHome create(Integer uid){
|
||||
return GameHome.of()
|
||||
.ownerUid(uid)
|
||||
.sceneMap(new ConcurrentHashMap<>())
|
||||
.build();
|
||||
}
|
||||
|
||||
public HomeSceneItem getHomeSceneItem(int sceneId) {
|
||||
return sceneMap.computeIfAbsent(sceneId, e -> {
|
||||
var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId);
|
||||
if (defaultItem != null){
|
||||
Grasscutter.getLogger().info("Set player {} home {} to initial setting", ownerUid, sceneId);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public void onOwnerLogin(Player player) {
|
||||
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
|
||||
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
|
||||
player.getSession().send(new PacketHomeComfortInfoNotify(player));
|
||||
player.getSession().send(new PacketFurnitureCurModuleArrangeCountNotify());
|
||||
player.getSession().send(new PacketUnlockedFurnitureFormulaDataNotify());
|
||||
}
|
||||
}
|
||||
64
src/main/java/emu/grasscutter/game/home/HomeBlockItem.java
Normal file
64
src/main/java/emu/grasscutter/game/home/HomeBlockItem.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
|
||||
import emu.grasscutter.net.proto.HomeBlockArrangementInfoOuterClass.HomeBlockArrangementInfo;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Builder(builderMethodName = "of")
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeBlockItem {
|
||||
|
||||
@Id
|
||||
int blockId;
|
||||
boolean unlocked;
|
||||
|
||||
List<HomeFurnitureItem> deployFurnitureList;
|
||||
|
||||
|
||||
public void update(HomeBlockArrangementInfo homeBlockArrangementInfo) {
|
||||
this.blockId = homeBlockArrangementInfo.getBlockId();
|
||||
|
||||
this.deployFurnitureList = homeBlockArrangementInfo.getDeployFurniureListList().stream()
|
||||
.map(HomeFurnitureItem::parseFrom)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public int calComfort(){
|
||||
return this.deployFurnitureList.stream()
|
||||
.mapToInt(HomeFurnitureItem::getComfort)
|
||||
.sum();
|
||||
}
|
||||
|
||||
public HomeBlockArrangementInfo toProto() {
|
||||
var proto = HomeBlockArrangementInfo.newBuilder()
|
||||
.setBlockId(blockId)
|
||||
.setIsUnlocked(unlocked)
|
||||
.setComfortValue(calComfort());
|
||||
|
||||
this.deployFurnitureList.forEach(f -> proto.addDeployFurniureList(f.toProto()));
|
||||
|
||||
return proto.build();
|
||||
}
|
||||
|
||||
public static HomeBlockItem parseFrom(HomeworldDefaultSaveData.HomeBlock homeBlock) {
|
||||
|
||||
return HomeBlockItem.of()
|
||||
.blockId(homeBlock.getBlockId())
|
||||
.unlocked(homeBlock.getFurnitures() != null)
|
||||
.deployFurnitureList(
|
||||
homeBlock.getFurnitures() == null ? List.of() :
|
||||
homeBlock.getFurnitures().stream()
|
||||
.map(HomeFurnitureItem::parseFrom)
|
||||
.toList())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.net.proto.HomeFurnitureDataOuterClass;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Builder(builderMethodName = "of")
|
||||
public class HomeFurnitureItem {
|
||||
int furnitureId;
|
||||
int guid;
|
||||
int parentFurnitureIndex;
|
||||
Position spawnPos;
|
||||
Position spawnRot;
|
||||
|
||||
public HomeFurnitureDataOuterClass.HomeFurnitureData toProto(){
|
||||
return HomeFurnitureDataOuterClass.HomeFurnitureData.newBuilder()
|
||||
.setFurnitureId(furnitureId)
|
||||
.setGuid(guid)
|
||||
.setParentFurnitureIndex(parentFurnitureIndex)
|
||||
.setSpawnPos(spawnPos.toProto())
|
||||
.setSpawnRot(spawnRot.toProto())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static HomeFurnitureItem parseFrom(HomeFurnitureDataOuterClass.HomeFurnitureData homeFurnitureData) {
|
||||
return HomeFurnitureItem.of()
|
||||
.furnitureId(homeFurnitureData.getFurnitureId())
|
||||
.guid(homeFurnitureData.getGuid())
|
||||
.parentFurnitureIndex(homeFurnitureData.getParentFurnitureIndex())
|
||||
.spawnPos(new Position(homeFurnitureData.getSpawnPos()))
|
||||
.spawnRot(new Position(homeFurnitureData.getSpawnRot()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static HomeFurnitureItem parseFrom(HomeworldDefaultSaveData.HomeFurniture homeFurniture) {
|
||||
return HomeFurnitureItem.of()
|
||||
.furnitureId(homeFurniture.getId())
|
||||
.parentFurnitureIndex(1)
|
||||
.spawnPos(homeFurniture.getPos() == null ? new Position() : homeFurniture.getPos())
|
||||
.spawnRot(homeFurniture.getRot() == null ? new Position() : homeFurniture.getRot())
|
||||
.build();
|
||||
}
|
||||
|
||||
public ItemData getAsItem() {
|
||||
return GameData.getItemDataMap().get(this.furnitureId);
|
||||
}
|
||||
|
||||
public int getComfort() {
|
||||
var item = getAsItem();
|
||||
|
||||
if (item == null){
|
||||
return 0;
|
||||
}
|
||||
return item.getComfort();
|
||||
}
|
||||
}
|
||||
91
src/main/java/emu/grasscutter/game/home/HomeSceneItem.java
Normal file
91
src/main/java/emu/grasscutter/game/home/HomeSceneItem.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
|
||||
import emu.grasscutter.net.proto.HomeBasicInfoOuterClass.HomeBasicInfo;
|
||||
import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Builder(builderMethodName = "of")
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeSceneItem {
|
||||
@Id
|
||||
int sceneId;
|
||||
Map<Integer, HomeBlockItem> blockItems;
|
||||
Position bornPos;
|
||||
Position bornRot;
|
||||
Position djinnPos;
|
||||
HomeFurnitureItem mainHouse;
|
||||
|
||||
public static HomeSceneItem parseFrom(HomeworldDefaultSaveData defaultItem, int sceneId) {
|
||||
return HomeSceneItem.of()
|
||||
.sceneId(sceneId)
|
||||
.blockItems(defaultItem.getHomeBlockLists().stream()
|
||||
.map(HomeBlockItem::parseFrom)
|
||||
.collect(Collectors.toMap(HomeBlockItem::getBlockId, y -> y)))
|
||||
.bornPos(defaultItem.getBornPos())
|
||||
.bornRot(defaultItem.getBornRot() == null ? new Position() : defaultItem.getBornRot())
|
||||
.djinnPos(defaultItem.getDjinPos() == null ? new Position() : defaultItem.getDjinPos())
|
||||
.mainHouse(defaultItem.getMainhouse() == null ? null :
|
||||
HomeFurnitureItem.parseFrom(defaultItem.getMainhouse()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public void update(HomeSceneArrangementInfo arrangementInfo){
|
||||
for(var blockItem : arrangementInfo.getBlockArrangementInfoListList()){
|
||||
var block = this.blockItems.get(blockItem.getBlockId());
|
||||
if(block == null){
|
||||
System.out.println(111);
|
||||
continue;
|
||||
}
|
||||
block.update(blockItem);
|
||||
this.blockItems.put(blockItem.getBlockId(), block);
|
||||
}
|
||||
|
||||
this.bornPos = new Position(arrangementInfo.getBornPos());
|
||||
this.bornRot = new Position(arrangementInfo.getBornRot());
|
||||
this.djinnPos = new Position(arrangementInfo.getDjinnPos());
|
||||
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());
|
||||
}
|
||||
|
||||
public int getRoomSceneId(){
|
||||
if(mainHouse == null || mainHouse.getAsItem() == null){
|
||||
return 0;
|
||||
}
|
||||
return mainHouse.getAsItem().getRoomSceneId();
|
||||
}
|
||||
|
||||
public int calComfort(){
|
||||
return this.blockItems.values().stream()
|
||||
.mapToInt(HomeBlockItem::calComfort)
|
||||
.sum();
|
||||
}
|
||||
|
||||
public HomeSceneArrangementInfo toProto(){
|
||||
var proto = HomeSceneArrangementInfo.newBuilder();
|
||||
blockItems.values().forEach(b -> proto.addBlockArrangementInfoList(b.toProto()));
|
||||
|
||||
proto.setComfortValue(calComfort())
|
||||
.setBornPos(bornPos.toProto())
|
||||
.setBornRot(bornRot.toProto())
|
||||
.setDjinnPos(djinnPos.toProto())
|
||||
.setSceneId(sceneId)
|
||||
.setTmpVersion(1);
|
||||
|
||||
if(mainHouse != null){
|
||||
proto.setMainHouse(mainHouse.toProto());
|
||||
}
|
||||
return proto.build();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user