From 51f0ee4ad8202916f1a3e761fb0a564850d4b888 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Tue, 26 Sep 2023 05:13:58 -0700 Subject: [PATCH] Implement support for npcs --- .../java/emu/lunarcore/data/GameData.java | 1 + .../emu/lunarcore/data/config/GroupInfo.java | 2 + .../emu/lunarcore/data/config/NpcInfo.java | 8 +++ .../emu/lunarcore/data/excel/NpcExcel.java | 17 +++++ .../emu/lunarcore/game/scene/EntityNpc.java | 41 ++++++++++++ .../emu/lunarcore/game/scene/GameEntity.java | 6 ++ .../java/emu/lunarcore/game/scene/Scene.java | 63 ++++++++++++------- 7 files changed, 116 insertions(+), 22 deletions(-) create mode 100644 src/main/java/emu/lunarcore/data/config/NpcInfo.java create mode 100644 src/main/java/emu/lunarcore/data/excel/NpcExcel.java create mode 100644 src/main/java/emu/lunarcore/game/scene/EntityNpc.java diff --git a/src/main/java/emu/lunarcore/data/GameData.java b/src/main/java/emu/lunarcore/data/GameData.java index b0192a8..eb6c018 100644 --- a/src/main/java/emu/lunarcore/data/GameData.java +++ b/src/main/java/emu/lunarcore/data/GameData.java @@ -19,6 +19,7 @@ public class GameData { @Getter private static Int2ObjectMap equipExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap relicExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap monsterExcelMap = new Int2ObjectOpenHashMap<>(); + @Getter private static Int2ObjectMap npcExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap npcMonsterExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap stageExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap mapEntranceExcelMap = new Int2ObjectOpenHashMap<>(); diff --git a/src/main/java/emu/lunarcore/data/config/GroupInfo.java b/src/main/java/emu/lunarcore/data/config/GroupInfo.java index 59f56be..863dfea 100644 --- a/src/main/java/emu/lunarcore/data/config/GroupInfo.java +++ b/src/main/java/emu/lunarcore/data/config/GroupInfo.java @@ -9,10 +9,12 @@ public class GroupInfo { private transient int id; private GroupLoadSide LoadSide; private boolean LoadOnInitial; + private int OwnerMainMissionID; private List AnchorList; private List MonsterList; private List PropList; + private List NPCList; public void setId(int id) { if (this.id == 0) this.id = id; diff --git a/src/main/java/emu/lunarcore/data/config/NpcInfo.java b/src/main/java/emu/lunarcore/data/config/NpcInfo.java new file mode 100644 index 0000000..fedae2b --- /dev/null +++ b/src/main/java/emu/lunarcore/data/config/NpcInfo.java @@ -0,0 +1,8 @@ +package emu.lunarcore.data.config; + +import lombok.Getter; + +@Getter +public class NpcInfo extends ObjectInfo { + private int NPCID; +} diff --git a/src/main/java/emu/lunarcore/data/excel/NpcExcel.java b/src/main/java/emu/lunarcore/data/excel/NpcExcel.java new file mode 100644 index 0000000..ca7b497 --- /dev/null +++ b/src/main/java/emu/lunarcore/data/excel/NpcExcel.java @@ -0,0 +1,17 @@ +package emu.lunarcore.data.excel; + +import emu.lunarcore.data.GameResource; +import emu.lunarcore.data.ResourceType; +import lombok.Getter; + +@Getter +@ResourceType(name = {"NPCData.json"}) +public class NpcExcel extends GameResource { + private int ID; + + @Override + public int getId() { + return ID; + } + +} diff --git a/src/main/java/emu/lunarcore/game/scene/EntityNpc.java b/src/main/java/emu/lunarcore/game/scene/EntityNpc.java new file mode 100644 index 0000000..5c1549f --- /dev/null +++ b/src/main/java/emu/lunarcore/game/scene/EntityNpc.java @@ -0,0 +1,41 @@ +package emu.lunarcore.game.scene; + +import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo; +import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo; +import emu.lunarcore.proto.SceneNpcInfoOuterClass.SceneNpcInfo; +import emu.lunarcore.util.Position; +import lombok.Getter; +import lombok.Setter; + +@Getter +public class EntityNpc implements GameEntity { + @Setter private int entityId; + @Setter private int groupId; + @Setter private int instId; + @Setter private int npcId; + + private Position pos; + private Position rot; + + public EntityNpc(int npcId, Position pos) { + this.npcId = npcId; + this.pos = pos; + this.rot = new Position(); + } + + @Override + public SceneEntityInfo toSceneEntityProto() { + var npc = SceneNpcInfo.newInstance() + .setNpcId(this.getNpcId()); + + var proto = SceneEntityInfo.newInstance() + .setEntityId(this.getEntityId()) + .setGroupId(this.getGroupId()) + .setInstId(this.getInstId()) + .setMotion(MotionInfo.newInstance().setPos(getPos().toProto()).setRot(getRot().toProto())) + .setNpc(npc); + + return proto; + } + +} diff --git a/src/main/java/emu/lunarcore/game/scene/GameEntity.java b/src/main/java/emu/lunarcore/game/scene/GameEntity.java index 3770279..f9139d7 100644 --- a/src/main/java/emu/lunarcore/game/scene/GameEntity.java +++ b/src/main/java/emu/lunarcore/game/scene/GameEntity.java @@ -3,6 +3,7 @@ package emu.lunarcore.game.scene; import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo; public interface GameEntity { + public int getEntityId(); public void setEntityId(int id); @@ -10,6 +11,11 @@ public interface GameEntity { public default int getGroupId() { return 0; } + + public default int getInstId() { + return 0; + } public SceneEntityInfo toSceneEntityProto(); + } diff --git a/src/main/java/emu/lunarcore/game/scene/Scene.java b/src/main/java/emu/lunarcore/game/scene/Scene.java index dede3f6..9b14bbd 100644 --- a/src/main/java/emu/lunarcore/game/scene/Scene.java +++ b/src/main/java/emu/lunarcore/game/scene/Scene.java @@ -5,11 +5,8 @@ import java.util.List; import emu.lunarcore.GameConstants; import emu.lunarcore.data.GameData; -import emu.lunarcore.data.config.FloorInfo; -import emu.lunarcore.data.config.GroupInfo; +import emu.lunarcore.data.config.*; import emu.lunarcore.data.config.GroupInfo.GroupLoadSide; -import emu.lunarcore.data.config.MonsterInfo; -import emu.lunarcore.data.config.PropInfo; import emu.lunarcore.data.excel.NpcMonsterExcel; import emu.lunarcore.data.excel.StageExcel; import emu.lunarcore.game.avatar.GameAvatar; @@ -17,7 +14,6 @@ import emu.lunarcore.game.player.PlayerLineup; import emu.lunarcore.game.player.Player; import emu.lunarcore.proto.SceneEntityGroupInfoOuterClass.SceneEntityGroupInfo; import emu.lunarcore.proto.SceneInfoOuterClass.SceneInfo; -import emu.lunarcore.server.packet.send.PacketSceneEntityUpdateScNotify; import emu.lunarcore.server.packet.send.PacketSceneGroupRefreshScNotify; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -76,7 +72,7 @@ public class Scene { } // Add monsters - if (group.getMonsterList() != null || group.getMonsterList().size() > 0) { + if (group.getMonsterList() != null && group.getMonsterList().size() > 0) { for (MonsterInfo monsterInfo : group.getMonsterList()) { // Get excels from game data NpcMonsterExcel excel = GameData.getNpcMonsterExcelMap().get(monsterInfo.getNPCMonsterID()); @@ -96,15 +92,8 @@ public class Scene { } // Add props - if (group.getPropList() != null || group.getPropList().size() > 0) { + if (group.getPropList() != null && group.getPropList().size() > 0) { for (PropInfo propInfo : group.getPropList()) { - // Dont add deleted props? - /* - if (propInfo.isIsDelete()) { - continue; - } - */ - // Create prop from prop info EntityProp prop = new EntityProp(propInfo.getPropID(), propInfo.clonePos()); //prop.setState(propInfo.getState()); @@ -120,6 +109,35 @@ public class Scene { this.addEntity(prop); } } + + // Add npcs + if (group.getNPCList() != null && group.getNPCList().size() > 0) { + for (NpcInfo npcInfo : group.getNPCList()) { + // Sanity check + if (!GameData.getNpcExcelMap().containsKey(npcInfo.getNPCID())) { + continue; + } + + // Dont spawn duplicate NPCs + boolean haseDuplicateNpcId = false; + for (GameEntity entity : this.getEntities().values()) { + if (entity instanceof EntityNpc eNpc && eNpc.getNpcId() == npcInfo.getNPCID()) { + haseDuplicateNpcId = true; + break; + } + } + if (haseDuplicateNpcId) continue; + + // Create npc from npc info + EntityNpc npc = new EntityNpc(npcInfo.getNPCID(), npcInfo.clonePos()); + npc.getRot().setY((int) (npcInfo.getRotY() * 1000f)); + npc.setInstId(npcInfo.getID()); + npc.setGroupId(group.getId()); + + // Add to monsters + this.addEntity(npc); + } + } } } @@ -201,7 +219,10 @@ public class Scene { PlayerLineup lineup = getPlayer().getLineupManager().getCurrentLineup(); int leaderAvatarId = lineup.getAvatars().get(getPlayer().getLineupManager().getCurrentLeader()); - // Scene group + // Sort entities into groups + var groups = new Int2ObjectOpenHashMap(); + + // Create player group var playerGroup = SceneEntityGroupInfo.newInstance(); for (var avatar : avatars.values()) { @@ -212,14 +233,12 @@ public class Scene { } } - proto.addEntityGroupList(playerGroup); + groups.put(0, playerGroup); - // Sort entities into groups - var groups = new Int2ObjectOpenHashMap(); - - for (var monster : entities.values()) { - var group = groups.computeIfAbsent(monster.getGroupId(), i -> SceneEntityGroupInfo.newInstance().setGroupId(i)); - group.addEntityList(monster.toSceneEntityProto()); + // Add rest of the entities to groups + for (var entity : entities.values()) { + var group = groups.computeIfAbsent(entity.getGroupId(), i -> SceneEntityGroupInfo.newInstance().setGroupId(i)); + group.addEntityList(entity.toSceneEntityProto()); } for (var group : groups.values()) {