Snowflake/RPG.Services.Gameserver/Modules/AdventureModule.cs

200 lines
6.5 KiB
C#

using RPG.GameCore.Enums;
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<MapEntryRow>(ExcelType.MapEntry, entryId);
if (entry == null) return Task.CompletedTask;
_mazeManager.EnterMaze(entryId, ModuleManager.Get<TeamModule>().Team);
Send(session, CmdType.CmdEnterMazeByServerScNotify, new EnterMazeByServerScNotify
{
Maze = _mazeManager.Maze
});
return Task.CompletedTask;
}
public override Task OnLogin()
{
ModuleManager.Get<TeamModule>().InitStartingLineup();
_mazeManager.SetPlayerUid(ModuleManager.PlayerUID);
_mazeManager.EnterMaze(StartingEntryId, ModuleManager.Get<TeamModule>().Team);
return Task.CompletedTask;
}
public void OnBattleWin(uint battleMonster, IEnumerable<uint> assistMonsters)
{
if (battleMonster != 0) // 0 - not on-scene battle vs npcmonster, means cocoon or challenge
_mazeManager.RemoveEntities(assistMonsters.Append(battleMonster));
}
public void OnBattleLost()
{
_mazeManager.ResetAvatarPosition();
}
[OnCommand(CmdType.CmdStartCocoonStageCsReq)]
public Task OnCmdStartCocoonStageCsReq(PlayerSession session, ReadOnlyMemory<byte> body)
{
StartCocoonStageCsReq req = StartCocoonStageCsReq.Parser.ParseFrom(body.Span);
CocoonRow? cocoonRow = _excelTables.GetExcelRow<CocoonRow>(ExcelType.Cocoon, req.CocoonId * 10); // CocoonId * 10 + worldLevel
if (cocoonRow == null)
{
Send(session, CmdType.CmdStartCocoonStageScRsp, new StartCocoonStageScRsp
{
Retcode = Retcode.RET_STAGE_COCOON_PROP_NOT_VALID
});
return Task.CompletedTask;
}
if (req.Wave is < 1 or > 5)
{
Send(session, CmdType.CmdStartCocoonStageScRsp, new StartCocoonStageScRsp
{
Retcode = Retcode.RET_STAGE_COCOON_WAVE_NOT_VALID
});
return Task.CompletedTask;
}
BattleModule battleModule = ModuleManager.Get<BattleModule>();
battleModule.StartCocoonStage(cocoonRow, req.Wave);
Send(session, CmdType.CmdStartCocoonStageScRsp, new StartCocoonStageScRsp
{
Retcode = Retcode.RET_SUCC,
BattleInfo = battleModule.Battle,
CocoonId = req.CocoonId,
PropEntityId = req.PropEntityId,
Wave = req.Wave
});
return Task.CompletedTask;
}
[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)]
public Task OnCmdSceneCastSkillCsReq(PlayerSession session, ReadOnlyMemory<byte> body)
{
SceneCastSkillCsReq req = SceneCastSkillCsReq.Parser.ParseFrom(body.Span);
BattleModule battleModule = ModuleManager.Get<BattleModule>();
if (_mazeManager.EntityManager.GetEntityById(req.CastEntityId) is NpcMonsterEntity)
{
battleModule.OnBeingHitByMonster(req.CastEntityId, req.AssistMonsterEntityIdList);
}
else if (_mazeManager.EntityManager.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<byte> _)
{
Send(session, CmdType.CmdGetCurSceneInfoScRsp, new GetCurSceneInfoScRsp
{
Retcode = 0,
Scene = _mazeManager.SceneInfo
});
return Task.CompletedTask;
}
[OnCommand(CmdType.CmdGetMazeMapInfoCsReq)]
public Task OnCmdGetMazeMapInfoCsReq(PlayerSession session, ReadOnlyMemory<byte> 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<byte> body)
{
EnterMazeCsReq req = EnterMazeCsReq.Parser.ParseFrom(body.Span);
MapEntryRow? entry = _excelTables.GetExcelRow<MapEntryRow>(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<TeamModule>().Team);
Send(session, CmdType.CmdEnterMazeScRsp, new EnterMazeScRsp
{
Retcode = 0,
Maze = _mazeManager.Maze
});
return Task.CompletedTask;
}
}