using RPG.GameCore.Excel; using RPG.Network.Proto; using RPG.Services.Gameserver.Game.Entity; using RPG.Services.Gameserver.Game.Maze; using RPG.Services.Gameserver.Modules.Attributes; using RPG.Services.Gameserver.Session; namespace RPG.Services.Gameserver.Modules; [GMAlias("adventure")] internal class AdventureModule : BaseModule { private const int StartingEntryId = 2010101; private readonly ExcelTables _excelTables; private readonly MazeManager _mazeManager; public AdventureModule(ModuleManager moduleManager, ExcelTables excelTables, MazeManager mazeManager) : base(moduleManager) { _excelTables = excelTables; _mazeManager = mazeManager; } [GMCommand("maze")] public Task OnGmEnterMaze(PlayerSession session, string[] args) { if (args.Length != 1) return Task.CompletedTask; if (!uint.TryParse(args[0], out uint entryId)) return Task.CompletedTask; MapEntryRow? entry = _excelTables.GetExcelRow(ExcelType.MapEntry, entryId); if (entry == null) return Task.CompletedTask; _mazeManager.EnterMaze(entryId, ModuleManager.Get().Team); Send(session, CmdType.CmdEnterMazeByServerScNotify, new EnterMazeByServerScNotify { Maze = _mazeManager.Maze }); return Task.CompletedTask; } public override Task OnLogin() { _mazeManager.EnterMaze(StartingEntryId, ModuleManager.Get().Team); return Task.CompletedTask; } public void OnBattleWin(uint battleMonster, IEnumerable assistMonsters) { _mazeManager.RemoveEntities(assistMonsters.Append(battleMonster)); } public void OnBattleLost() { _mazeManager.ResetAvatarPosition(); } [OnCommand(CmdType.CmdSceneCastSkillCsReq)] public Task OnCmdSceneCastSkillCsReq(PlayerSession session, ReadOnlyMemory body) { SceneCastSkillCsReq req = SceneCastSkillCsReq.Parser.ParseFrom(body.Span); BattleModule battleModule = ModuleManager.Get(); if (_mazeManager.GetEntityById(req.CastEntityId) is NpcMonsterEntity) { battleModule.OnBeingHitByMonster(req.CastEntityId, req.AssistMonsterEntityIdList); } else if (_mazeManager.GetEntityById(req.AbilityTargetEntityId) is NpcMonsterEntity) { battleModule.OnSuccessfulAttack(req.AbilityTargetEntityId, req.AssistMonsterEntityIdList); } Send(session, CmdType.CmdSceneCastSkillScRsp, new SceneCastSkillScRsp { Retcode = 0, BattleInfo = battleModule.Battle ?? new() }); return Task.CompletedTask; } [OnCommand(CmdType.CmdGetCurSceneInfoCsReq)] public Task OnCmdGetCurSceneInfoCsReq(PlayerSession session, ReadOnlyMemory _) { Send(session, CmdType.CmdGetCurSceneInfoScRsp, new GetCurSceneInfoScRsp { Retcode = 0, Scene = _mazeManager.SceneInfo }); return Task.CompletedTask; } [OnCommand(CmdType.CmdGetMazeMapInfoCsReq)] public Task OnCmdGetMazeMapInfoCsReq(PlayerSession session, ReadOnlyMemory body) { GetMazeMapInfoCsReq req = GetMazeMapInfoCsReq.Parser.ParseFrom(body.Span); Send(session, CmdType.CmdGetMazeMapInfoScRsp, new GetMazeMapInfoScRsp { Retcode = 0, EntryId = req.EntryId, // TODO: LightenSectionList = { }, MazeGroupList = { }, MazePropList = { } }); return Task.CompletedTask; } [OnCommand(CmdType.CmdEnterMazeCsReq)] public Task OnCmdEnterMazeCsReq(PlayerSession session, ReadOnlyMemory body) { EnterMazeCsReq req = EnterMazeCsReq.Parser.ParseFrom(body.Span); MapEntryRow? entry = _excelTables.GetExcelRow(ExcelType.MapEntry, req.EntryId); if (entry == null) { Send(session, CmdType.CmdEnterMazeScRsp, new EnterMazeScRsp { Retcode = Retcode.RET_MAZE_MAP_NOT_EXIST }); return Task.CompletedTask; } _mazeManager.EnterMaze(entry.ID, ModuleManager.Get().Team); Send(session, CmdType.CmdEnterMazeScRsp, new EnterMazeScRsp { Retcode = 0, Maze = _mazeManager.Maze }); return Task.CompletedTask; } }