From 637147227808e9ab7b3bd672c5307374fc32c1dd Mon Sep 17 00:00:00 2001 From: Somebody Date: Sat, 14 Sep 2024 23:00:50 +0800 Subject: [PATCH] Fix Basic Challenge --- Common/Data/Excel/ChallengeBossExtraExcel.cs | 2 +- Common/Data/Excel/ChallengeConfigExcel.cs | 1 + Common/Data/Excel/ChallengeStoryExtraExcel.cs | 2 +- Common/Data/Excel/StageConfigExcel.cs | 2 +- Common/Database/Inventory/InventoryData.cs | 29 +++ GameServer/Game/Battle/BattleInstance.cs | 7 +- .../Game/Challenge/ChallengeEntityLoader.cs | 8 +- .../Game/Challenge/ChallengeInstance.cs | 185 +++++++++++++++--- GameServer/Game/Inventory/InventoryManager.cs | 18 +- .../HandlerEnterChallengeNextPhaseCsReq.cs | 21 ++ .../PacketChallengeBossPhaseSettleNotify.cs | 5 +- .../PacketEnterChallengeNextPhaseScRsp.cs | 29 +++ .../Challenge/PacketStartChallengeScRsp.cs | 1 + 13 files changed, 266 insertions(+), 44 deletions(-) create mode 100644 GameServer/Server/Packet/Recv/Challenge/HandlerEnterChallengeNextPhaseCsReq.cs create mode 100644 GameServer/Server/Packet/Send/Challenge/PacketEnterChallengeNextPhaseScRsp.cs diff --git a/Common/Data/Excel/ChallengeBossExtraExcel.cs b/Common/Data/Excel/ChallengeBossExtraExcel.cs index 2a16760c..7827194a 100644 --- a/Common/Data/Excel/ChallengeBossExtraExcel.cs +++ b/Common/Data/Excel/ChallengeBossExtraExcel.cs @@ -13,7 +13,7 @@ public class ChallengeBossExtraExcel : ExcelResource return ID; } - public override void Loaded() + public override void AfterAllDone() { if (GameData.ChallengeConfigData.ContainsKey(ID)) { diff --git a/Common/Data/Excel/ChallengeConfigExcel.cs b/Common/Data/Excel/ChallengeConfigExcel.cs index 4d283151..21ca9cd0 100644 --- a/Common/Data/Excel/ChallengeConfigExcel.cs +++ b/Common/Data/Excel/ChallengeConfigExcel.cs @@ -14,6 +14,7 @@ public class ChallengeConfigExcel : ExcelResource public int ID { get; set; } public int GroupID { get; set; } public int MapEntranceID { get; set; } + public int MapEntranceID2 { get; set; } public int StageNum { get; set; } public int ChallengeCountDown { get; set; } public int MazeBuffID { get; set; } diff --git a/Common/Data/Excel/ChallengeStoryExtraExcel.cs b/Common/Data/Excel/ChallengeStoryExtraExcel.cs index 174e1a0a..0f4627d3 100644 --- a/Common/Data/Excel/ChallengeStoryExtraExcel.cs +++ b/Common/Data/Excel/ChallengeStoryExtraExcel.cs @@ -14,7 +14,7 @@ public class ChallengeStoryExtraExcel : ExcelResource return ID; } - public override void Loaded() + public override void AfterAllDone() { if (GameData.ChallengeConfigData.ContainsKey(ID)) { diff --git a/Common/Data/Excel/StageConfigExcel.cs b/Common/Data/Excel/StageConfigExcel.cs index 5a730490..53454c7d 100644 --- a/Common/Data/Excel/StageConfigExcel.cs +++ b/Common/Data/Excel/StageConfigExcel.cs @@ -2,7 +2,7 @@ namespace EggLink.DanhengServer.Data.Excel; -[ResourceEntity("StageConfig.json", false)] +[ResourceEntity("StageConfig.json,StageTestConfig.json", true)] public class StageConfigExcel : ExcelResource { public int StageID { get; set; } = 0; diff --git a/Common/Database/Inventory/InventoryData.cs b/Common/Database/Inventory/InventoryData.cs index 608f6adf..46948dcc 100644 --- a/Common/Database/Inventory/InventoryData.cs +++ b/Common/Database/Inventory/InventoryData.cs @@ -127,6 +127,35 @@ public class ItemData }; } + public ChallengeBossEquipmentInfo ToChallengeEquipmentProto() + { + return new ChallengeBossEquipmentInfo + { + Tid = (uint)ItemId, + UniqueId = (uint)UniqueId, + Level = (uint)Level, + Promotion = (uint)Promotion, + Rank = (uint)Rank + }; + } + + public ChallengeBossRelicInfo ToChallengeRelicProto() + { + var proto = new ChallengeBossRelicInfo + { + Tid = (uint)ItemId, + UniqueId = (uint)UniqueId, + Level = (uint)Level, + MainAffixId = (uint)MainAffix + }; + + if (SubAffixes.Count < 1) return proto; + foreach (var subAffix in SubAffixes) + proto.SubAffixList.Add(subAffix.ToProto()); + + return proto; + } + public Item ToProto() { return new Item diff --git a/GameServer/Game/Battle/BattleInstance.cs b/GameServer/Game/Battle/BattleInstance.cs index f2e8f892..c300cec1 100644 --- a/GameServer/Game/Battle/BattleInstance.cs +++ b/GameServer/Game/Battle/BattleInstance.cs @@ -30,7 +30,9 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List monster.GetStageId())) { - GameData.StageConfigData.TryGetValue(id, out var stage); + GameData.PlaneEventData.TryGetValue(id * 10 + player.Data.WorldLevel, out var planeEvent); + if (planeEvent == null) continue; + GameData.StageConfigData.TryGetValue(planeEvent.StageID, out var stage); if (stage != null) Stages.Add(stage); } @@ -214,7 +216,8 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List wave.ToProto())) diff --git a/GameServer/Game/Challenge/ChallengeEntityLoader.cs b/GameServer/Game/Challenge/ChallengeEntityLoader.cs index 52688d4a..37f26ad0 100644 --- a/GameServer/Game/Challenge/ChallengeEntityLoader.cs +++ b/GameServer/Game/Challenge/ChallengeEntityLoader.cs @@ -54,10 +54,10 @@ public class ChallengeEntityLoader(SceneInstance scene, PlayerInstance player) : // Get current stage monster infos Dictionary challengeMonsters; - if (instance.Excel.MazeGroupID1 == group.Id) - challengeMonsters = instance.Excel.ChallengeMonsters1; - else if (instance.Excel.MazeGroupID2 == group.Id) - challengeMonsters = instance.Excel.ChallengeMonsters2; + if (instance.Excel.MazeGroupID1 == group.Id || instance.Excel.MazeGroupID2 == group.Id) + { + challengeMonsters = instance.CurrentStage == 1 ? instance.Excel.ChallengeMonsters1 : instance.Excel.ChallengeMonsters2; + } else return null; diff --git a/GameServer/Game/Challenge/ChallengeInstance.cs b/GameServer/Game/Challenge/ChallengeInstance.cs index 8f4b2a70..7a74a632 100644 --- a/GameServer/Game/Challenge/ChallengeInstance.cs +++ b/GameServer/Game/Challenge/ChallengeInstance.cs @@ -2,6 +2,7 @@ using EggLink.DanhengServer.Data; using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Database.Challenge; +using EggLink.DanhengServer.Enums.Item; using EggLink.DanhengServer.Enums.Mission; using EggLink.DanhengServer.GameServer.Game.Battle; using EggLink.DanhengServer.GameServer.Game.Player; @@ -132,13 +133,22 @@ public class ChallengeInstance ScoreTwo = (uint)ScoreStage2, RoundCount = (uint)GetRoundsElapsed(), ExtraLineupType = (ExtraLineupType)CurrentExtraLineup, - StageInfo = new ChallengeStoryInfo - { - CurStoryBuffs = new ChallengeStoryBuffList(), - CurBossBuffs = new ChallengeBossBuffList() - } + StageInfo = new ChallengeStoryInfo() }; + if (Excel.IsBoss()) + { + proto.StageInfo.CurBossBuffs = new ChallengeBossBuffList + { + ChallengeBossConst = 1 + }; + } + + if (Excel.IsStory()) + { + proto.StageInfo.CurStoryBuffs = new ChallengeStoryBuffList(); + } + if (StoryBuffs.Count >= CurrentStage) proto.StageInfo.CurStoryBuffs.BuffList.Add(StoryBuffs.Select(x => (uint)x)); @@ -148,6 +158,65 @@ public class ChallengeInstance return proto; } + public ChallengeStageInfo ToStageInfo() + { + var proto = new ChallengeStageInfo(); + + if (Excel.IsBoss()) + { + proto.BossInfo = new ChallengeBossInfo + { + FirstNode = new ChallengeBossSingleNodeInfo + { + BuffId = (uint)BossBuffs[0] + }, + SecondNode = new ChallengeBossSingleNodeInfo + { + BuffId = (uint)BossBuffs[1] + }, + LBOJBINABDG = true + }; + + foreach (var lineupAvatar in Player.LineupManager?.GetExtraLineup(ExtraLineupType.LineupChallenge)?.BaseAvatars ?? []) + { + var avatar = Player.AvatarManager?.GetAvatar(lineupAvatar.BaseAvatarId); + if (avatar == null) continue; + proto.BossInfo.FirstLineup.Add((uint)avatar.GetAvatarId()); + proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.GetAvatarId(), Player.InventoryManager?.GetItem(0, avatar.GetCurPathInfo().EquipId, ItemMainTypeEnum.Equipment)?.ToChallengeEquipmentProto()); // it wont be null + + var relicProto = new ChallengeBossAvatarRelicInfo(); + + foreach (var relicUniqueId in avatar.GetCurPathInfo().Relic) + { + var relic = Player.InventoryManager?.GetItem(0, relicUniqueId.Value, ItemMainTypeEnum.Relic); + if (relic == null) continue; + relicProto.AvatarRelicSlotMap.Add((uint)relicUniqueId.Key, relic.ToChallengeRelicProto()); + } + proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.GetAvatarId(), relicProto); + } + + foreach (var lineupAvatar in Player.LineupManager?.GetExtraLineup(ExtraLineupType.LineupChallenge2)?.BaseAvatars ?? []) + { + var avatar = Player.AvatarManager?.GetAvatar(lineupAvatar.BaseAvatarId); + if (avatar == null) continue; + proto.BossInfo.FirstLineup.Add((uint)avatar.GetAvatarId()); + proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.GetAvatarId(), Player.InventoryManager?.GetItem(0, avatar.GetCurPathInfo().EquipId, ItemMainTypeEnum.Equipment)?.ToChallengeEquipmentProto()); // it wont be null + + var relicProto = new ChallengeBossAvatarRelicInfo(); + + foreach (var relicUniqueId in avatar.GetCurPathInfo().Relic) + { + var relic = Player.InventoryManager?.GetItem(0, relicUniqueId.Value, ItemMainTypeEnum.Relic); + if (relic == null) continue; + relicProto.AvatarRelicSlotMap.Add((uint)relicUniqueId.Key, relic.ToChallengeRelicProto()); + } + proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.GetAvatarId(), relicProto); + } + } + + return proto; + } + #endregion #region Management @@ -156,15 +225,12 @@ public class ChallengeInstance { battle.RoundLimit = RoundsLeft; - if (StoryBuffs != null) - { - battle.Buffs.Add(new MazeBuff(Excel.MazeBuffID, 1, -1)); + battle.Buffs.Add(new MazeBuff(Excel.MazeBuffID, 1, -1)); - if (StoryBuffs.Count >= CurrentStage) - { - var buffId = StoryBuffs[CurrentStage - 1]; - battle.Buffs.Add(new MazeBuff(buffId, 1, -1)); - } + if (StoryBuffs.Count >= CurrentStage) + { + var buffId = StoryBuffs[CurrentStage - 1]; + battle.Buffs.Add(new MazeBuff(buffId, 1, -1)); } if (Excel.StoryExcel != null) @@ -173,6 +239,12 @@ public class ChallengeInstance foreach (var id in Excel.StoryExcel.BattleTargetID!) battle.AddBattleTarget(5, id, GetTotalScore()); } + + if (Excel.BossExcel != null) + { + battle.AddBattleTarget(1, 90004, 0); + battle.AddBattleTarget(1, 90005, 0); + } } public virtual async ValueTask OnBattleEnd(BattleInstance battle, PVEBattleResultCsReq req) @@ -189,6 +261,22 @@ public class ChallengeInstance ScoreStage2 = stageScore; } + if (IsBoss()) + { + // Calculate score for current stage + var stageScore = 0; + foreach (var battleTarget in req.Stt.BattleTargetInfo[1].BattleTargetList_) + { + stageScore += (int)battleTarget.Progress; + } + + // Set score + if (CurrentStage == 1) + ScoreStage1 = stageScore; + else + ScoreStage2 = stageScore; + } + switch (req.EndStatus) { case BattleEndStatus.BattleEndWin: @@ -200,7 +288,7 @@ public class ChallengeInstance // Get monster count in stage long monsters = Player.SceneInstance!.Entities.Values.OfType().Count(); - if (monsters == 0) await AdvanceStage(); + if (monsters == 0) await AdvanceStage(req); // Calculate rounds left if (IsStory()) RoundsLeft = (int)Math.Min(Math.Max(RoundsLeft - req.Stt.RoundCnt, 1), RoundsLeft); @@ -219,7 +307,7 @@ public class ChallengeInstance // Determine challenge result if ((IsStory() || IsBoss()) && req.Stt.EndReason == BattleEndReason.TurnLimit) { - await AdvanceStage(); + await AdvanceStage(req); } else { @@ -234,7 +322,7 @@ public class ChallengeInstance } } - private async ValueTask AdvanceStage() + private async ValueTask AdvanceStage(PVEBattleResultCsReq req) { if (CurrentStage >= Excel.StageNum) { @@ -247,7 +335,7 @@ public class ChallengeInstance // Send challenge result data if (IsBoss()) - await Player.SendPacket(new PacketChallengeBossPhaseSettleNotify(this)); + await Player.SendPacket(new PacketChallengeBossPhaseSettleNotify(this, req.Stt.BattleTargetInfo[1])); else await Player.SendPacket(new PacketChallengeSettleNotify(this)); @@ -256,23 +344,62 @@ public class ChallengeInstance } else { - // Increment and reset stage - CurrentStage++; + if (IsBoss()) + { + await Player.SendPacket(new PacketChallengeBossPhaseSettleNotify(this, req.Stt.BattleTargetInfo[1])); + } + else + { + // Increment and reset stage + CurrentStage++; + // Load scene group for stage 2 + await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2); - // Load scene group for stage 2 - await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2); + // Change player line up + SetCurrentExtraLineup(ExtraLineupType.LineupChallenge2); + await Player.LineupManager!.SetCurLineup(CurrentExtraLineup + 10); + await Player.SendPacket(new PacketChallengeLineupNotify((ExtraLineupType)CurrentExtraLineup)); + SavedMp = Player.LineupManager.GetCurLineup()!.Mp; - // Change player line up - SetCurrentExtraLineup(ExtraLineupType.LineupChallenge2); - await Player.LineupManager!.SetCurLineup(CurrentExtraLineup + 10); - await Player.SendPacket(new PacketChallengeLineupNotify((ExtraLineupType)CurrentExtraLineup)); - SavedMp = Player.LineupManager.GetCurLineup()!.Mp; - - // Move player - await Player.MoveTo(StartPos, StartRot); + // Move player + if (Excel.MapEntranceID2 != 0) + { + await Player.EnterScene(Excel.MapEntranceID2, 0, true); + StartPos = Player.Data.Pos!; + StartRot = Player.Data.Rot!; + await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2); + } + else + await Player.MoveTo(StartPos, StartRot); + } } } + public async ValueTask NextPhase() + { + // Increment and reset stage + CurrentStage++; + // Load scene group for stage 2 + await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2); + + // Change player line up + SetCurrentExtraLineup(ExtraLineupType.LineupChallenge2); + await Player.LineupManager!.SetCurLineup(CurrentExtraLineup + 10); + await Player.SendPacket(new PacketChallengeLineupNotify((ExtraLineupType)CurrentExtraLineup)); + SavedMp = Player.LineupManager.GetCurLineup()!.Mp; + + // Move player + if (Excel.MapEntranceID2 != 0) + { + await Player.EnterScene(Excel.MapEntranceID2, 0, false); + StartPos = Player.Data.Pos!; + StartRot = Player.Data.Rot!; + await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2); + } + else + await Player.MoveTo(StartPos, StartRot); + } + public void OnUpdate() { // End challenge if its done diff --git a/GameServer/Game/Inventory/InventoryManager.cs b/GameServer/Game/Inventory/InventoryManager.cs index 8cdf4315..bc95806a 100644 --- a/GameServer/Game/Inventory/InventoryManager.cs +++ b/GameServer/Game/Inventory/InventoryManager.cs @@ -326,18 +326,26 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) return itemData; } - public ItemData? GetItem(int itemId) + /// + /// Get item by itemId and uniqueId, if uniqueId provided, itemId will be ignored + /// + /// + /// + /// + public ItemData? GetItem(int itemId, int uniqueId = 0, ItemMainTypeEnum mainType = ItemMainTypeEnum.Unknown) { GameData.ItemConfigData.TryGetValue(itemId, out var itemConfig); - if (itemConfig == null) return null; - switch (itemConfig.ItemMainType) + if (itemConfig == null && mainType == ItemMainTypeEnum.Unknown) return null; + if (itemConfig != null) + mainType = itemConfig.ItemMainType; + switch (mainType) { case ItemMainTypeEnum.Material: return Data.MaterialItems.Find(x => x.ItemId == itemId); case ItemMainTypeEnum.Equipment: - return Data.EquipmentItems.Find(x => x.ItemId == itemId); + return uniqueId > 0 ? Data.EquipmentItems.Find(x => x.UniqueId == uniqueId) : Data.EquipmentItems.Find(x => x.ItemId == itemId); case ItemMainTypeEnum.Relic: - return Data.RelicItems.Find(x => x.ItemId == itemId); + return uniqueId > 0 ? Data.RelicItems.Find(x => x.UniqueId == uniqueId) : Data.RelicItems.Find(x => x.ItemId == itemId); case ItemMainTypeEnum.Virtual: switch (itemConfig.ID) { diff --git a/GameServer/Server/Packet/Recv/Challenge/HandlerEnterChallengeNextPhaseCsReq.cs b/GameServer/Server/Packet/Recv/Challenge/HandlerEnterChallengeNextPhaseCsReq.cs new file mode 100644 index 00000000..53112396 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Challenge/HandlerEnterChallengeNextPhaseCsReq.cs @@ -0,0 +1,21 @@ +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Challenge; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.Challenge; + +[Opcode(CmdIds.EnterChallengeNextPhaseCsReq)] +public class HandlerEnterChallengeNextPhaseCsReq : Handler +{ + public override async Task OnHandle(Connection connection, byte[] header, byte[] data) + { + if (connection.Player!.ChallengeManager?.ChallengeInstance == null) + { + await connection.SendPacket(new PacketEnterChallengeNextPhaseScRsp(Retcode.RetChallengeNotDoing)); + return; + } + + await connection.Player.ChallengeManager.ChallengeInstance.NextPhase(); + await connection.SendPacket(new PacketEnterChallengeNextPhaseScRsp(connection.Player)); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Challenge/PacketChallengeBossPhaseSettleNotify.cs b/GameServer/Server/Packet/Send/Challenge/PacketChallengeBossPhaseSettleNotify.cs index 2a2a7ae9..13e160bd 100644 --- a/GameServer/Server/Packet/Send/Challenge/PacketChallengeBossPhaseSettleNotify.cs +++ b/GameServer/Server/Packet/Send/Challenge/PacketChallengeBossPhaseSettleNotify.cs @@ -1,12 +1,13 @@ using EggLink.DanhengServer.GameServer.Game.Challenge; using EggLink.DanhengServer.Kcp; using EggLink.DanhengServer.Proto; +using Google.Protobuf.Collections; namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Challenge; public class PacketChallengeBossPhaseSettleNotify : BasePacket { - public PacketChallengeBossPhaseSettleNotify(ChallengeInstance challenge) : base(CmdIds + public PacketChallengeBossPhaseSettleNotify(ChallengeInstance challenge, BattleTargetList? targetLists = null) : base(CmdIds .ChallengeBossPhaseSettleNotify) { var proto = new ChallengeBossPhaseSettleNotify @@ -21,6 +22,8 @@ public class PacketChallengeBossPhaseSettleNotify : BasePacket IsReward = true }; + proto.BattleTargetList.AddRange(targetLists?.BattleTargetList_ ?? []); + SetData(proto); } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Challenge/PacketEnterChallengeNextPhaseScRsp.cs b/GameServer/Server/Packet/Send/Challenge/PacketEnterChallengeNextPhaseScRsp.cs new file mode 100644 index 00000000..c75018ac --- /dev/null +++ b/GameServer/Server/Packet/Send/Challenge/PacketEnterChallengeNextPhaseScRsp.cs @@ -0,0 +1,29 @@ +using EggLink.DanhengServer.GameServer.Game.Challenge; +using EggLink.DanhengServer.GameServer.Game.Player; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Challenge; + +public class PacketEnterChallengeNextPhaseScRsp : BasePacket +{ + public PacketEnterChallengeNextPhaseScRsp(PlayerInstance instance) : base(CmdIds.EnterChallengeNextPhaseScRsp) + { + var proto = new EnterChallengeNextPhaseScRsp + { + Scene = instance.SceneInstance!.ToProto() + }; + + SetData(proto); + } + + public PacketEnterChallengeNextPhaseScRsp(Retcode code) : base(CmdIds.EnterChallengeNextPhaseScRsp) + { + var proto = new EnterChallengeNextPhaseScRsp + { + Retcode = (uint)code + }; + + SetData(proto); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Challenge/PacketStartChallengeScRsp.cs b/GameServer/Server/Packet/Send/Challenge/PacketStartChallengeScRsp.cs index 099d7190..8c9f9cd8 100644 --- a/GameServer/Server/Packet/Send/Challenge/PacketStartChallengeScRsp.cs +++ b/GameServer/Server/Packet/Send/Challenge/PacketStartChallengeScRsp.cs @@ -23,6 +23,7 @@ public class PacketStartChallengeScRsp : BasePacket if (player.ChallengeManager!.ChallengeInstance != null) { proto.CurChallenge = player.ChallengeManager.ChallengeInstance.ToProto(); + proto.StageInfo = player.ChallengeManager.ChallengeInstance.ToStageInfo(); proto.LineupList.Add(player.LineupManager!.GetExtraLineup(ExtraLineupType.LineupChallenge)!.ToProto()); proto.LineupList.Add(player.LineupManager!.GetExtraLineup(ExtraLineupType.LineupChallenge2)!.ToProto()); if (sendScene) proto.Scene = player.SceneInstance!.ToProto();