Implement PropEntity spawn
This commit is contained in:
parent
b093824270
commit
158e81be6b
10 changed files with 137 additions and 41 deletions
7
RPG.GameCore/Level/Capture/StageObjectCapture.cs
Normal file
7
RPG.GameCore/Level/Capture/StageObjectCapture.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace RPG.GameCore.Level.Capture;
|
||||||
|
|
||||||
|
public class StageObjectCapture
|
||||||
|
{
|
||||||
|
public string BlockAlias { get; set; } = string.Empty; // 0x10
|
||||||
|
public string PrefabAlias { get; set; } = string.Empty; // 0x18
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ public class LevelGroupInfo
|
||||||
public LevelAnchorInfo[] AnchorList { get; set; } = []; // 0x50
|
public LevelAnchorInfo[] AnchorList { get; set; } = []; // 0x50
|
||||||
// TODO: public LevelModelInfo[] ModelList { get; set; } // 0x58
|
// TODO: public LevelModelInfo[] ModelList { get; set; } // 0x58
|
||||||
public LevelMonsterInfo[] MonsterList { get; set; } = []; // 0x60
|
public LevelMonsterInfo[] MonsterList { get; set; } = []; // 0x60
|
||||||
// TODO: public LevelPropInfo[] PropList { get; set; } // 0x68
|
public LevelPropInfo[] PropList { get; set; } = []; // 0x68
|
||||||
// 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
|
||||||
|
|
35
RPG.GameCore/Level/Objects/LevelPropInfo.cs
Normal file
35
RPG.GameCore/Level/Objects/LevelPropInfo.cs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
using RPG.GameCore.Enums;
|
||||||
|
using RPG.GameCore.Level.Capture;
|
||||||
|
using RPG.GameCore.Level.Graph;
|
||||||
|
using RPG.GameCore.Level.Trigger;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace RPG.GameCore.Level.Objects;
|
||||||
|
|
||||||
|
public class LevelPropInfo : NamedLevelObjectInfo
|
||||||
|
{
|
||||||
|
public float RotX { get; set; } // 0x40
|
||||||
|
public float RotZ { get; set; } // 0x44
|
||||||
|
public uint PropID { get; set; } // 0x48
|
||||||
|
public bool IsLimitedLife { get; set; } // 0x4C
|
||||||
|
public float LifeTime { get; set; } // 0x50
|
||||||
|
public string InitLevelGraph { get; set; } = string.Empty; // 0x58
|
||||||
|
public LevelTriggerInfo? Trigger { get; set; } // 0x60
|
||||||
|
public bool CreateOnInitial { get; set; } // 0x68
|
||||||
|
public LevelGraphValueSource? ValueSource { get; set; } // 0x70
|
||||||
|
public uint CampID { get; set; } // 0x78
|
||||||
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
|
public PropState State { get; set; } // 0x7C
|
||||||
|
public uint RecordID { get; set; } // 0x80
|
||||||
|
public uint EventID { get; set; } // 0x84
|
||||||
|
public uint AnchorGroupID { get; set; } // 0x88
|
||||||
|
public uint AnchorID { get; set; } // 0x8C
|
||||||
|
public uint MapTeleportID { get; set; } // 0x90
|
||||||
|
public uint ChestID { get; set; } // 0x94
|
||||||
|
public uint DialogueTriggerAngle { get; set; } // 0x98
|
||||||
|
public uint[] DialogueGroups { get; set; } = []; // 0xA0
|
||||||
|
public bool OverrideTriggerHint { get; set; } // 0xA8
|
||||||
|
public float HintRange { get; set; } // 0xAC
|
||||||
|
public uint[] ServerInteractVerificationIDList { get; set; } = []; // 0xB0
|
||||||
|
public StageObjectCapture? StageObjectCapture { get; set; } // 0xB8
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ internal class AvatarEntity : EntityBase
|
||||||
public AvatarType AvatarType { get; }
|
public AvatarType AvatarType { get; }
|
||||||
public uint Uid { get; }
|
public uint Uid { get; }
|
||||||
|
|
||||||
public AvatarEntity(uint id, uint groupId, uint instanceId, uint avatarId, AvatarType type, uint uid) : base(id, groupId, instanceId)
|
public AvatarEntity(uint id, uint avatarId, AvatarType type, uint uid) : base(id, 0, 0)
|
||||||
{
|
{
|
||||||
AvatarId = avatarId;
|
AvatarId = avatarId;
|
||||||
AvatarType = type;
|
AvatarType = type;
|
||||||
|
|
|
@ -9,7 +9,7 @@ internal class EntityFactory
|
||||||
|
|
||||||
public AvatarEntity CreateAvatarEntity(uint avatarId, AvatarType type, uint uid)
|
public AvatarEntity CreateAvatarEntity(uint avatarId, AvatarType type, uint uid)
|
||||||
{
|
{
|
||||||
return new(NextEntityId(), 0, 0, avatarId, type, uid);
|
return new(NextEntityId(), avatarId, type, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NpcMonsterEntity CreateNpcMonsterEntity(LevelMonsterInfo levelMonster, uint groupId)
|
public NpcMonsterEntity CreateNpcMonsterEntity(LevelMonsterInfo levelMonster, uint groupId)
|
||||||
|
@ -17,6 +17,11 @@ internal class EntityFactory
|
||||||
return new(NextEntityId(), groupId, levelMonster.ID, levelMonster.NPCMonsterID, levelMonster.EventID);
|
return new(NextEntityId(), groupId, levelMonster.ID, levelMonster.NPCMonsterID, levelMonster.EventID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PropEntity CreatePropEntity(LevelPropInfo levelProp, uint groupId)
|
||||||
|
{
|
||||||
|
return new(NextEntityId(), groupId, levelProp.ID, levelProp);
|
||||||
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_entityIdSeed = 0;
|
_entityIdSeed = 0;
|
||||||
|
|
34
RPG.Services.Gameserver/Game/Entity/PropEntity.cs
Normal file
34
RPG.Services.Gameserver/Game/Entity/PropEntity.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using RPG.GameCore.Enums;
|
||||||
|
using RPG.GameCore.Level.Objects;
|
||||||
|
using RPG.Network.Proto;
|
||||||
|
|
||||||
|
namespace RPG.Services.Gameserver.Game.Entity;
|
||||||
|
|
||||||
|
internal class PropEntity : EntityBase
|
||||||
|
{
|
||||||
|
public uint PropId { get; }
|
||||||
|
public PropState State { get; set; }
|
||||||
|
|
||||||
|
public PropEntity(uint id, uint groupId, uint instanceId, LevelPropInfo info) : base(id, groupId, instanceId)
|
||||||
|
{
|
||||||
|
PropId = info.PropID;
|
||||||
|
State = info.State;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EntityType Type => EntityType.EntityProp;
|
||||||
|
|
||||||
|
public override SceneEntityInfo SceneEntityInfo
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
SceneEntityInfo info = base.SceneEntityInfo;
|
||||||
|
info.Prop = new()
|
||||||
|
{
|
||||||
|
PropId = PropId,
|
||||||
|
PropState = (uint)State
|
||||||
|
};
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,13 +8,13 @@ using RPG.Network.Proto;
|
||||||
using RPG.Services.Gameserver.Game.Entity;
|
using RPG.Services.Gameserver.Game.Entity;
|
||||||
using RPG.Services.Gameserver.Game.Entity.Factory;
|
using RPG.Services.Gameserver.Game.Entity.Factory;
|
||||||
using RPG.Services.Gameserver.Game.Team;
|
using RPG.Services.Gameserver.Game.Team;
|
||||||
|
using RPG.Services.Gameserver.Game.Util;
|
||||||
using MazeInfo = RPG.Network.Proto.Maze;
|
using MazeInfo = RPG.Network.Proto.Maze;
|
||||||
|
|
||||||
namespace RPG.Services.Gameserver.Game.Maze;
|
namespace RPG.Services.Gameserver.Game.Maze;
|
||||||
|
|
||||||
internal class MazeManager
|
internal class MazeManager
|
||||||
{
|
{
|
||||||
private readonly EntityManager _entityManager;
|
|
||||||
private readonly EntityFactory _entityFactory;
|
private readonly EntityFactory _entityFactory;
|
||||||
|
|
||||||
private readonly ExcelTables _excelTables;
|
private readonly ExcelTables _excelTables;
|
||||||
|
@ -26,38 +26,35 @@ internal class MazeManager
|
||||||
private PlayerTeam? _playerTeam;
|
private PlayerTeam? _playerTeam;
|
||||||
private uint _uid;
|
private uint _uid;
|
||||||
|
|
||||||
|
public EntityManager EntityManager { get; }
|
||||||
|
|
||||||
public MazeManager(EntityManager entityManager, EntityFactory entityFactory, ExcelTables excelTables, LevelTables levelTables)
|
public MazeManager(EntityManager entityManager, EntityFactory entityFactory, ExcelTables excelTables, LevelTables levelTables)
|
||||||
{
|
{
|
||||||
_entityManager = entityManager;
|
EntityManager = entityManager;
|
||||||
_entityFactory = entityFactory;
|
_entityFactory = entityFactory;
|
||||||
_excelTables = excelTables;
|
_excelTables = excelTables;
|
||||||
_levelTables = levelTables;
|
_levelTables = levelTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityBase? GetEntityById(uint entityId)
|
|
||||||
{
|
|
||||||
return _entityManager.GetEntityById(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetAvatarPosition()
|
public void ResetAvatarPosition()
|
||||||
{
|
{
|
||||||
foreach (TeamMember? member in _playerTeam!.Members)
|
foreach (TeamMember? member in _playerTeam!.Members)
|
||||||
{
|
{
|
||||||
if (member == null) continue;
|
if (member == null) continue;
|
||||||
|
|
||||||
AvatarEntity? entity = _entityManager.GetAvatar(_uid, member.AvatarId);
|
AvatarEntity? entity = EntityManager.GetAvatar(_uid, member.AvatarId);
|
||||||
|
|
||||||
if (entity != null)
|
if (entity != null)
|
||||||
{
|
{
|
||||||
entity.SetMotion(CreateInitialAvatarMotion());
|
entity.SetMotion(CreateInitialAvatarMotion());
|
||||||
_entityManager.NotifyUpdate(entity);
|
EntityManager.NotifyUpdate(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveEntities(IEnumerable<uint> entities)
|
public void RemoveEntities(IEnumerable<uint> entities)
|
||||||
{
|
{
|
||||||
_entityManager.RemoveEntities(entities);
|
EntityManager.RemoveEntities(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPlayerUid(uint uid)
|
public void SetPlayerUid(uint uid)
|
||||||
|
@ -104,7 +101,7 @@ internal class MazeManager
|
||||||
{
|
{
|
||||||
if (_mapEntry == null || _playerTeam == null) throw new InvalidOperationException("GetSceneInfo: scene not loaded!");
|
if (_mapEntry == null || _playerTeam == null) throw new InvalidOperationException("GetSceneInfo: scene not loaded!");
|
||||||
|
|
||||||
AvatarEntity? leaderEntity = _entityManager.GetAvatar(_uid, _playerTeam.Leader.AvatarId);
|
AvatarEntity? leaderEntity = EntityManager.GetAvatar(_uid, _playerTeam.Leader.AvatarId);
|
||||||
|
|
||||||
SceneInfo info = new()
|
SceneInfo info = new()
|
||||||
{
|
{
|
||||||
|
@ -114,7 +111,7 @@ internal class MazeManager
|
||||||
LeaderEntityId = leaderEntity?.Id ?? 0,
|
LeaderEntityId = leaderEntity?.Id ?? 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
info.EntityList.AddRange(_entityManager.EntityInfoList);
|
info.EntityList.AddRange(EntityManager.EntityInfoList);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -132,9 +129,19 @@ internal class MazeManager
|
||||||
if (!levelMonster.CreateOnInitial) continue;
|
if (!levelMonster.CreateOnInitial) continue;
|
||||||
|
|
||||||
NpcMonsterEntity monsterEntity = _entityFactory.CreateNpcMonsterEntity(levelMonster, groupInstanceInfo.ID);
|
NpcMonsterEntity monsterEntity = _entityFactory.CreateNpcMonsterEntity(levelMonster, groupInstanceInfo.ID);
|
||||||
monsterEntity.SetMotion(CreateDefaultMotion(levelMonster));
|
monsterEntity.SetMotion(MazeUtil.CreateDefaultMotion(levelMonster));
|
||||||
|
|
||||||
_entityManager.AddEntity(monsterEntity);
|
EntityManager.AddEntity(monsterEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (LevelPropInfo levelProp in levelGroup.PropList)
|
||||||
|
{
|
||||||
|
if (!levelProp.CreateOnInitial) continue;
|
||||||
|
|
||||||
|
PropEntity propEntity = _entityFactory.CreatePropEntity(levelProp, groupInstanceInfo.ID);
|
||||||
|
propEntity.SetMotion(MazeUtil.CreateDefaultMotion(levelProp));
|
||||||
|
|
||||||
|
EntityManager.AddEntity(propEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +155,7 @@ internal class MazeManager
|
||||||
AvatarEntity entity = _entityFactory.CreateAvatarEntity(member.AvatarId, member.AvatarType, _uid);
|
AvatarEntity entity = _entityFactory.CreateAvatarEntity(member.AvatarId, member.AvatarType, _uid);
|
||||||
entity.SetMotion(CreateInitialAvatarMotion());
|
entity.SetMotion(CreateInitialAvatarMotion());
|
||||||
|
|
||||||
_entityManager.AddEntity(entity);
|
EntityManager.AddEntity(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,29 +164,12 @@ internal class MazeManager
|
||||||
LevelGroupInfo startGroup = _levelTables.GetGroupInfo(_floor!.StartGroup.GroupGUID)!;
|
LevelGroupInfo startGroup = _levelTables.GetGroupInfo(_floor!.StartGroup.GroupGUID)!;
|
||||||
LevelAnchorInfo startAnchor = startGroup.AnchorList.First(anchor => anchor.ID == _floor.StartAnchorID);
|
LevelAnchorInfo startAnchor = startGroup.AnchorList.First(anchor => anchor.ID == _floor.StartAnchorID);
|
||||||
|
|
||||||
return CreateDefaultMotion(startAnchor);
|
return MazeUtil.CreateDefaultMotion(startAnchor);
|
||||||
}
|
|
||||||
|
|
||||||
private static MotionInfo CreateDefaultMotion(NamedLevelObjectInfo info)
|
|
||||||
{
|
|
||||||
return new()
|
|
||||||
{
|
|
||||||
Pos = new()
|
|
||||||
{
|
|
||||||
X = MathUtil.GetLogicCoordValue(info.PosX),
|
|
||||||
Y = MathUtil.GetLogicCoordValue(info.PosY),
|
|
||||||
Z = MathUtil.GetLogicCoordValue(info.PosZ)
|
|
||||||
},
|
|
||||||
Rot = new()
|
|
||||||
{
|
|
||||||
Y = MathUtil.GetLogicCoordValue(info.RotY)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BeforeEnter()
|
private void BeforeEnter()
|
||||||
{
|
{
|
||||||
_entityFactory.Reset();
|
_entityFactory.Reset();
|
||||||
_entityManager.Clear();
|
EntityManager.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
RPG.Services.Gameserver/Game/Util/MazeUtil.cs
Normal file
25
RPG.Services.Gameserver/Game/Util/MazeUtil.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using RPG.GameCore.Level.Objects;
|
||||||
|
using RPG.GameCore.Util;
|
||||||
|
using RPG.Network.Proto;
|
||||||
|
|
||||||
|
namespace RPG.Services.Gameserver.Game.Util;
|
||||||
|
|
||||||
|
internal static class MazeUtil
|
||||||
|
{
|
||||||
|
public static MotionInfo CreateDefaultMotion(NamedLevelObjectInfo info)
|
||||||
|
{
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
Pos = new()
|
||||||
|
{
|
||||||
|
X = MathUtil.GetLogicCoordValue(info.PosX),
|
||||||
|
Y = MathUtil.GetLogicCoordValue(info.PosY),
|
||||||
|
Z = MathUtil.GetLogicCoordValue(info.PosZ)
|
||||||
|
},
|
||||||
|
Rot = new()
|
||||||
|
{
|
||||||
|
Y = MathUtil.GetLogicCoordValue(info.RotY)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,11 +65,11 @@ internal class AdventureModule : BaseModule
|
||||||
SceneCastSkillCsReq req = SceneCastSkillCsReq.Parser.ParseFrom(body.Span);
|
SceneCastSkillCsReq req = SceneCastSkillCsReq.Parser.ParseFrom(body.Span);
|
||||||
|
|
||||||
BattleModule battleModule = ModuleManager.Get<BattleModule>();
|
BattleModule battleModule = ModuleManager.Get<BattleModule>();
|
||||||
if (_mazeManager.GetEntityById(req.CastEntityId) is NpcMonsterEntity)
|
if (_mazeManager.EntityManager.GetEntityById(req.CastEntityId) is NpcMonsterEntity)
|
||||||
{
|
{
|
||||||
battleModule.OnBeingHitByMonster(req.CastEntityId, req.AssistMonsterEntityIdList);
|
battleModule.OnBeingHitByMonster(req.CastEntityId, req.AssistMonsterEntityIdList);
|
||||||
}
|
}
|
||||||
else if (_mazeManager.GetEntityById(req.AbilityTargetEntityId) is NpcMonsterEntity)
|
else if (_mazeManager.EntityManager.GetEntityById(req.AbilityTargetEntityId) is NpcMonsterEntity)
|
||||||
{
|
{
|
||||||
battleModule.OnSuccessfulAttack(req.AbilityTargetEntityId, req.AssistMonsterEntityIdList);
|
battleModule.OnSuccessfulAttack(req.AbilityTargetEntityId, req.AssistMonsterEntityIdList);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,14 +72,14 @@ internal class BattleModule : BaseModule
|
||||||
|
|
||||||
List<uint> battleEvents = [];
|
List<uint> battleEvents = [];
|
||||||
|
|
||||||
if (_mazeManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster)
|
if (_mazeManager.EntityManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster)
|
||||||
{
|
{
|
||||||
battleEvents.Add(monster.EventId);
|
battleEvents.Add(monster.EventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (uint assistEntityId in assists)
|
foreach (uint assistEntityId in assists)
|
||||||
{
|
{
|
||||||
if (_mazeManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster)
|
if (_mazeManager.EntityManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster)
|
||||||
{
|
{
|
||||||
battleEvents.Add(assistMonster.EventId);
|
battleEvents.Add(assistMonster.EventId);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue