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
|
||||
// TODO: public LevelModelInfo[] ModelList { get; set; } // 0x58
|
||||
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 LevelPathwayInfo[] PathwayList { get; set; } // 0x78
|
||||
// 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 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;
|
||||
AvatarType = type;
|
||||
|
|
|
@ -9,7 +9,7 @@ internal class EntityFactory
|
|||
|
||||
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)
|
||||
|
@ -17,6 +17,11 @@ internal class EntityFactory
|
|||
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()
|
||||
{
|
||||
_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.Factory;
|
||||
using RPG.Services.Gameserver.Game.Team;
|
||||
using RPG.Services.Gameserver.Game.Util;
|
||||
using MazeInfo = RPG.Network.Proto.Maze;
|
||||
|
||||
namespace RPG.Services.Gameserver.Game.Maze;
|
||||
|
||||
internal class MazeManager
|
||||
{
|
||||
private readonly EntityManager _entityManager;
|
||||
private readonly EntityFactory _entityFactory;
|
||||
|
||||
private readonly ExcelTables _excelTables;
|
||||
|
@ -26,38 +26,35 @@ internal class MazeManager
|
|||
private PlayerTeam? _playerTeam;
|
||||
private uint _uid;
|
||||
|
||||
public EntityManager EntityManager { get; }
|
||||
|
||||
public MazeManager(EntityManager entityManager, EntityFactory entityFactory, ExcelTables excelTables, LevelTables levelTables)
|
||||
{
|
||||
_entityManager = entityManager;
|
||||
EntityManager = entityManager;
|
||||
_entityFactory = entityFactory;
|
||||
_excelTables = excelTables;
|
||||
_levelTables = levelTables;
|
||||
}
|
||||
|
||||
public EntityBase? GetEntityById(uint entityId)
|
||||
{
|
||||
return _entityManager.GetEntityById(entityId);
|
||||
}
|
||||
|
||||
public void ResetAvatarPosition()
|
||||
{
|
||||
foreach (TeamMember? member in _playerTeam!.Members)
|
||||
{
|
||||
if (member == null) continue;
|
||||
|
||||
AvatarEntity? entity = _entityManager.GetAvatar(_uid, member.AvatarId);
|
||||
AvatarEntity? entity = EntityManager.GetAvatar(_uid, member.AvatarId);
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
entity.SetMotion(CreateInitialAvatarMotion());
|
||||
_entityManager.NotifyUpdate(entity);
|
||||
EntityManager.NotifyUpdate(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveEntities(IEnumerable<uint> entities)
|
||||
{
|
||||
_entityManager.RemoveEntities(entities);
|
||||
EntityManager.RemoveEntities(entities);
|
||||
}
|
||||
|
||||
public void SetPlayerUid(uint uid)
|
||||
|
@ -104,7 +101,7 @@ internal class MazeManager
|
|||
{
|
||||
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()
|
||||
{
|
||||
|
@ -114,7 +111,7 @@ internal class MazeManager
|
|||
LeaderEntityId = leaderEntity?.Id ?? 0,
|
||||
};
|
||||
|
||||
info.EntityList.AddRange(_entityManager.EntityInfoList);
|
||||
info.EntityList.AddRange(EntityManager.EntityInfoList);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
@ -132,9 +129,19 @@ internal class MazeManager
|
|||
if (!levelMonster.CreateOnInitial) continue;
|
||||
|
||||
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);
|
||||
entity.SetMotion(CreateInitialAvatarMotion());
|
||||
|
||||
_entityManager.AddEntity(entity);
|
||||
EntityManager.AddEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,29 +164,12 @@ internal class MazeManager
|
|||
LevelGroupInfo startGroup = _levelTables.GetGroupInfo(_floor!.StartGroup.GroupGUID)!;
|
||||
LevelAnchorInfo startAnchor = startGroup.AnchorList.First(anchor => anchor.ID == _floor.StartAnchorID);
|
||||
|
||||
return 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)
|
||||
}
|
||||
};
|
||||
return MazeUtil.CreateDefaultMotion(startAnchor);
|
||||
}
|
||||
|
||||
private void BeforeEnter()
|
||||
{
|
||||
_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);
|
||||
|
||||
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);
|
||||
}
|
||||
else if (_mazeManager.GetEntityById(req.AbilityTargetEntityId) is NpcMonsterEntity)
|
||||
else if (_mazeManager.EntityManager.GetEntityById(req.AbilityTargetEntityId) is NpcMonsterEntity)
|
||||
{
|
||||
battleModule.OnSuccessfulAttack(req.AbilityTargetEntityId, req.AssistMonsterEntityIdList);
|
||||
}
|
||||
|
|
|
@ -72,14 +72,14 @@ internal class BattleModule : BaseModule
|
|||
|
||||
List<uint> battleEvents = [];
|
||||
|
||||
if (_mazeManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster)
|
||||
if (_mazeManager.EntityManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster)
|
||||
{
|
||||
battleEvents.Add(monster.EventId);
|
||||
}
|
||||
|
||||
foreach (uint assistEntityId in assists)
|
||||
{
|
||||
if (_mazeManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster)
|
||||
if (_mazeManager.EntityManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster)
|
||||
{
|
||||
battleEvents.Add(assistMonster.EventId);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue