diff --git a/RPG.GameCore/Excel/CocoonRow.cs b/RPG.GameCore/Excel/CocoonRow.cs new file mode 100644 index 0000000..93dd091 --- /dev/null +++ b/RPG.GameCore/Excel/CocoonRow.cs @@ -0,0 +1,18 @@ +using RPG.GameCore.Excel.Attributes; + +namespace RPG.GameCore.Excel; + +[ExcelTable("CocoonExcelTable.json", ExcelType.Cocoon)] +public class CocoonRow : ExcelRow +{ + public override uint Id => ID * 10 + WorldLevel; + + public uint ID { get; set; } // 0x10 + public uint WorldLevel { get; set; } // 0x14 + public uint PropID { get; set; } // 0x18 + public uint MappingInfoID { get; set; } // 0x1C + public uint StageID { get; set; } // 0x20 + public uint[] StageIDList { get; set; } = []; // 0x28 + public uint[] DropList { get; set; } = []; // 0x30 + public uint StaminaCost { get; set; } // 0x38 +} diff --git a/RPG.GameCore/Excel/ExcelType.cs b/RPG.GameCore/Excel/ExcelType.cs index b434d9d..03a2386 100644 --- a/RPG.GameCore/Excel/ExcelType.cs +++ b/RPG.GameCore/Excel/ExcelType.cs @@ -6,5 +6,6 @@ public enum ExcelType MapEntry, Monster, MonsterTemplate, - Stage + Stage, + Cocoon } diff --git a/RPG.GameCore/RPG.GameCore.csproj b/RPG.GameCore/RPG.GameCore.csproj index f5ff244..70278b9 100644 --- a/RPG.GameCore/RPG.GameCore.csproj +++ b/RPG.GameCore/RPG.GameCore.csproj @@ -27,6 +27,7 @@ + diff --git a/RPG.GameCore/data/Config/ExcelBinOutput/CocoonExcelTable.json b/RPG.GameCore/data/Config/ExcelBinOutput/CocoonExcelTable.json new file mode 100644 index 0000000..225c1d2 --- /dev/null +++ b/RPG.GameCore/data/Config/ExcelBinOutput/CocoonExcelTable.json @@ -0,0 +1,568 @@ +{ + "10010": { + "ID": 1001, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1001, + "StageID": 1022010, + "StageIDList": [ + 1022010, + 1022020, + 1022030 + ], + "DropList": [ + 1000919, + 1000319, + 999121, + 999121, + 999122 + ], + "StaminaCost": 20 + }, + "10011": { + "ID": 1001, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1001, + "StageID": 1022011, + "StageIDList": [ + 1022011, + 1022021, + 1022031 + ], + "DropList": [ + 1000919, + 1000339, + 999121, + 999121, + 999121, + 999121 + ], + "StaminaCost": 20 + }, + "10012": { + "ID": 1001, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1001, + "StageID": 1022012, + "StageIDList": [ + 1022012, + 1022022, + 1022032 + ], + "DropList": [ + 1000919, + 1000359, + 999124, + 999121, + 999121, + 999121, + 999121, + 999122 + ], + "StaminaCost": 20 + }, + "10013": { + "ID": 1001, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1001, + "StageID": 1022013, + "StageIDList": [ + 1022013, + 1022023, + 1022033 + ], + "DropList": [ + 1000919, + 1000389, + 999125, + 999121, + 999121, + 999121, + 999121, + 999121 + ], + "StaminaCost": 20 + }, + "10020": { + "ID": 1002, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1002, + "StageID": 1022110, + "StageIDList": [ + 1022110, + 1022120, + 1022130 + ], + "DropList": [ + 1000919, + 1000319, + 1001068 + ], + "StaminaCost": 20 + }, + "10021": { + "ID": 1002, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1002, + "StageID": 1022111, + "StageIDList": [ + 1022111, + 1022121, + 1022131 + ], + "DropList": [ + 1000919, + 1000339, + 1001075 + ], + "StaminaCost": 20 + }, + "10022": { + "ID": 1002, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1002, + "StageID": 1022112, + "StageIDList": [ + 1022112, + 1022122, + 1022132 + ], + "DropList": [ + 1000919, + 1000359, + 1001066, + 1001082 + ], + "StaminaCost": 20 + }, + "10023": { + "ID": 1002, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1002, + "StageID": 1022113, + "StageIDList": [ + 1022113, + 1022123, + 1022133 + ], + "DropList": [ + 1000919, + 1000389, + 1001063, + 1001084 + ], + "StaminaCost": 20 + }, + "10030": { + "ID": 1003, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1003, + "StageID": 1022210, + "StageIDList": [ + 1022210, + 1022220, + 1022230 + ], + "DropList": [ + 1000919, + 1000319, + 2003008, + 1001024 + ], + "StaminaCost": 20 + }, + "10031": { + "ID": 1003, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1003, + "StageID": 1022211, + "StageIDList": [ + 1022211, + 1022221, + 1022231 + ], + "DropList": [ + 1000919, + 1000339, + 2003006, + 1001029 + ], + "StaminaCost": 20 + }, + "10032": { + "ID": 1003, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1003, + "StageID": 1022212, + "StageIDList": [ + 1022212, + 1022222, + 1022232 + ], + "DropList": [ + 1000919, + 1000359, + 1001026, + 1001041 + ], + "StaminaCost": 20 + }, + "10033": { + "ID": 1003, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1003, + "StageID": 1022213, + "StageIDList": [ + 1022213, + 1022223, + 1022233 + ], + "DropList": [ + 1000919, + 1000389, + 2003106, + 1001043 + ], + "StaminaCost": 20 + }, + "10040": { + "ID": 1004, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1004, + "StageID": 1022310, + "StageIDList": [ + 1022310, + 1022320, + 1022330 + ], + "DropList": [ + 1000919, + 1000319, + 999111, + 999111, + 999112 + ], + "StaminaCost": 20 + }, + "10041": { + "ID": 1004, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1004, + "StageID": 1022311, + "StageIDList": [ + 1022311, + 1022321, + 1022331 + ], + "DropList": [ + 1000919, + 1000339, + 999111, + 999111, + 999111, + 999111 + ], + "StaminaCost": 20 + }, + "10042": { + "ID": 1004, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1004, + "StageID": 1022312, + "StageIDList": [ + 1022312, + 1022322, + 1022332 + ], + "DropList": [ + 1000919, + 1000359, + 999114, + 999111, + 999111, + 999111, + 999111, + 999112 + ], + "StaminaCost": 20 + }, + "10043": { + "ID": 1004, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1004, + "StageID": 1022313, + "StageIDList": [ + 1022313, + 1022323, + 1022333 + ], + "DropList": [ + 1000919, + 1000389, + 999115, + 999111, + 999111, + 999111, + 999111, + 999111 + ], + "StaminaCost": 20 + }, + "10050": { + "ID": 1005, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1005, + "StageID": 1022410, + "StageIDList": [ + 1022410, + 1022420, + 1022430 + ], + "DropList": [ + 1000919, + 1000319, + 999131, + 999131, + 999132 + ], + "StaminaCost": 20 + }, + "10051": { + "ID": 1005, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1005, + "StageID": 1022411, + "StageIDList": [ + 1022411, + 1022421, + 1022431 + ], + "DropList": [ + 1000919, + 1000339, + 999131, + 999131, + 999131, + 999131 + ], + "StaminaCost": 20 + }, + "10052": { + "ID": 1005, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1005, + "StageID": 1022412, + "StageIDList": [ + 1022412, + 1022422, + 1022432 + ], + "DropList": [ + 1000919, + 1000359, + 999134, + 999131, + 999131, + 999131, + 999131, + 999132 + ], + "StaminaCost": 20 + }, + "10053": { + "ID": 1005, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1005, + "StageID": 1022413, + "StageIDList": [ + 1022413, + 1022423, + 1022433 + ], + "DropList": [ + 1000919, + 1000389, + 999135, + 999131, + 999131, + 999131, + 999131, + 999131 + ], + "StaminaCost": 20 + }, + "10060": { + "ID": 1006, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1006, + "StageID": 1022410, + "StageIDList": [ + 1022510, + 1022520, + 1022530 + ], + "DropList": [ + 1000919, + 1000319, + 1003180, + 1003180, + 999141 + ], + "StaminaCost": 20 + }, + "10061": { + "ID": 1006, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1006, + "StageID": 1022411, + "StageIDList": [ + 1022511, + 1022521, + 1022531 + ], + "DropList": [ + 1000919, + 1000339, + 1003180, + 1003180, + 1003180, + 1003180 + ], + "StaminaCost": 20 + }, + "10062": { + "ID": 1006, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1006, + "StageID": 1022412, + "StageIDList": [ + 1022512, + 1022522, + 1022532 + ], + "DropList": [ + 1000919, + 1000359, + 999142, + 1003180, + 1003180, + 1003180, + 1003180, + 999141 + ], + "StaminaCost": 20 + }, + "10063": { + "ID": 1006, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1006, + "StageID": 1022413, + "StageIDList": [ + 1022513, + 1022523, + 1022533 + ], + "DropList": [ + 1000919, + 1000389, + 999143, + 1003180, + 1003180, + 1003180, + 1003180, + 1003180 + ], + "StaminaCost": 20 + }, + "10070": { + "ID": 1007, + "WorldLevel": 0, + "PropID": 801, + "MappingInfoID": 1007, + "StageID": 1022410, + "StageIDList": [ + 1022610, + 1022620, + 1022630 + ], + "DropList": [ + 1000919, + 1000489 + ], + "StaminaCost": 20 + }, + "10071": { + "ID": 1007, + "WorldLevel": 1, + "PropID": 801, + "MappingInfoID": 1007, + "StageID": 1022411, + "StageIDList": [ + 1022611, + 1022621, + 1022631 + ], + "DropList": [ + 1000919, + 1000505 + ], + "StaminaCost": 20 + }, + "10072": { + "ID": 1007, + "WorldLevel": 2, + "PropID": 801, + "MappingInfoID": 1007, + "StageID": 1022412, + "StageIDList": [ + 1022612, + 1022622, + 1022632 + ], + "DropList": [ + 1000919, + 1000512 + ], + "StaminaCost": 20 + }, + "10073": { + "ID": 1007, + "WorldLevel": 3, + "PropID": 801, + "MappingInfoID": 1007, + "StageID": 1022413, + "StageIDList": [ + 1022613, + 1022623, + 1022633 + ], + "DropList": [ + 1000919, + 1000519 + ], + "StaminaCost": 20 + } +} \ No newline at end of file diff --git a/RPG.Services.Gameserver/Modules/AdventureModule.cs b/RPG.Services.Gameserver/Modules/AdventureModule.cs index 635839e..c0c6fc0 100644 --- a/RPG.Services.Gameserver/Modules/AdventureModule.cs +++ b/RPG.Services.Gameserver/Modules/AdventureModule.cs @@ -55,7 +55,8 @@ internal class AdventureModule : BaseModule public void OnBattleWin(uint battleMonster, IEnumerable assistMonsters) { - _mazeManager.RemoveEntities(assistMonsters.Append(battleMonster)); + if (battleMonster != 0) // 0 - not on-scene battle vs npcmonster, means cocoon or challenge + _mazeManager.RemoveEntities(assistMonsters.Append(battleMonster)); } public void OnBattleLost() @@ -63,6 +64,45 @@ internal class AdventureModule : BaseModule _mazeManager.ResetAvatarPosition(); } + [OnCommand(CmdType.CmdStartCocoonStageCsReq)] + public Task OnCmdStartCocoonStageCsReq(PlayerSession session, ReadOnlyMemory body) + { + StartCocoonStageCsReq req = StartCocoonStageCsReq.Parser.ParseFrom(body.Span); + + CocoonRow? cocoonRow = _excelTables.GetExcelRow(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.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 body) { diff --git a/RPG.Services.Gameserver/Modules/BattleModule.cs b/RPG.Services.Gameserver/Modules/BattleModule.cs index d88e675..4535df4 100644 --- a/RPG.Services.Gameserver/Modules/BattleModule.cs +++ b/RPG.Services.Gameserver/Modules/BattleModule.cs @@ -48,6 +48,8 @@ internal class BattleModule : BaseModule EndStatus = req.EndStatus }); + _battleMonsterAssists = []; + _battleMonsterEntityId = 0; return Task.CompletedTask; } @@ -65,6 +67,17 @@ internal class BattleModule : BaseModule StartBattle(monsterEntityId, assists); } + public void StartCocoonStage(CocoonRow cocoon, uint waveCount) + { + List stageIds = []; + for (int i = 0; i < waveCount; i++) + { + stageIds.Add(cocoon.StageIDList[i % cocoon.StageIDList.Length]); + } + + Battle = CreateBattleWithStages(stageIds); + } + private void StartBattle(uint monsterEntityId, IEnumerable assists) { _battleMonsterEntityId = monsterEntityId; @@ -74,31 +87,31 @@ internal class BattleModule : BaseModule if (_mazeManager.EntityManager.GetEntityById(monsterEntityId) is NpcMonsterEntity monster) { - battleEvents.Add(monster.EventId); + battleEvents.Add(monster.EventId * 10); } foreach (uint assistEntityId in assists) { if (_mazeManager.EntityManager.GetEntityById(assistEntityId) is NpcMonsterEntity assistMonster) { - battleEvents.Add(assistMonster.EventId); + battleEvents.Add(assistMonster.EventId * 10); } } - Battle = CreateBattleWithEvents(battleEvents); + Battle = CreateBattleWithStages(battleEvents); } - private SceneBattleInfo CreateBattleWithEvents(List battleEvents) + private SceneBattleInfo CreateBattleWithStages(List battleEvents) { SceneBattleInfo battle = new() { LogicRandomSeed = (uint)RandomNumberGenerator.GetInt32(int.MaxValue), - StageId = battleEvents[0] * 10, + StageId = battleEvents[0], }; foreach (uint eventId in battleEvents) { - StageRow stage = _excelTables.GetExcelRow(ExcelType.Stage, eventId * 10)!; + StageRow stage = _excelTables.GetExcelRow(ExcelType.Stage, eventId)!; foreach (StageMonsterWave stageWave in stage.MonsterList) {