2024-01-23 17:54:53 +00:00
|
|
|
|
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;
|
2024-01-25 12:14:47 +00:00
|
|
|
|
case BattleEndStatus.BattleEndQuit:
|
2024-01-23 17:54:53 +00:00
|
|
|
|
case BattleEndStatus.BattleEndLose:
|
|
|
|
|
adventureModule.OnBattleLost();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Send(session, CmdType.CmdPVEBattleResultScRsp, new PVEBattleResultScRsp
|
|
|
|
|
{
|
|
|
|
|
Retcode = 0,
|
|
|
|
|
StageId = req.StageId,
|
|
|
|
|
EndStatus = req.EndStatus
|
|
|
|
|
});
|
|
|
|
|
|
2024-01-25 13:03:45 +00:00
|
|
|
|
_battleMonsterAssists = [];
|
|
|
|
|
_battleMonsterEntityId = 0;
|
2024-01-23 17:54:53 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 13:03:45 +00:00
|
|
|
|
public void StartCocoonStage(CocoonRow cocoon, uint waveCount)
|
|
|
|
|
{
|
|
|
|
|
List<uint> stageIds = [];
|
|
|
|
|
for (int i = 0; i < waveCount; i++)
|
|
|
|
|
{
|
|
|
|
|
stageIds.Add(cocoon.StageIDList[i % cocoon.StageIDList.Length]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Battle = CreateBattleWithStages(stageIds);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-23 17:54:53 +00:00
|
|
|
|
private void StartBattle(uint monsterEntityId, IEnumerable<uint> assists)
|
|
|
|
|
{
|
|
|
|
|
_battleMonsterEntityId = monsterEntityId;
|
|
|
|
|
_battleMonsterAssists = assists;
|
|
|
|
|
|
|
|
|
|
List<uint> battleEvents = [];
|
|
|
|
|
|
2024-01-25 10:55:10 +00:00
|
|
|
|
if (_mazeManager.EntityManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster)
|
2024-01-23 17:54:53 +00:00
|
|
|
|
{
|
2024-01-25 13:03:45 +00:00
|
|
|
|
battleEvents.Add(monster.EventId * 10);
|
2024-01-23 17:54:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (uint assistEntityId in assists)
|
|
|
|
|
{
|
2024-01-25 10:55:10 +00:00
|
|
|
|
if (_mazeManager.EntityManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster)
|
2024-01-23 17:54:53 +00:00
|
|
|
|
{
|
2024-01-25 13:03:45 +00:00
|
|
|
|
battleEvents.Add(assistMonster.EventId * 10);
|
2024-01-23 17:54:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 13:03:45 +00:00
|
|
|
|
Battle = CreateBattleWithStages(battleEvents);
|
2024-01-23 17:54:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 13:03:45 +00:00
|
|
|
|
private SceneBattleInfo CreateBattleWithStages(List<uint> battleEvents)
|
2024-01-23 17:54:53 +00:00
|
|
|
|
{
|
|
|
|
|
SceneBattleInfo battle = new()
|
|
|
|
|
{
|
|
|
|
|
LogicRandomSeed = (uint)RandomNumberGenerator.GetInt32(int.MaxValue),
|
2024-01-25 13:03:45 +00:00
|
|
|
|
StageId = battleEvents[0],
|
2024-01-23 17:54:53 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach (uint eventId in battleEvents)
|
|
|
|
|
{
|
2024-01-25 13:03:45 +00:00
|
|
|
|
StageRow stage = _excelTables.GetExcelRow<StageRow>(ExcelType.Stage, eventId)!;
|
2024-01-23 17:54:53 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|