From 696c995c42902b688a03071c303baf1bf7f92233 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Sun, 1 Oct 2023 02:37:09 -0700 Subject: [PATCH] Handle player death --- .../emu/lunarcore/data/config/FloorInfo.java | 9 +++- .../lunarcore/game/battle/BattleService.java | 43 +++++++++++++++---- .../emu/lunarcore/game/player/Player.java | 11 +++++ .../java/emu/lunarcore/game/scene/Scene.java | 3 +- .../send/PacketSceneEntityMoveScNotify.java | 22 ++++++++++ 5 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 src/main/java/emu/lunarcore/server/packet/send/PacketSceneEntityMoveScNotify.java diff --git a/src/main/java/emu/lunarcore/data/config/FloorInfo.java b/src/main/java/emu/lunarcore/data/config/FloorInfo.java index 70b2446..7b043db 100644 --- a/src/main/java/emu/lunarcore/data/config/FloorInfo.java +++ b/src/main/java/emu/lunarcore/data/config/FloorInfo.java @@ -14,9 +14,12 @@ import lombok.Getter; @Getter public class FloorInfo { private int FloorID; + private int StartGroupID; + private int StartAnchorID; + @SerializedName(value = "GroupList") private List SimpleGroupList; - + // Cached data private transient boolean loaded; private transient Int2ObjectMap groups; @@ -29,6 +32,10 @@ public class FloorInfo { this.unlockedCheckpoints = new ArrayList<>(); } + public AnchorInfo getStartAnchorInfo() { + return getAnchorInfo(StartGroupID, StartAnchorID); + } + public AnchorInfo getAnchorInfo(int groupId, int anchorId) { GroupInfo group = this.getGroups().get(groupId); if (group == null) return null; diff --git a/src/main/java/emu/lunarcore/game/battle/BattleService.java b/src/main/java/emu/lunarcore/game/battle/BattleService.java index 27c5e9c..363a0b0 100644 --- a/src/main/java/emu/lunarcore/game/battle/BattleService.java +++ b/src/main/java/emu/lunarcore/game/battle/BattleService.java @@ -106,6 +106,7 @@ public class BattleService extends BaseGameService { // Create battle and add npc monsters to it Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages); battle.getNpcMonsters().addAll(monsters); + // Add weakness buff to battle if (isPlayerCaster) { GameAvatar avatar = player.getLineupManager().getCurrentLeaderAvatar(); @@ -116,6 +117,7 @@ public class BattleService extends BaseGameService { } } } + // Set battle and send rsp packet player.setBattle(battle); player.sendPacket(new PacketSceneCastSkillScRsp(battle)); @@ -175,10 +177,33 @@ public class BattleService extends BaseGameService { return; } - // Get battle object + // Get battle object and setup variables Battle battle = player.getBattle(); + int minimumHp = 0; + boolean teleportToAnchor = false; - // Set health/energy + // Handle result + switch (result) { + case BATTLE_END_WIN -> { + // Remove monsters from the map - Could optimize it a little better + for (var monster : battle.getNpcMonsters()) { + player.getScene().removeEntity(monster); + } + } + case BATTLE_END_LOSE -> { + // Set avatar hp to 20% if the player's party is downed + minimumHp = 2000; + teleportToAnchor = true; + } + case BATTLE_END_QUIT -> { + teleportToAnchor = true; + } + default -> { + + } + } + + // Set health/energy for player avatars for (var battleAvatar : battleAvatars) { GameAvatar avatar = player.getAvatarById(battleAvatar.getId()); if (avatar == null) continue; @@ -187,19 +212,19 @@ public class BattleService extends BaseGameService { int currentHp = (int) Math.round((prop.getLeftHp() / prop.getMaxHp()) * 100); int currentSp = (int) prop.getLeftSp() * 100; - //avatar.setCurrentHp(currentHp); - avatar.setCurrentSp(currentSp); + avatar.setCurrentHp(Math.max(currentHp, minimumHp)); + avatar.setCurrentSp(Math.max(currentSp, 0)); avatar.save(); } // Sync with player player.sendPacket(new PacketSyncLineupNotify(battle.getLineup())); - // Delete enemies if the player won - if (result == BattleEndStatus.BATTLE_END_WIN) { - // Could optimize it a little better - for (var monster : battle.getNpcMonsters()) { - player.getScene().removeEntity(monster); + // Teleport to anchor if player has lost/retreated. On official servers, the player party is teleported to the nearest anchor. + if (teleportToAnchor) { + var anchor = player.getScene().getFloorInfo().getStartAnchorInfo(); + if (anchor != null) { + player.moveTo(anchor.clonePos()); } } diff --git a/src/main/java/emu/lunarcore/game/player/Player.java b/src/main/java/emu/lunarcore/game/player/Player.java index debdea8..f746ebb 100644 --- a/src/main/java/emu/lunarcore/game/player/Player.java +++ b/src/main/java/emu/lunarcore/game/player/Player.java @@ -33,6 +33,7 @@ import emu.lunarcore.server.packet.SessionState; import emu.lunarcore.server.packet.send.PacketEnterSceneByServerScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketRevcMsgScNotify; +import emu.lunarcore.server.packet.send.PacketSceneEntityMoveScNotify; import emu.lunarcore.util.Position; import lombok.Getter; @@ -305,6 +306,16 @@ public class Player { this.battle = battle; } + public void moveTo(int entryId, Position pos) { + this.entryId = entryId; + this.moveTo(pos); + } + + public void moveTo(Position pos) { + this.getPos().set(pos); + this.sendPacket(new PacketSceneEntityMoveScNotify(this)); + } + public void enterScene(int entryId, int teleportId, boolean sendPacket) { // Get map entrance excel MapEntranceExcel entry = GameData.getMapEntranceExcelMap().get(entryId); diff --git a/src/main/java/emu/lunarcore/game/scene/Scene.java b/src/main/java/emu/lunarcore/game/scene/Scene.java index fd8045a..3e4b8c6 100644 --- a/src/main/java/emu/lunarcore/game/scene/Scene.java +++ b/src/main/java/emu/lunarcore/game/scene/Scene.java @@ -29,6 +29,7 @@ import lombok.Getter; public class Scene { private final Player player; private final MazePlaneExcel excel; + private final FloorInfo floorInfo; private final int planeId; private final int floorId; private int entryId; @@ -67,7 +68,7 @@ public class Scene { } // Spawn monsters - FloorInfo floorInfo = GameData.getFloorInfo(this.planeId, this.floorId); + this.floorInfo = GameData.getFloorInfo(this.planeId, this.floorId); if (floorInfo == null) return; for (GroupInfo group : floorInfo.getGroups().values()) { diff --git a/src/main/java/emu/lunarcore/server/packet/send/PacketSceneEntityMoveScNotify.java b/src/main/java/emu/lunarcore/server/packet/send/PacketSceneEntityMoveScNotify.java new file mode 100644 index 0000000..5f45c18 --- /dev/null +++ b/src/main/java/emu/lunarcore/server/packet/send/PacketSceneEntityMoveScNotify.java @@ -0,0 +1,22 @@ +package emu.lunarcore.server.packet.send; + +import emu.lunarcore.game.player.Player; +import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo; +import emu.lunarcore.proto.SceneEntityMoveScNotifyOuterClass.SceneEntityMoveScNotify; +import emu.lunarcore.proto.VectorOuterClass.Vector; +import emu.lunarcore.server.packet.BasePacket; +import emu.lunarcore.server.packet.CmdId; + +public class PacketSceneEntityMoveScNotify extends BasePacket { + + public PacketSceneEntityMoveScNotify(Player player) { + super(CmdId.SceneEntityMoveScNotify); + + var data = SceneEntityMoveScNotify.newInstance() + .setEntryId(player.getEntryId()) + .setMotion(MotionInfo.newInstance().setPos(player.getPos().toProto()).setRot(Vector.newInstance())); + + this.setData(data); + } + +}