NPC spawn

This commit is contained in:
xeon 2024-01-25 14:31:32 +03:00
parent 158e81be6b
commit 4d182852e5
6 changed files with 86 additions and 2 deletions

View file

@ -23,7 +23,7 @@ public class LevelGroupInfo
// TODO: public LevelWaypointInfo[] WaypointList { get; set; } // 0x70 // TODO: public LevelWaypointInfo[] WaypointList { get; set; } // 0x70
// TODO: public LevelPathwayInfo[] PathwayList { get; set; } // 0x78 // TODO: public LevelPathwayInfo[] PathwayList { get; set; } // 0x78
// TODO: public LevelBattleAreaInfo[] BattleAreaList { get; set; } // 0x80 // TODO: public LevelBattleAreaInfo[] BattleAreaList { get; set; } // 0x80
// TODO: public LevelNPCInfo[] NPCList { get; set; } // 0x88 public LevelNPCInfo[] NPCList { get; set; } = []; // 0x88
public uint GroupRefreshID { get; set; } // 0x90 public uint GroupRefreshID { get; set; } // 0x90
// TODO: public RandomNPCMonsterInfo[] RandomNPCMonsterList { get; set; } // 0x98 // TODO: public RandomNPCMonsterInfo[] RandomNPCMonsterList { get; set; } // 0x98
public uint[] InitialRandomNPCMonsterIDList { get; set; } = []; // 0xA0 public uint[] InitialRandomNPCMonsterIDList { get; set; } = []; // 0xA0

View file

@ -0,0 +1,23 @@
using RPG.GameCore.Level.AI;
using RPG.GameCore.Level.Graph;
using RPG.GameCore.Level.Trigger;
namespace RPG.GameCore.Level.Objects;
public class LevelNPCInfo : NamedLevelObjectInfo
{
public uint NPCID { get; set; } // 0x40
public string LevelGraph { get; set; } = string.Empty; // 0x48
public bool CreateOnInitial { get; set; } // 0x50
public LevelGraphValueSource? ValueSource { get; set; } // 0x58
public uint CampID { get; set; } // 0x60
public LevelTriggerInfo? Trigger { get; set; } // 0x68
public AIConfigInfo? AIConfig { get; set; } // 0x70
public uint RecordID { get; set; } // 0x78
public uint EventID { get; set; } // 0x7C
public bool Stable { get; set; } // 0x80
public uint DialogueTriggerAngle { get; set; } // 0x84
public uint[] DialogueGroups { get; set; } = []; // 0x88
public uint[] ServerInteractVerificationIDList { get; set; } = []; // 0x90
public string DefaultIdleStateName { get; set; } = string.Empty; // 0x98
}

View file

@ -22,6 +22,11 @@ internal class EntityFactory
return new(NextEntityId(), groupId, levelProp.ID, levelProp); return new(NextEntityId(), groupId, levelProp.ID, levelProp);
} }
public NpcEntity CreateNpcEntity(LevelNPCInfo levelNPC, uint groupId)
{
return new(NextEntityId(), groupId, levelNPC.ID, levelNPC);
}
public void Reset() public void Reset()
{ {
_entityIdSeed = 0; _entityIdSeed = 0;

View file

@ -0,0 +1,30 @@
using RPG.GameCore.Level.Objects;
using RPG.Network.Proto;
namespace RPG.Services.Gameserver.Game.Entity;
internal class NpcEntity : EntityBase
{
public uint NpcId { get; }
public NpcEntity(uint id, uint groupId, uint instanceId, LevelNPCInfo info) : base(id, groupId, instanceId)
{
NpcId = info.NPCID;
}
public override EntityType Type => EntityType.EntityNpc;
public override SceneEntityInfo SceneEntityInfo
{
get
{
SceneEntityInfo info = base.SceneEntityInfo;
info.Npc = new()
{
NpcId = NpcId
};
return info;
}
}
}

View file

@ -143,6 +143,16 @@ internal class MazeManager
EntityManager.AddEntity(propEntity); EntityManager.AddEntity(propEntity);
} }
foreach (LevelNPCInfo levelNPC in levelGroup.NPCList)
{
if (!levelNPC.CreateOnInitial) continue;
NpcEntity npcEntity = _entityFactory.CreateNpcEntity(levelNPC, groupInstanceInfo.ID);
npcEntity.SetMotion(MazeUtil.CreateDefaultMotion(levelNPC));
EntityManager.AddEntity(npcEntity);
}
} }
} }

View file

@ -1,4 +1,5 @@
using RPG.GameCore.Excel; using RPG.GameCore.Enums;
using RPG.GameCore.Excel;
using RPG.Network.Proto; using RPG.Network.Proto;
using RPG.Services.Gameserver.Game.Entity; using RPG.Services.Gameserver.Game.Entity;
using RPG.Services.Gameserver.Game.Maze; using RPG.Services.Gameserver.Game.Maze;
@ -59,6 +60,21 @@ internal class AdventureModule : BaseModule
_mazeManager.ResetAvatarPosition(); _mazeManager.ResetAvatarPosition();
} }
[OnCommand(CmdType.CmdInteractPropCsReq)]
public Task OnCmdInteractPropCsReq(PlayerSession session, ReadOnlyMemory<byte> body)
{
InteractPropCsReq req = InteractPropCsReq.Parser.ParseFrom(body.Span);
// TODO: interact logic
Send(session, CmdType.CmdInteractPropScRsp, new InteractPropScRsp
{
PropEntityId = req.PropEntityId,
Retcode = 0
});
return Task.CompletedTask;
}
[OnCommand(CmdType.CmdSceneCastSkillCsReq)] [OnCommand(CmdType.CmdSceneCastSkillCsReq)]
public Task OnCmdSceneCastSkillCsReq(PlayerSession session, ReadOnlyMemory<byte> body) public Task OnCmdSceneCastSkillCsReq(PlayerSession session, ReadOnlyMemory<byte> body)
{ {