mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-14 14:24:37 +01:00
Rewrite how scenes load entities to support spawning the correct rogue monsters
This commit is contained in:
@@ -37,6 +37,7 @@ public class GameData {
|
|||||||
@Getter private static Int2ObjectMap<RogueAreaExcel> rogueAreaExcelMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static Int2ObjectMap<RogueAreaExcel> rogueAreaExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
@Getter private static Int2ObjectMap<RogueManagerExcel> rogueManagerExcelMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static Int2ObjectMap<RogueManagerExcel> rogueManagerExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
@Getter private static Int2ObjectMap<RogueRoomExcel> rogueRoomExcelMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static Int2ObjectMap<RogueRoomExcel> rogueRoomExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
@Getter private static Int2ObjectMap<RogueMonsterExcel> rogueMonsterExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
private static Int2ObjectMap<AvatarPromotionExcel> avatarPromotionExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<AvatarPromotionExcel> avatarPromotionExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static Int2ObjectMap<AvatarSkillTreeExcel> avatarSkillTreeExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<AvatarSkillTreeExcel> avatarSkillTreeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package emu.lunarcore.data.excel;
|
||||||
|
|
||||||
|
import emu.lunarcore.data.GameResource;
|
||||||
|
import emu.lunarcore.data.ResourceType;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = {"RogueMonster.json"})
|
||||||
|
public class RogueMonsterExcel extends GameResource {
|
||||||
|
private int RogueMonsterID;
|
||||||
|
private int NpcMonsterID;
|
||||||
|
private int EventID;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return RogueMonsterID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package emu.lunarcore.data.excel;
|
package emu.lunarcore.data.excel;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import emu.lunarcore.data.GameResource;
|
import emu.lunarcore.data.GameResource;
|
||||||
import emu.lunarcore.data.ResourceType;
|
import emu.lunarcore.data.ResourceType;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -14,11 +12,15 @@ public class RogueRoomExcel extends GameResource {
|
|||||||
private int RogueRoomType;
|
private int RogueRoomType;
|
||||||
private int MapEntrance;
|
private int MapEntrance;
|
||||||
private int GroupID;
|
private int GroupID;
|
||||||
private Map<Integer, Integer> GroupWithContent;
|
private Int2IntOpenHashMap GroupWithContent;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return RogueRoomID;
|
return RogueRoomID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getGroupContent(int id) {
|
||||||
|
return GroupWithContent.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,30 @@
|
|||||||
package emu.lunarcore.game.enums;
|
package emu.lunarcore.game.enums;
|
||||||
|
|
||||||
|
import emu.lunarcore.game.rogue.RogueEntityLoader;
|
||||||
|
import emu.lunarcore.game.scene.SceneEntityLoader;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public enum PlaneType {
|
public enum PlaneType {
|
||||||
Unknown (0),
|
Unknown (0),
|
||||||
Town (1),
|
Town (1),
|
||||||
Maze (2),
|
Maze (2),
|
||||||
Train (3),
|
Train (3),
|
||||||
Challenge (4),
|
Challenge (4),
|
||||||
Rogue (5),
|
Rogue (5, new RogueEntityLoader()),
|
||||||
Raid (6),
|
Raid (6),
|
||||||
AetherDivide (7),
|
AetherDivide (7),
|
||||||
TrialActivity (8);
|
TrialActivity (8);
|
||||||
|
|
||||||
private final int val;
|
private final int val;
|
||||||
|
private final SceneEntityLoader sceneEntityLoader;
|
||||||
|
|
||||||
private PlaneType(int value) {
|
private PlaneType(int value) {
|
||||||
|
this(value, new SceneEntityLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlaneType(int value, SceneEntityLoader entityLoader) {
|
||||||
this.val = value;
|
this.val = value;
|
||||||
|
this.sceneEntityLoader = entityLoader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,6 +58,8 @@ public class RogueData {
|
|||||||
public RogueRoomData getCurrentRoom() {
|
public RogueRoomData getCurrentRoom() {
|
||||||
return this.rooms.get(this.getCurrentSiteId());
|
return this.rooms.get(this.getCurrentSiteId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serialization
|
||||||
|
|
||||||
public RogueCurrentInfo toProto() {
|
public RogueCurrentInfo toProto() {
|
||||||
var proto = RogueCurrentInfo.newInstance()
|
var proto = RogueCurrentInfo.newInstance()
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package emu.lunarcore.game.rogue;
|
||||||
|
|
||||||
|
import emu.lunarcore.data.GameData;
|
||||||
|
import emu.lunarcore.data.config.GroupInfo;
|
||||||
|
import emu.lunarcore.data.config.MonsterInfo;
|
||||||
|
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
||||||
|
import emu.lunarcore.data.excel.RogueMonsterExcel;
|
||||||
|
import emu.lunarcore.game.scene.Scene;
|
||||||
|
import emu.lunarcore.game.scene.SceneEntityLoader;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
|
|
||||||
|
public class RogueEntityLoader extends SceneEntityLoader {
|
||||||
|
|
||||||
|
public EntityMonster loadMonster(Scene scene, GroupInfo group, MonsterInfo monsterInfo) {
|
||||||
|
// Make sure player is in a rogue instance
|
||||||
|
RogueData rogue = scene.getPlayer().getRogueData();
|
||||||
|
if (rogue == null) return null;
|
||||||
|
|
||||||
|
// Get rogue group content
|
||||||
|
int content = rogue.getCurrentRoom().getExcel().getGroupContent(group.getId());
|
||||||
|
if (content <= 0) return null;
|
||||||
|
|
||||||
|
// Get rogue monster excel and npc monster excel
|
||||||
|
RogueMonsterExcel rogueMonster = GameData.getRogueMonsterExcelMap().get((content * 10) + 1);
|
||||||
|
if (rogueMonster == null) return null;
|
||||||
|
|
||||||
|
NpcMonsterExcel npcMonster = GameData.getNpcMonsterExcelMap().get(rogueMonster.getNpcMonsterID());
|
||||||
|
if (npcMonster == null) return null;
|
||||||
|
|
||||||
|
// Actually create the monster now
|
||||||
|
EntityMonster monster = new EntityMonster(scene, npcMonster, monsterInfo.getPos());
|
||||||
|
monster.getRot().set(monsterInfo.getRot());
|
||||||
|
monster.setGroupId(group.getId());
|
||||||
|
monster.setInstId(monsterInfo.getID());
|
||||||
|
monster.setEventId(rogueMonster.getEventID());
|
||||||
|
monster.setOverrideStageId(rogueMonster.getEventID());
|
||||||
|
|
||||||
|
return monster;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,12 @@ public class RogueManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void startRogue(int areaId, RepeatedInt avatarIdList) {
|
public void startRogue(int areaId, RepeatedInt avatarIdList) {
|
||||||
|
// Make sure player already isnt in a rogue instance
|
||||||
|
if (getPlayer().getRogueData() != null) {
|
||||||
|
getPlayer().sendPacket(new PacketStartRogueScRsp());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get excel
|
// Get excel
|
||||||
var excel = GameData.getRogueAreaExcelMap().get(areaId);
|
var excel = GameData.getRogueAreaExcelMap().get(areaId);
|
||||||
if (excel == null || !excel.isValid()) {
|
if (excel == null || !excel.isValid()) {
|
||||||
@@ -72,13 +78,13 @@ public class RogueManager extends BasePlayerManager {
|
|||||||
getPlayer().sendPacket(new PacketStartRogueScRsp());
|
getPlayer().sendPacket(new PacketStartRogueScRsp());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load scene groups
|
|
||||||
RogueRoomExcel roomExcel = data.getCurrentRoom().getExcel();
|
|
||||||
for (var entry : roomExcel.getGroupWithContent().entrySet()) {
|
|
||||||
getPlayer().getScene().loadGroup(entry.getKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Set rogue data
|
||||||
|
getPlayer().setRogueData(data);
|
||||||
|
|
||||||
|
// Get room excel
|
||||||
|
RogueRoomExcel roomExcel = data.getCurrentRoom().getExcel();
|
||||||
|
|
||||||
// Move player to rogue start position
|
// Move player to rogue start position
|
||||||
AnchorInfo anchor = getPlayer().getScene().getFloorInfo().getAnchorInfo(roomExcel.getGroupID(), 1);
|
AnchorInfo anchor = getPlayer().getScene().getFloorInfo().getAnchorInfo(roomExcel.getGroupID(), 1);
|
||||||
if (anchor != null) {
|
if (anchor != null) {
|
||||||
@@ -86,8 +92,12 @@ public class RogueManager extends BasePlayerManager {
|
|||||||
getPlayer().getRot().set(anchor.getRot());
|
getPlayer().getRot().set(anchor.getRot());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set rogue data and send packet
|
// Load scene groups. THIS NEEDS TO BE LAST
|
||||||
getPlayer().setRogueData(data);
|
for (int key : roomExcel.getGroupWithContent().keySet()) {
|
||||||
|
getPlayer().getScene().loadGroup(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done
|
||||||
getPlayer().sendPacket(new PacketStartRogueScRsp(getPlayer()));
|
getPlayer().sendPacket(new PacketStartRogueScRsp(getPlayer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,8 @@ import emu.lunarcore.data.GameData;
|
|||||||
import emu.lunarcore.data.config.*;
|
import emu.lunarcore.data.config.*;
|
||||||
import emu.lunarcore.data.config.GroupInfo.GroupLoadSide;
|
import emu.lunarcore.data.config.GroupInfo.GroupLoadSide;
|
||||||
import emu.lunarcore.data.excel.MazePlaneExcel;
|
import emu.lunarcore.data.excel.MazePlaneExcel;
|
||||||
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
|
||||||
import emu.lunarcore.data.excel.PropExcel;
|
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.enums.PlaneType;
|
import emu.lunarcore.game.enums.PlaneType;
|
||||||
import emu.lunarcore.game.enums.PropState;
|
|
||||||
import emu.lunarcore.game.enums.PropType;
|
|
||||||
import emu.lunarcore.game.player.PlayerLineup;
|
import emu.lunarcore.game.player.PlayerLineup;
|
||||||
import emu.lunarcore.game.scene.entity.*;
|
import emu.lunarcore.game.scene.entity.*;
|
||||||
import emu.lunarcore.game.scene.triggers.PropTrigger;
|
import emu.lunarcore.game.scene.triggers.PropTrigger;
|
||||||
@@ -23,6 +19,7 @@ import emu.lunarcore.proto.SceneGroupStateOuterClass.SceneGroupState;
|
|||||||
import emu.lunarcore.proto.SceneInfoOuterClass.SceneInfo;
|
import emu.lunarcore.proto.SceneInfoOuterClass.SceneInfo;
|
||||||
import emu.lunarcore.server.packet.send.PacketActivateFarmElementScRsp;
|
import emu.lunarcore.server.packet.send.PacketActivateFarmElementScRsp;
|
||||||
import emu.lunarcore.server.packet.send.PacketSceneGroupRefreshScNotify;
|
import emu.lunarcore.server.packet.send.PacketSceneGroupRefreshScNotify;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -32,6 +29,7 @@ public class Scene {
|
|||||||
private final Player player;
|
private final Player player;
|
||||||
private final MazePlaneExcel excel;
|
private final MazePlaneExcel excel;
|
||||||
private final FloorInfo floorInfo;
|
private final FloorInfo floorInfo;
|
||||||
|
private final SceneEntityLoader entityLoader;
|
||||||
private final int planeId;
|
private final int planeId;
|
||||||
private final int floorId;
|
private final int floorId;
|
||||||
private int entryId;
|
private int entryId;
|
||||||
@@ -50,7 +48,7 @@ public class Scene {
|
|||||||
// Cache
|
// Cache
|
||||||
private List<PropTrigger> triggers;
|
private List<PropTrigger> triggers;
|
||||||
private List<EntityProp> healingSprings;
|
private List<EntityProp> healingSprings;
|
||||||
|
|
||||||
public Scene(Player player, MazePlaneExcel excel, int floorId) {
|
public Scene(Player player, MazePlaneExcel excel, int floorId) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.excel = excel;
|
this.excel = excel;
|
||||||
@@ -65,7 +63,11 @@ public class Scene {
|
|||||||
|
|
||||||
this.healingSprings = new ObjectArrayList<>();
|
this.healingSprings = new ObjectArrayList<>();
|
||||||
this.triggers = new ObjectArrayList<>();
|
this.triggers = new ObjectArrayList<>();
|
||||||
|
|
||||||
|
// Use singleton to avoid allocating memory for a new entity loader everytime we create a scene
|
||||||
|
this.entityLoader = getExcel().getPlaneType().getSceneEntityLoader();
|
||||||
|
|
||||||
|
// Add avatar entities
|
||||||
PlayerLineup lineup = getPlayer().getCurrentLineup();
|
PlayerLineup lineup = getPlayer().getCurrentLineup();
|
||||||
|
|
||||||
for (int avatarId : lineup.getAvatars()) {
|
for (int avatarId : lineup.getAvatars()) {
|
||||||
@@ -115,97 +117,36 @@ public class Scene {
|
|||||||
// Add monsters
|
// Add monsters
|
||||||
if (group.getMonsterList() != null && group.getMonsterList().size() > 0) {
|
if (group.getMonsterList() != null && group.getMonsterList().size() > 0) {
|
||||||
for (MonsterInfo monsterInfo : group.getMonsterList()) {
|
for (MonsterInfo monsterInfo : group.getMonsterList()) {
|
||||||
// Don't spawn entity if they have the IsDelete flag in group info
|
try {
|
||||||
if (monsterInfo.isIsDelete()) continue;
|
EntityMonster monster = this.getEntityLoader().loadMonster(this, group, monsterInfo);
|
||||||
|
this.addEntity(monster);
|
||||||
// Get excels from game data
|
} catch (Exception e) {
|
||||||
NpcMonsterExcel npcMonsterExcel = GameData.getNpcMonsterExcelMap().get(monsterInfo.getNPCMonsterID());
|
// Ignored
|
||||||
if (npcMonsterExcel == null) continue;
|
}
|
||||||
|
|
||||||
// Create monster with excels
|
|
||||||
EntityMonster monster = new EntityMonster(this, npcMonsterExcel, monsterInfo.getPos());
|
|
||||||
monster.getRot().set(monsterInfo.getRot());
|
|
||||||
monster.setInstId(monsterInfo.getID());
|
|
||||||
monster.setEventId(monsterInfo.getEventID());
|
|
||||||
monster.setGroupId(group.getId());
|
|
||||||
monster.setWorldLevel(this.getPlayer().getWorldLevel());
|
|
||||||
|
|
||||||
// Add to monsters
|
|
||||||
this.addEntity(monster);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add props
|
// Add props
|
||||||
if (group.getPropList() != null && group.getPropList().size() > 0) {
|
if (group.getPropList() != null && group.getPropList().size() > 0) {
|
||||||
for (PropInfo propInfo : group.getPropList()) {
|
for (PropInfo propInfo : group.getPropList()) {
|
||||||
// Don't spawn entity if they have the IsDelete flag in group info
|
try {
|
||||||
if (propInfo.isIsDelete()) continue;
|
EntityProp prop = this.getEntityLoader().loadNpc(this, group, propInfo);
|
||||||
|
this.addEntity(prop);
|
||||||
// Get prop excel
|
} catch (Exception e) {
|
||||||
PropExcel propExcel = GameData.getPropExcelMap().get(propInfo.getPropID());
|
// Ignored
|
||||||
if (propExcel == null) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create prop from prop info
|
|
||||||
EntityProp prop = new EntityProp(this, propExcel, propInfo.getPos());
|
|
||||||
prop.setState(propInfo.getState());
|
|
||||||
prop.getRot().set(propInfo.getRot());
|
|
||||||
prop.setInstId(propInfo.getID());
|
|
||||||
prop.setGroupId(group.getId());
|
|
||||||
prop.setPropInfo(propInfo);
|
|
||||||
|
|
||||||
// Cache
|
|
||||||
if (prop.getPropId() == 1003) {
|
|
||||||
// Hacky fix to open simulated universe
|
|
||||||
if (propInfo.getMappingInfoID() == 2220) {
|
|
||||||
// Regular simulated universe is locked behind a mission requirement by default
|
|
||||||
prop.setState(PropState.Open);
|
|
||||||
} else {
|
|
||||||
// Skip tutorial simulated universe
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (prop.getExcel().getPropType() == PropType.PROP_SPRING) {
|
|
||||||
// Cache teleport anchors
|
|
||||||
this.getHealingSprings().add(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add trigger
|
|
||||||
if (propInfo.getTrigger() != null) {
|
|
||||||
this.getTriggers().add(propInfo.getTrigger());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to monsters
|
|
||||||
this.addEntity(prop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add npcs
|
// Add NPCs
|
||||||
if (group.getNPCList() != null && group.getNPCList().size() > 0) {
|
if (group.getNPCList() != null && group.getNPCList().size() > 0) {
|
||||||
for (NpcInfo npcInfo : group.getNPCList()) {
|
for (NpcInfo npcInfo : group.getNPCList()) {
|
||||||
// Don't spawn entity if they have the IsDelete flag in group info
|
try {
|
||||||
if (npcInfo.isIsDelete() || !GameData.getNpcExcelMap().containsKey(npcInfo.getNPCID())) {
|
EntityNpc npc = this.getEntityLoader().loadNpc(this, group, npcInfo);
|
||||||
continue;
|
this.addEntity(npc);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(this, npcInfo.getNPCID(), npcInfo.getPos());
|
|
||||||
npc.getRot().set(npcInfo.getRot());
|
|
||||||
npc.setInstId(npcInfo.getID());
|
|
||||||
npc.setGroupId(group.getId());
|
|
||||||
|
|
||||||
// Add to monsters
|
|
||||||
this.addEntity(npc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,13 +266,18 @@ public class Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void addEntity(GameEntity entity, boolean sendPacket) {
|
public synchronized void addEntity(GameEntity entity, boolean sendPacket) {
|
||||||
// Dont add if monster id already exists
|
// Sanity checks - Also dont add entity if it already exists
|
||||||
if (entity.getEntityId() != 0) return;
|
if (entity == null || entity.getEntityId() != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set entity id and add monster to entity map
|
// Set entity id and add monster to entity map
|
||||||
entity.setEntityId(this.getNextEntityId());
|
entity.setEntityId(this.getNextEntityId());
|
||||||
this.getEntities().put(entity.getEntityId(), entity);
|
this.getEntities().put(entity.getEntityId(), entity);
|
||||||
|
|
||||||
// Entity add callback
|
// Entity add callback
|
||||||
entity.onAdd();
|
entity.onAdd();
|
||||||
|
|
||||||
// Send packet
|
// Send packet
|
||||||
if (sendPacket) {
|
if (sendPacket) {
|
||||||
player.sendPacket(new PacketSceneGroupRefreshScNotify(entity, null));
|
player.sendPacket(new PacketSceneGroupRefreshScNotify(entity, null));
|
||||||
@@ -346,7 +292,8 @@ public class Scene {
|
|||||||
GameEntity entity = this.getEntities().remove(entityId);
|
GameEntity entity = this.getEntities().remove(entityId);
|
||||||
|
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
// Entity remove callback
|
// Reset entity id and run event
|
||||||
|
entity.setEntityId(0);
|
||||||
entity.onRemove();
|
entity.onRemove();
|
||||||
// Send packet
|
// Send packet
|
||||||
player.sendPacket(new PacketSceneGroupRefreshScNotify(null, entity));
|
player.sendPacket(new PacketSceneGroupRefreshScNotify(null, entity));
|
||||||
|
|||||||
103
src/main/java/emu/lunarcore/game/scene/SceneEntityLoader.java
Normal file
103
src/main/java/emu/lunarcore/game/scene/SceneEntityLoader.java
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package emu.lunarcore.game.scene;
|
||||||
|
|
||||||
|
import emu.lunarcore.data.GameData;
|
||||||
|
import emu.lunarcore.data.config.GroupInfo;
|
||||||
|
import emu.lunarcore.data.config.MonsterInfo;
|
||||||
|
import emu.lunarcore.data.config.NpcInfo;
|
||||||
|
import emu.lunarcore.data.config.PropInfo;
|
||||||
|
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
||||||
|
import emu.lunarcore.data.excel.PropExcel;
|
||||||
|
import emu.lunarcore.game.enums.PropState;
|
||||||
|
import emu.lunarcore.game.enums.PropType;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityNpc;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityProp;
|
||||||
|
import emu.lunarcore.game.scene.entity.GameEntity;
|
||||||
|
|
||||||
|
public class SceneEntityLoader {
|
||||||
|
|
||||||
|
public EntityMonster loadMonster(Scene scene, GroupInfo group, MonsterInfo monsterInfo) {
|
||||||
|
// Don't spawn entity if they have the IsDelete flag in group info
|
||||||
|
if (monsterInfo.isIsDelete()) return null;
|
||||||
|
|
||||||
|
// Get excels from game data
|
||||||
|
NpcMonsterExcel npcMonsterExcel = GameData.getNpcMonsterExcelMap().get(monsterInfo.getNPCMonsterID());
|
||||||
|
if (npcMonsterExcel == null) return null;
|
||||||
|
|
||||||
|
// Create monster with excels
|
||||||
|
EntityMonster monster = new EntityMonster(scene, npcMonsterExcel, monsterInfo.getPos());
|
||||||
|
monster.getRot().set(monsterInfo.getRot());
|
||||||
|
monster.setGroupId(group.getId());
|
||||||
|
monster.setInstId(monsterInfo.getID());
|
||||||
|
monster.setEventId(monsterInfo.getEventID());
|
||||||
|
monster.setWorldLevel(scene.getPlayer().getWorldLevel());
|
||||||
|
|
||||||
|
return monster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityProp loadNpc(Scene scene, GroupInfo group, PropInfo propInfo) {
|
||||||
|
// Don't spawn entity if they have the IsDelete flag in group info
|
||||||
|
if (propInfo.isIsDelete()) return null;
|
||||||
|
|
||||||
|
// Get prop excel
|
||||||
|
PropExcel propExcel = GameData.getPropExcelMap().get(propInfo.getPropID());
|
||||||
|
if (propExcel == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create prop from prop info
|
||||||
|
EntityProp prop = new EntityProp(scene, propExcel, propInfo.getPos());
|
||||||
|
prop.setState(propInfo.getState());
|
||||||
|
prop.getRot().set(propInfo.getRot());
|
||||||
|
prop.setInstId(propInfo.getID());
|
||||||
|
prop.setGroupId(group.getId());
|
||||||
|
prop.setPropInfo(propInfo);
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
if (prop.getPropId() == 1003) {
|
||||||
|
// Hacky fix to open simulated universe
|
||||||
|
if (propInfo.getMappingInfoID() == 2220) {
|
||||||
|
// Regular simulated universe is locked behind a mission requirement by default
|
||||||
|
prop.setState(PropState.Open);
|
||||||
|
} else {
|
||||||
|
// Skip tutorial simulated universe
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (prop.getExcel().getPropType() == PropType.PROP_SPRING) {
|
||||||
|
// Cache teleport anchors
|
||||||
|
scene.getHealingSprings().add(prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add trigger
|
||||||
|
if (propInfo.getTrigger() != null) {
|
||||||
|
scene.getTriggers().add(propInfo.getTrigger());
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityNpc loadNpc(Scene scene, GroupInfo group, NpcInfo npcInfo) {
|
||||||
|
// Don't spawn entity if they have the IsDelete flag in group info
|
||||||
|
if (npcInfo.isIsDelete() || !GameData.getNpcExcelMap().containsKey(npcInfo.getNPCID())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dont spawn duplicate NPCs
|
||||||
|
boolean haseDuplicateNpcId = false;
|
||||||
|
for (GameEntity entity : scene.getEntities().values()) {
|
||||||
|
if (entity instanceof EntityNpc eNpc && eNpc.getNpcId() == npcInfo.getNPCID()) {
|
||||||
|
haseDuplicateNpcId = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (haseDuplicateNpcId) return null;
|
||||||
|
|
||||||
|
// Create npc from npc info
|
||||||
|
EntityNpc npc = new EntityNpc(scene, npcInfo.getNPCID(), npcInfo.getPos());
|
||||||
|
npc.getRot().set(npcInfo.getRot());
|
||||||
|
npc.setInstId(npcInfo.getID());
|
||||||
|
npc.setGroupId(group.getId());
|
||||||
|
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user