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

142 lines
4.5 KiB
C#

using RPG.GameCore.Excel;
using RPG.Network.Proto;
using RPG.Services.Gameserver.Game.Entity;
using RPG.Services.Gameserver.Game.Maze;
using RPG.Services.Gameserver.Game.Team;
using RPG.Services.Gameserver.Modules.Attributes;
using RPG.Services.Gameserver.Session;
using System.Security.Cryptography;
namespace RPG.Services.Gameserver.Modules;
internal class BattleModule : BaseModule
{
public SceneBattleInfo? Battle { get; private set; }
private uint _battleMonsterEntityId;
private IEnumerable<uint>? _battleMonsterAssists;
private readonly MazeManager _mazeManager;
private readonly ExcelTables _excelTables;
public BattleModule(ModuleManager moduleManager, MazeManager mazeManager, ExcelTables excelTables) : base(moduleManager)
{
_mazeManager = mazeManager;
_excelTables = excelTables;
}
[OnCommand(CmdType.CmdPVEBattleResultCsReq)]
public Task OnCmdPVEBattleResultCsReq(PlayerSession session, ReadOnlyMemory<byte> body)
{
PVEBattleResultCsReq req = PVEBattleResultCsReq.Parser.ParseFrom(body.Span);
AdventureModule adventureModule = ModuleManager.Get<AdventureModule>();
switch (req.EndStatus)
{
case BattleEndStatus.BattleEndWin:
adventureModule.OnBattleWin(_battleMonsterEntityId, _battleMonsterAssists!);
break;
case BattleEndStatus.BattleEndQuit:
case BattleEndStatus.BattleEndLose:
adventureModule.OnBattleLost();
break;
}
Send(session, CmdType.CmdPVEBattleResultScRsp, new PVEBattleResultScRsp
{
Retcode = 0,
StageId = req.StageId,
EndStatus = req.EndStatus
});
return Task.CompletedTask;
}
public void OnBeingHitByMonster(uint monsterEntityId, IEnumerable<uint> assists)
{
// TODO: debuffs
StartBattle(monsterEntityId, assists);
}
public void OnSuccessfulAttack(uint monsterEntityId, IEnumerable<uint> assists)
{
// TODO: buffs
StartBattle(monsterEntityId, assists);
}
private void StartBattle(uint monsterEntityId, IEnumerable<uint> assists)
{
_battleMonsterEntityId = monsterEntityId;
_battleMonsterAssists = assists;
List<uint> battleEvents = [];
if (_mazeManager.EntityManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster)
{
battleEvents.Add(monster.EventId);
}
foreach (uint assistEntityId in assists)
{
if (_mazeManager.EntityManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster)
{
battleEvents.Add(assistMonster.EventId);
}
}
Battle = CreateBattleWithEvents(battleEvents);
}
private SceneBattleInfo CreateBattleWithEvents(List<uint> battleEvents)
{
SceneBattleInfo battle = new()
{
LogicRandomSeed = (uint)RandomNumberGenerator.GetInt32(int.MaxValue),
StageId = battleEvents[0] * 10,
};
foreach (uint eventId in battleEvents)
{
StageRow stage = _excelTables.GetExcelRow<StageRow>(ExcelType.Stage, eventId * 10)!;
foreach (StageMonsterWave stageWave in stage.MonsterList)
{
SceneMonsterWave wave = new();
// wtf mihoyo..
if (stageWave.Monster0 != 0)
wave.MonsterIdList.Add(stageWave.Monster0);
if (stageWave.Monster1 != 0)
wave.MonsterIdList.Add(stageWave.Monster1);
if (stageWave.Monster2 != 0)
wave.MonsterIdList.Add(stageWave.Monster2);
if (stageWave.Monster3 != 0)
wave.MonsterIdList.Add(stageWave.Monster3);
if (stageWave.Monster4 != 0)
wave.MonsterIdList.Add(stageWave.Monster4);
battle.MonsterWaveList.Add(wave);
}
}
foreach (TeamMember? member in ModuleManager.Get<TeamModule>().Team.Members)
{
if (member == null) continue;
battle.BattleAvatarList.Add(new BattleAvatar
{
Id = member.AvatarId,
Hp = member.Hp,
Sp = member.Sp,
Level = 8,
Promotion = 0,
Rank = 0,
AvatarType = member.AvatarType,
Index = (uint)battle.BattleAvatarList.Count
});
}
return battle;
}
}