From dbc45f36f021a11c513cf8fb79b78112441ba581 Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Tue, 29 Aug 2023 23:48:51 -0400 Subject: [PATCH] Add `PlayerSwitchAvatarEvent` --- .../grasscutter/game/player/TeamManager.java | 40 ++++++++++++++----- .../event/player/PlayerSwitchAvatarEvent.java | 37 +++++++++++++++++ 2 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/main/java/emu/grasscutter/server/event/player/PlayerSwitchAvatarEvent.java diff --git a/src/main/java/emu/grasscutter/game/player/TeamManager.java b/src/main/java/emu/grasscutter/game/player/TeamManager.java index cf38cc8e3..669e7bb11 100644 --- a/src/main/java/emu/grasscutter/game/player/TeamManager.java +++ b/src/main/java/emu/grasscutter/game/player/TeamManager.java @@ -1,7 +1,5 @@ package emu.grasscutter.game.player; -import static emu.grasscutter.config.Configuration.GAME_OPTIONS; - import dev.morphia.annotations.*; import emu.grasscutter.*; import emu.grasscutter.data.GameData; @@ -18,14 +16,17 @@ import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType; import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord.GrantReason; import emu.grasscutter.server.event.entity.EntityCreationEvent; -import emu.grasscutter.server.event.player.PlayerTeamDeathEvent; +import emu.grasscutter.server.event.player.*; import emu.grasscutter.server.packet.send.*; import emu.grasscutter.utils.Utils; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import lombok.*; + import java.util.*; import java.util.stream.Stream; -import lombok.*; + +import static emu.grasscutter.config.Configuration.GAME_OPTIONS; @Entity public final class TeamManager extends BasePlayerDataManager { @@ -187,7 +188,7 @@ public final class TeamManager extends BasePlayerDataManager { public EntityAvatar getCurrentAvatarEntity() { // Check if any avatars are equipped. - if (this.getActiveTeam().size() == 0) return null; + if (this.getActiveTeam().isEmpty()) return null; if (this.currentCharacterIndex >= this.getActiveTeam().size()) { this.currentCharacterIndex = 0; // Reset to the first character. @@ -424,15 +425,23 @@ public final class TeamManager extends BasePlayerDataManager { } // Check if character changed - if (currentEntity != this.getCurrentAvatarEntity()) { + var newAvatarEntity = this.getCurrentAvatarEntity(); + if (currentEntity != null && + newAvatarEntity != null && + currentEntity != newAvatarEntity) { + // Call PlayerSwitchAvatarEvent. + var event = new PlayerSwitchAvatarEvent(this.getPlayer(), + currentEntity.getAvatar(), newAvatarEntity.getAvatar()); + if (!event.call()) return; + // Remove and Add - this.getPlayer().getScene().replaceEntity(currentEntity, this.getCurrentAvatarEntity()); + this.getPlayer().getScene().replaceEntity(currentEntity, newAvatarEntity); } } public synchronized void setupAvatarTeam(int teamId, List list) { // Sanity checks - if (list.size() == 0 + if (list.isEmpty() || list.size() > this.getMaxTeamSize() || this.getPlayer().isInMultiplayer()) { return; @@ -732,10 +741,14 @@ public final class TeamManager extends BasePlayerDataManager { this.getPlayer().sendPacket(new PacketChangeTeamNameRsp(teamId, teamName)); } + /** + * Swaps the current avatar in the scene. + * + * @param guid The GUID of the avatar to swap to. + */ public synchronized void changeAvatar(long guid) { EntityAvatar oldEntity = this.getCurrentAvatarEntity(); - - if (guid == oldEntity.getAvatar().getGuid()) { + if (oldEntity == null || guid == oldEntity.getAvatar().getGuid()) { return; } @@ -752,6 +765,13 @@ public final class TeamManager extends BasePlayerDataManager { return; } + // Call PlayerSwitchAvatarEvent. + var event = new PlayerSwitchAvatarEvent(this.getPlayer(), + oldEntity.getAvatar(), newEntity.getAvatar()); + if (!event.call()) return; + + newEntity = event.getNewAvatarEntity(); + // Set index this.setCurrentCharacterIndex(index); diff --git a/src/main/java/emu/grasscutter/server/event/player/PlayerSwitchAvatarEvent.java b/src/main/java/emu/grasscutter/server/event/player/PlayerSwitchAvatarEvent.java new file mode 100644 index 000000000..c3349fdbc --- /dev/null +++ b/src/main/java/emu/grasscutter/server/event/player/PlayerSwitchAvatarEvent.java @@ -0,0 +1,37 @@ +package emu.grasscutter.server.event.player; + +import emu.grasscutter.game.avatar.Avatar; +import emu.grasscutter.game.entity.EntityAvatar; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.server.event.Cancellable; +import emu.grasscutter.server.event.types.PlayerEvent; +import lombok.*; + +@Getter +public final class PlayerSwitchAvatarEvent extends PlayerEvent implements Cancellable { + private final Avatar previousAvatar; + @Setter private Avatar newAvatar; + + public PlayerSwitchAvatarEvent(Player player, + Avatar previousAvatar, + Avatar newAvatar) { + super(player); + + this.previousAvatar = previousAvatar; + this.newAvatar = newAvatar; + } + + /** + * @return The previous avatar as an entity. + */ + public EntityAvatar getPreviousAvatarEntity() { + return this.previousAvatar.getAsEntity(); + } + + /** + * @return The new avatar as an entity. + */ + public EntityAvatar getNewAvatarEntity() { + return this.newAvatar.getAsEntity(); + } +}