fix: arrangement of main house is duplicated even if player changes module (#2325)

* fix: arrangement of main house is duplicated even if player change module

* removeIf

* Update src/main/java/emu/grasscutter/game/home/GameHome.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
This commit is contained in:
hamusuke
2023-09-03 00:52:56 +09:00
committed by GitHub
parent decf494234
commit ed97201473
9 changed files with 126 additions and 52 deletions

View File

@@ -12,6 +12,7 @@ import emu.grasscutter.game.props.SceneType;
import emu.grasscutter.net.proto.HomeAvatarTalkFinishInfoOuterClass;
import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
@@ -51,6 +52,7 @@ public class GameHome {
int storedFetterExp;
List<FurnitureMakeSlotItem> furnitureMakeSlotItemList;
ConcurrentHashMap<Integer, HomeSceneItem> sceneMap;
ConcurrentHashMap<Integer, HomeSceneItem> mainHouseMap;
Set<Integer> unlockedHomeBgmList;
int enterHomeOption;
Map<Integer, Set<Integer>> finishedTalkIdMap;
@@ -60,6 +62,9 @@ public class GameHome {
if (home == null) {
home = GameHome.create(uid);
}
home.fixMainHouseIfOld();
return home;
}
@@ -69,12 +74,25 @@ public class GameHome {
public static GameHome create(Integer uid) {
return GameHome.of()
.ownerUid(uid)
.level(1)
.sceneMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.finishedTalkIdMap(new HashMap<>())
.build();
.ownerUid(uid)
.level(1)
.sceneMap(new ConcurrentHashMap<>())
.mainHouseMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.finishedTalkIdMap(new HashMap<>())
.build();
}
// Data fixer.
private void fixMainHouseIfOld() {
if (this.getMainHouseMap() == null) {
Grasscutter.getLogger().debug("Player {}'s main house will be deleted due to GC update! (ps. sorry XD)", this.getPlayer().getUid());
this.mainHouseMap = new ConcurrentHashMap<>(); // assign.
}
this.getSceneMap().values().removeIf(homeSceneItem -> homeSceneItem.getSceneId() > 2200);
this.save();
}
public void save() {
@@ -82,6 +100,10 @@ public class GameHome {
}
public HomeSceneItem getHomeSceneItem(int sceneId) {
if (sceneId >= 2200) {
return this.getMainHouseItem(this.getPlayer().getCurrentRealmId() + 2000);
}
return sceneMap.computeIfAbsent(
sceneId,
e -> {
@@ -98,8 +120,31 @@ public class GameHome {
});
}
public HomeSceneItem getMainHouseItem(int outdoorSceneId) {
return this.getMainHouseMap().computeIfAbsent(outdoorSceneId, integer -> {
var curHomeSceneItem = this.getHomeSceneItem(outdoorSceneId);
var roomSceneId = curHomeSceneItem.getRoomSceneId();
var defaultItem = GameData.getHomeworldDefaultSaveData().get(roomSceneId);
if (defaultItem == null) {
Grasscutter.getLogger().info("defaultItem == null! returns Liyue style house.");
return HomeSceneItem.parseFrom(GameData.getHomeworldDefaultSaveData().get(2202), 2202); // Liyue style
}
Grasscutter.getLogger().info("Set player {} main house {} to initial setting", this.ownerUid, roomSceneId);
return HomeSceneItem.parseFrom(defaultItem, roomSceneId);
});
}
public void onMainHouseChanged() {
Grasscutter.getLogger().debug("main house changed!");
var outdoor = this.getPlayer().getCurrentRealmId() + 2000;
this.getMainHouseMap().remove(outdoor); // delete main house in current scene.
this.getMainHouseItem(outdoor); // put new main house with default arrangement.
this.save();
}
public void onOwnerLogin(Player player) {
if (this.player == null) this.player = player;
this.player = player; // update player pointer. (prevent offline player from sending packet)
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
player.getSession().send(new PacketHomeComfortInfoNotify(player));
@@ -273,19 +318,19 @@ public class GameHome {
});
// Check as realm 5 inside is not in defaults and will be null
if (Objects.nonNull(sceneMap.get(player.getCurrentRealmId() + 2200))) {
if (Objects.nonNull(mainHouseMap.get(player.getCurrentRealmId() + 2000))) {
// Indoors avatars
sceneMap
.get(player.getCurrentRealmId() + 2200)
.getBlockItems()
.forEach(
(i, e) -> {
e.getDeployNPCList()
.forEach(
id -> {
invitedAvatars.add(id.getAvatarId());
});
});
mainHouseMap
.get(player.getCurrentRealmId() + 2000)
.getBlockItems()
.forEach(
(i, e) -> {
e.getDeployNPCList()
.forEach(
id -> {
invitedAvatars.add(id.getAvatarId());
});
});
}
// Add exp to all avatars

View File

@@ -5,6 +5,7 @@ import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.net.proto.*;
import java.util.Set;
import java.util.stream.Collectors;
@@ -65,7 +66,7 @@ public class HomeFurnitureItem implements HomeMarkPointProtoFactory {
}
public ItemData getAsItem() {
return GameData.getItemDataMap().get(this.furnitureId);
return this.furnitureId == 0 ? null : GameData.getItemDataMap().get(this.furnitureId);
}
public int getComfort() {

View File

@@ -9,6 +9,7 @@ import emu.grasscutter.game.entity.EntityHomeAnimal;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -62,7 +63,11 @@ public class HomeSceneItem {
this.bornRot = new Position(arrangementInfo.getBornRot());
this.djinnPos = new Position(arrangementInfo.getDjinnPos());
this.homeBgmId = arrangementInfo.getBgmId();
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());
if (!this.isRoom() && arrangementInfo.hasMainHouse()) {
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());
}
this.tmpVersion = arrangementInfo.getTmpVersion();
}