Implement support for npcs

This commit is contained in:
Melledy
2023-09-26 05:13:58 -07:00
parent 5a21304b3f
commit 51f0ee4ad8
7 changed files with 116 additions and 22 deletions

View File

@@ -19,6 +19,7 @@ public class GameData {
@Getter private static Int2ObjectMap<EquipmentExcel> equipExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<RelicExcel> relicExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<MonsterExcel> monsterExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<NpcExcel> npcExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<NpcMonsterExcel> npcMonsterExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<StageExcel> stageExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<MapEntranceExcel> mapEntranceExcelMap = new Int2ObjectOpenHashMap<>();

View File

@@ -9,10 +9,12 @@ public class GroupInfo {
private transient int id;
private GroupLoadSide LoadSide;
private boolean LoadOnInitial;
private int OwnerMainMissionID;
private List<AnchorInfo> AnchorList;
private List<MonsterInfo> MonsterList;
private List<PropInfo> PropList;
private List<NpcInfo> NPCList;
public void setId(int id) {
if (this.id == 0) this.id = id;

View File

@@ -0,0 +1,8 @@
package emu.lunarcore.data.config;
import lombok.Getter;
@Getter
public class NpcInfo extends ObjectInfo {
private int NPCID;
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
@@ -11,5 +12,10 @@ public interface GameEntity {
return 0;
}
public default int getInstId() {
return 0;
}
public SceneEntityInfo toSceneEntityProto();
}

View File

@@ -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<SceneEntityGroupInfo>();
// 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<SceneEntityGroupInfo>();
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()) {