From 0db69882a309702c5137581123706bcc37097438 Mon Sep 17 00:00:00 2001 From: hamusuke Date: Sat, 2 Sep 2023 09:31:55 +0900 Subject: [PATCH] fix: sync home avatar costume (#2326) --- .../game/avatar/AvatarStorage.java | 25 +++++++++++++------ .../emu/grasscutter/game/home/GameHome.java | 23 ++++++++++++++++- .../grasscutter/game/home/HomeNPCItem.java | 9 ++++--- .../PacketHomeAvatarCostumeChangeNotify.java | 15 +++++++++++ 4 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeAvatarCostumeChangeNotify.java diff --git a/src/main/java/emu/grasscutter/game/avatar/AvatarStorage.java b/src/main/java/emu/grasscutter/game/avatar/AvatarStorage.java index 0a238f5f6..fe35557ee 100644 --- a/src/main/java/emu/grasscutter/game/avatar/AvatarStorage.java +++ b/src/main/java/emu/grasscutter/game/avatar/AvatarStorage.java @@ -1,17 +1,23 @@ package emu.grasscutter.game.avatar; import emu.grasscutter.data.GameData; -import emu.grasscutter.data.excels.avatar.*; +import emu.grasscutter.data.excels.avatar.AvatarData; +import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData; import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.inventory.GameItem; -import emu.grasscutter.game.player.*; +import emu.grasscutter.game.player.BasePlayerManager; +import emu.grasscutter.game.player.Player; import emu.grasscutter.server.event.entity.EntityCreationEvent; -import emu.grasscutter.server.packet.send.*; -import it.unimi.dsi.fastutil.ints.*; -import it.unimi.dsi.fastutil.longs.*; +import emu.grasscutter.server.packet.send.PacketAvatarChangeCostumeNotify; +import emu.grasscutter.server.packet.send.PacketAvatarFlycloakChangeNotify; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.util.*; +import java.util.Iterator; +import java.util.List; public class AvatarStorage extends BasePlayerManager implements Iterable { private final Int2ObjectMap avatars; @@ -114,11 +120,14 @@ public class AvatarStorage extends BasePlayerManager implements Iterable entity = EntityCreationEvent.call( EntityAvatar.class, new Class[] {Avatar.class}, new Object[] {avatar}); - getPlayer().sendPacket(new PacketAvatarChangeCostumeNotify(entity)); + getPlayer().getWorld().broadcastPacket(new PacketAvatarChangeCostumeNotify(entity)); } else { - getPlayer().getScene().broadcastPacket(new PacketAvatarChangeCostumeNotify(entity)); + getPlayer().getWorld().broadcastPacket(new PacketAvatarChangeCostumeNotify(entity)); } + // Notify costume change to HomeWorld + this.getPlayer().getHome().onPlayerChangedAvatarCostume(avatar); + // Done return true; } diff --git a/src/main/java/emu/grasscutter/game/home/GameHome.java b/src/main/java/emu/grasscutter/game/home/GameHome.java index bcc2d68f0..47ce2b54c 100644 --- a/src/main/java/emu/grasscutter/game/home/GameHome.java +++ b/src/main/java/emu/grasscutter/game/home/GameHome.java @@ -6,11 +6,14 @@ import emu.grasscutter.data.GameData; import emu.grasscutter.data.excels.HomeWorldLevelData; import emu.grasscutter.data.excels.scene.SceneData; import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.SceneType; import emu.grasscutter.server.packet.send.*; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import lombok.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; import lombok.experimental.FieldDefaults; import java.time.ZonedDateTime; @@ -102,6 +105,24 @@ public class GameHome { player.getSession().send(new PacketHomeResourceNotify(player)); } + public void onPlayerChangedAvatarCostume(Avatar avatar) { + var world = this.player.getServer().getHomeWorldOrCreate(this.player); + world.broadcastPacket(new PacketHomeAvatarCostumeChangeNotify(avatar.getAvatarId(), avatar.getCostume())); + + this.sceneMap.values().stream() + .map(HomeSceneItem::getBlockItems) + .map(Map::values) + .flatMap(Collection::stream) + .map(HomeBlockItem::getDeployNPCList) + .flatMap(Collection::stream) + .filter(homeNPCItem -> homeNPCItem.getAvatarId() == avatar.getAvatarId()) + .forEach(homeNPCItem -> homeNPCItem.setCostumeId(avatar.getCostume())); + + this.save(); + + world.getPlayers().forEach(player -> player.sendPacket(new PacketHomeMarkPointNotify(player))); + } + // Tell the client the reward is claimed or realm unlocked public void onClaimReward(Player player) { player.getSession().send(new PacketPlayerHomeCompInfoNotify(player)); diff --git a/src/main/java/emu/grasscutter/game/home/HomeNPCItem.java b/src/main/java/emu/grasscutter/game/home/HomeNPCItem.java index f4d4d54a9..3a1795a5f 100644 --- a/src/main/java/emu/grasscutter/game/home/HomeNPCItem.java +++ b/src/main/java/emu/grasscutter/game/home/HomeNPCItem.java @@ -3,8 +3,12 @@ package emu.grasscutter.game.home; import dev.morphia.annotations.Entity; import emu.grasscutter.data.GameData; import emu.grasscutter.game.world.Position; -import emu.grasscutter.net.proto.*; -import lombok.*; +import emu.grasscutter.net.proto.HomeMarkPointFurnitureDataOuterClass; +import emu.grasscutter.net.proto.HomeMarkPointNPCDataOuterClass; +import emu.grasscutter.net.proto.HomeNpcDataOuterClass; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; import lombok.experimental.FieldDefaults; import org.jetbrains.annotations.Nullable; @@ -24,7 +28,6 @@ public class HomeNPCItem implements HomeMarkPointProtoFactory { .avatarId(homeNpcData.getAvatarId()) .spawnPos(new Position(homeNpcData.getSpawnPos())) .spawnRot(new Position(homeNpcData.getSpawnRot())) - .costumeId(homeNpcData.getCostumeId()) .build(); } diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeAvatarCostumeChangeNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeAvatarCostumeChangeNotify.java new file mode 100644 index 000000000..4533b38e1 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeAvatarCostumeChangeNotify.java @@ -0,0 +1,15 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.HomeAvatarCostumeChangeNotifyOuterClass; + +public class PacketHomeAvatarCostumeChangeNotify extends BasePacket { + public PacketHomeAvatarCostumeChangeNotify(int avatarId, int costumeId) { + super(PacketOpcodes.HomeAvatarCostumeChangeNotify); + + this.setData(HomeAvatarCostumeChangeNotifyOuterClass.HomeAvatarCostumeChangeNotify.newBuilder() + .setAvatarId(avatarId) + .setCostumeId(costumeId)); + } +}