Snowflake/RPG.Services.Gameserver/Game/Maze/MazeManager.cs

184 lines
5.5 KiB
C#

using RPG.GameCore.Excel;
using RPG.GameCore.Level;
using RPG.GameCore.Level.Floor;
using RPG.GameCore.Level.Group;
using RPG.GameCore.Level.Objects;
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 EntityFactory _entityFactory;
private readonly ExcelTables _excelTables;
private readonly LevelTables _levelTables;
private MapEntryRow? _mapEntry;
private LevelFloorInfo? _floor;
private PlayerTeam? _playerTeam;
private uint _uid;
public EntityManager EntityManager { get; }
public MazeManager(EntityManager entityManager, EntityFactory entityFactory, ExcelTables excelTables, LevelTables levelTables)
{
EntityManager = entityManager;
_entityFactory = entityFactory;
_excelTables = excelTables;
_levelTables = levelTables;
}
public void ResetAvatarPosition()
{
foreach (TeamMember? member in _playerTeam!.Members)
{
if (member == null) continue;
AvatarEntity? entity = EntityManager.GetAvatar(_uid, member.AvatarId);
if (entity != null)
{
entity.SetMotion(CreateInitialAvatarMotion());
EntityManager.NotifyMove(entity);
}
}
}
public void RemoveEntities(IEnumerable<uint> entities)
{
EntityManager.RemoveEntities(entities);
}
public void SetPlayerUid(uint uid)
{
_uid = uid;
}
public void EnterMaze(uint entryId, PlayerTeam team)
{
BeforeEnter();
_playerTeam = team;
_mapEntry = _excelTables.GetExcelRow<MapEntryRow>(ExcelType.MapEntry, entryId)
?? throw new ArgumentException("EnterMaze: specified entryId doesn't exist!", nameof(entryId));
_floor = _levelTables.GetFloorInfo(_mapEntry.FloorID);
AddTeamMemberEntities();
InitLevelGroups();
}
public MazeInfo Maze
{
get
{
if (_mapEntry == null) throw new InvalidOperationException("GetMaze: maze not loaded!");
return new()
{
MapEntryId = _mapEntry.ID,
Id = _mapEntry.PlaneID,
Floor = new()
{
FloorId = _mapEntry.FloorID,
Scene = SceneInfo
}
};
}
}
public SceneInfo SceneInfo
{
get
{
if (_mapEntry == null || _playerTeam == null) throw new InvalidOperationException("GetSceneInfo: scene not loaded!");
AvatarEntity? leaderEntity = EntityManager.GetAvatar(_uid, _playerTeam.Leader.AvatarId);
SceneInfo info = new()
{
EntryId = _mapEntry.ID,
PlaneId = _mapEntry.PlaneID,
FloorId = _mapEntry.FloorID,
LeaderEntityId = leaderEntity?.Id ?? 0,
};
info.EntityList.AddRange(EntityManager.EntityInfoList);
return info;
}
}
private void InitLevelGroups()
{
foreach (LevelGroupInstanceInfo groupInstanceInfo in _floor!.GroupList)
{
LevelGroupInfo? levelGroup = _levelTables.GetGroupInfo(groupInstanceInfo.GroupGUID);
if (levelGroup == null) continue;
foreach (LevelMonsterInfo levelMonster in levelGroup.MonsterList)
{
if (!levelMonster.CreateOnInitial) continue;
NpcMonsterEntity monsterEntity = _entityFactory.CreateNpcMonsterEntity(levelMonster, groupInstanceInfo.ID);
monsterEntity.SetMotion(MazeUtil.CreateDefaultMotion(levelMonster));
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);
}
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);
}
}
}
private void AddTeamMemberEntities()
{
foreach (TeamMember? member in _playerTeam!.Members)
{
if (member == null) continue;
AvatarEntity entity = _entityFactory.CreateAvatarEntity(member.AvatarId, member.AvatarType, _uid);
entity.SetMotion(CreateInitialAvatarMotion());
EntityManager.AddEntity(entity);
}
}
private MotionInfo CreateInitialAvatarMotion()
{
LevelGroupInfo startGroup = _levelTables.GetGroupInfo(_floor!.StartGroup.GroupGUID)!;
LevelAnchorInfo startAnchor = startGroup.AnchorList.First(anchor => anchor.ID == _floor.StartAnchorID);
return MazeUtil.CreateDefaultMotion(startAnchor);
}
private void BeforeEnter()
{
_entityFactory.Reset();
EntityManager.Clear();
}
}