From bd79c42df09608788be51dfb4dd791cdf1122729 Mon Sep 17 00:00:00 2001 From: Somebody Date: Sun, 13 Oct 2024 10:49:34 +0800 Subject: [PATCH] Implement Gold And Gears Dice Surface --- .../ChessRogueDiceSurfaceEffectConfig.cs | 18 + Common/Data/GameData.cs | 2 + Common/Data/ResourceManager.cs | 39 ++ Common/Enums/Rogue/RogueCellMarkTypeEnum.cs | 13 + Config/ChessRogueDiceSurfaceEffect.json | 367 ++++++++++++++++++ .../ChessRogue/Cell/ChessRogueCellInstance.cs | 27 +- .../Game/ChessRogue/ChessRogueInstance.cs | 62 ++- .../ChessRogue/Dice/ChessRogueDiceInstance.cs | 42 +- .../ChessRogueDiceModifierInstance.cs | 99 +++++ .../ModifierEffectChangeSelectCellType.cs | 57 +++ ...ifierEffectReplicateCurCellToSelectCell.cs | 54 +++ ...difierEffectReplicateSelectCellToAround.cs | 79 ++++ .../ModifierEffectSetCellTypeAndTakeReward.cs | 100 +++++ .../ModifierEffectTrunAroundToEmptyGetBuff.cs | 69 ++++ .../ModifierEffectTurnRandomCellBlockType.cs | 68 ++++ .../ModifierEffect/ModifierEffectAttribute.cs | 10 + .../ModifierEffect/ModifierEffectHandler.cs | 13 + .../Game/Rogue/Buff/RogueBuffSelectMenu.cs | 4 +- .../Player/HandlerPlayerLoginFinishCsReq.cs | 6 +- .../Player/HandlerQueryProductInfoCsReq.cs | 13 + .../HandlerRogueModifierSelectCellCsReq.cs | 20 + .../PacketChessRogueCellUpdateNotify.cs | 27 +- .../Player/PacketQueryProductInfoScRsp.cs | 17 + .../PacketRogueModifierAddNotify.cs | 18 + .../PacketRogueModifierDelNotify.cs | 18 + .../PacketRogueModifierSelectCellScRsp.cs | 17 + .../PacketRogueModifierStageStartNotify.cs | 17 + 27 files changed, 1259 insertions(+), 17 deletions(-) create mode 100644 Common/Data/Custom/ChessRogueDiceSurfaceEffectConfig.cs create mode 100644 Common/Enums/Rogue/RogueCellMarkTypeEnum.cs create mode 100644 Config/ChessRogueDiceSurfaceEffect.json create mode 100644 GameServer/Game/ChessRogue/Modifier/ChessRogueDiceModifierInstance.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectChangeSelectCellType.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateCurCellToSelectCell.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateSelectCellToAround.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectSetCellTypeAndTakeReward.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTrunAroundToEmptyGetBuff.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTurnRandomCellBlockType.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectAttribute.cs create mode 100644 GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectHandler.cs create mode 100644 GameServer/Server/Packet/Recv/Player/HandlerQueryProductInfoCsReq.cs create mode 100644 GameServer/Server/Packet/Recv/RogueModifier/HandlerRogueModifierSelectCellCsReq.cs create mode 100644 GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs create mode 100644 GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierAddNotify.cs create mode 100644 GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierDelNotify.cs create mode 100644 GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierSelectCellScRsp.cs create mode 100644 GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierStageStartNotify.cs diff --git a/Common/Data/Custom/ChessRogueDiceSurfaceEffectConfig.cs b/Common/Data/Custom/ChessRogueDiceSurfaceEffectConfig.cs new file mode 100644 index 00000000..9e540c52 --- /dev/null +++ b/Common/Data/Custom/ChessRogueDiceSurfaceEffectConfig.cs @@ -0,0 +1,18 @@ +using EggLink.DanhengServer.Enums.Rogue; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace EggLink.DanhengServer.Data.Custom; + +public class ChessRogueDiceSurfaceEffectConfig +{ + public int SurfaceId { get; set; } + public List ContentEffects { get; set; } = []; +} + +public class ChessRogueDiceSurfaceContentEffect +{ + [JsonConverter(typeof(StringEnumConverter))] + public ModifierEffectTypeEnum EffectType { get; set; } + public Dictionary Params { get; set; } = []; +} \ No newline at end of file diff --git a/Common/Data/GameData.cs b/Common/Data/GameData.cs index 8da7b476..248a96b6 100644 --- a/Common/Data/GameData.cs +++ b/Common/Data/GameData.cs @@ -67,6 +67,8 @@ public static class GameData public static Dictionary> ChessRogueRoomData { get; private set; } = []; + public static Dictionary ChessRogueDiceSurfaceEffectData { get; set; } = []; + public static Dictionary RogueDLCAreaData { get; private set; } = []; public static Dictionary RogueDLCBossDecayData { get; private set; } = []; public static Dictionary RogueDLCBossBpData { get; private set; } = []; diff --git a/Common/Data/ResourceManager.cs b/Common/Data/ResourceManager.cs index 4c35613b..39d9d065 100644 --- a/Common/Data/ResourceManager.cs +++ b/Common/Data/ResourceManager.cs @@ -43,6 +43,7 @@ public class ResourceManager new RogueMiracleEffectConfig(); LoadChessRogueRoomData(); LoadRogueTournRoomData(); + LoadChessRogueDiceSurfaceEffectData(); Task.WaitAll(t1, t2, t3, t4, t5, t6, t7); } @@ -769,6 +770,44 @@ public class ResourceManager I18NManager.Translate("Word.RogueTournRoomInfo"))); } + public static void LoadChessRogueDiceSurfaceEffectData() + { + Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadingItem", + I18NManager.Translate("Word.RogueDiceSurfaceInfo"))); + var count = 0; + + FileInfo file = new(ConfigManager.Config.Path.ConfigPath + "/ChessRogueDiceSurfaceEffect.json"); + + if (!file.Exists) + { + Logger.Warn(I18NManager.Translate("Server.ServerInfo.ConfigMissing", + I18NManager.Translate("Word.RogueDiceSurfaceInfo"), + $"{ConfigManager.Config.Path.ConfigPath}/ChessRogueDiceSurfaceEffect.json", + I18NManager.Translate("Word.RogueDiceSurface"))); + + return; + } + + try + { + using var reader = file.OpenRead(); + using StreamReader reader2 = new(reader); + var text = reader2.ReadToEnd(); + var json = JsonConvert.DeserializeObject>(text); + if (json == null) throw new Exception("Failed to deserialize ChessRogueDiceSurfaceEffect.json"); + + GameData.ChessRogueDiceSurfaceEffectData = json; + count = json.Count; + } + catch (Exception ex) + { + Logger.Error("Error in reading " + file.Name, ex); + } + + Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), + I18NManager.Translate("Word.RogueDiceSurfaceInfo"))); + } + public static void AddRoomToGameData(RogueDLCBlockTypeEnum type, ChessRogueRoomConfig room) { if (GameData.ChessRogueRoomData.TryGetValue(type, out var list)) diff --git a/Common/Enums/Rogue/RogueCellMarkTypeEnum.cs b/Common/Enums/Rogue/RogueCellMarkTypeEnum.cs new file mode 100644 index 00000000..029786dd --- /dev/null +++ b/Common/Enums/Rogue/RogueCellMarkTypeEnum.cs @@ -0,0 +1,13 @@ +namespace EggLink.DanhengServer.Enums.Rogue; + +public enum RogueCellMarkTypeEnum +{ + + None = 0, + Enhance = 1, + Buff = 2, + Heteromorphosis = 3, + Miracle = 5, + Double = 6, + Choice = 7 +} \ No newline at end of file diff --git a/Config/ChessRogueDiceSurfaceEffect.json b/Config/ChessRogueDiceSurfaceEffect.json new file mode 100644 index 00000000..e17f52af --- /dev/null +++ b/Config/ChessRogueDiceSurfaceEffect.json @@ -0,0 +1,367 @@ +{ + "2001": { + "SurfaceId": 2001, + "ContentEffects": [ + { + "EffectType": "SetCellTypeAndTakeReward", + "Params": { + "SourceType": "3;5", + "TargetType": "1", + "Reward": "Area,0" + } + + } + ] + }, + "2002": { + "SurfaceId": 2002, + "ContentEffects": [ + { + "EffectType": "SetCellTypeAndTakeReward", + "Params": { + "SourceType": "7;8;9", + "TargetType": "1", + "Reward": "Event,Buff" + } + } + ] + }, + "2003": { + "SurfaceId": 2003, + "ContentEffects": [ + { + "EffectType": "TrunAroundToEmptyGetBuff", + "Params": { + "SourceType": "2;3;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "1", + "Reward": "Cell,Buff" + } + } + ] + }, + "2004": { + "SurfaceId": 2004, + "ContentEffects": [ + { + "EffectType": "ChangeSelectCellType", + "Params": { + "SourceType": "1;2;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "3" + } + } + ] + }, + "2005": { + "SurfaceId": 2005, + "ContentEffects": [ + { + "EffectType": "TurnRandomCellBlockType", + "Params": { + "SourceType": "1;2;3;4;5;6;7;10;13;14;16;17", + "TargetType": "8;9", + "Count": "1" + } + } + ] + }, + "2006": { + "SurfaceId": 2006, + "ContentEffects": [ + { + "EffectType": "ReplicateCurCellToSelectCell", + "Params": { + "SourceType": "1;2;3;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "0" + } + } + ] + }, + "2007": { + "SurfaceId": 2007, + "ContentEffects": [ + { + "EffectType": "ReplicateSelectCellToAround", + "Params": { + "SourceType": "1;2;3;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "0", + "Count": "1" + } + } + ] + }, + "2008": { + "SurfaceId": 2008, + "ContentEffects": [ + { + "EffectType": "ReRandomCellTypeGetMoney", + "Params": { + "SourceType": "1;2;3;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "2;3;4;5;6;7;8;9;10;13;14;16;17", + "Reward": "Cell,Money", + "Count": "50" + } + } + ] + }, + "2009": { + "SurfaceId": 2009, + "ContentEffects": [ + { + "EffectType": "SetBlockTypeToAround", + "Params": { + "SourceType": "1;2;3;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "0", + "Count": "1" + } + } + ] + }, + "2010": { + "SurfaceId": 2010, + "ContentEffects": [ + { + "EffectType": "ReplicateSelectCellToRandom", + "Params": { + "SourceType": "1;2;3;4;5;6;7;8;9;10;13;14;16;17", + "TargetType": "0", + "Count": 2 + } + } + ] + }, + "2011": { + "SurfaceId": 2011, + "ContentEffects": [ + { + "EffectType": "SetBlockTypeToAround", + "Params": { + "SourceType": "3", + "TargetType": "3", + "Count": "1" + } + } + ] + }, + "2012": { + "SurfaceId": 2012, + "ContentEffects": [ + { + "EffectType": "TurnRandomCellBlockType", + "Params": { + "SourceType": "5;6", + "TargetType": "7", + "Count": "1" + } + } + ] + }, + "2013": { + "SurfaceId": 2013, + "ContentEffects": [ + { + "EffectType": "SwapCellToCurAround", + "Params": { + "SourceType": "3,5" + } + } + ] + }, + "2017": { + "SurfaceId": 2017, + "ContentEffects": [ + { + "EffectType": "ReplicateCurCellToRandom", + "Params": { + "Count": 2 + } + } + ] + }, + "2046": { + "SurfaceId": 2046, + "ContentEffects": [ + { + "EffectType": "SetColCanMove", + "Params": { + "Count": "~1;~2;~3" + } + } + ] + }, + "2058": { + "SurfaceId": 2058, + "ContentEffects": [ + { + "EffectType": "GetMoneyOnAbandonMiracle", + "Params": { + "Count": "100" + } + } + ] + }, + "2061": { + "SurfaceId": 2061, + "ContentEffects": [ + { + "EffectType": "AddMiracleList", + "Params": { + "SelectMiracle": "10002,1", + "AddMiracle": "10003,1" + } + } + ] + }, + "2062": { + "SurfaceId": 2062, + "ContentEffects": [ + { + "EffectType": "AbandonReGetMiracle" + } + ] + }, + "2063": { + "SurfaceId": 2063, + "ContentEffects": [ + { + "EffectType": "SetRandomCellToTargeType", + "Params": { + "SourceType": "1;2;3;4;5;6;7;8;9;10;14;16;17", + "TargetType": "13", + "Count": "2" + } + } + ] + }, + "2064": { + "SurfaceId": 2064, + "ContentEffects": [ + { + "EffectType": "GetMoneyOnEnterCell", + "Params": { + "SourceType": "13", + "Count": "150" + } + } + ] + }, + "2065": { + "SurfaceId": 2065, + "ContentEffects": [ + { + "EffectType": "GetMoneyOnSelectCellToTargetType", + "Params": { + "SourceType": "5;6;7", + "TargetType": "13", + "Count": "150" + } + } + ] + }, + "2066": { + "SurfaceId": 2066, + "ContentEffects": [ + { + "EffectType": "GetMoneyByMiracleCount", + "Params": { + "Count": "50" + } + } + ] + }, + "2067": { + "SurfaceId": 2067, + "ContentEffects": [ + { + "EffectType": "ShopDiscountOnTradeCell", + "Params": { + "Discount": "1.5" + } + } + ] + }, + "2068": { + "SurfaceId": 2068, + "ContentEffects": [ + { + "EffectType": "GetMoneyChangeActionPoint", + "Params": { + "Count": "200", + "ActionPoint": "-1" + } + } + ] + }, + "2070": { + "SurfaceId": 2070, + "ContentEffects": [ + { + "EffectType": "AddActionPointOnGetMiracle", + "Params": { + "AddMiracle": "10003,1", + "ActionPoint": "-1" + } + } + ] + }, + "2071": { + "SurfaceId": 2071, + "ContentEffects": [ + { + "EffectType": "GetMoneyActionPointOnAbandonMiracle", + "Params": { + "LoseCount": "1", + "Money": "0", + "ActionPoint": "1" + } + } + ] + }, + "2072": { + "SurfaceId": 2072, + "ContentEffects": [ + { + "EffectType": "AddActionPointOnSetCellType", + "Params": { + "SourceType": "6;7", + "TargetType": "1", + "ActionPoint": "1" + } + } + ] + }, + "2089": { + "SurfaceId": 2089, + "ContentEffects": [ + { + "EffectType": "AddMazeBuff", + "Params": { + "BuffId": "650310" + } + } + ] + }, + "2101": { + "SurfaceId": 2101, + "ContentEffects": [ + { + "EffectType": "RandomSetReplaceMarkType", + "Params": { + "SourceType": "7;8;9", + "TargetType": "6;7", + "Count": "2" + } + } + ] + }, + "2103": { + "SurfaceId": 2103, + "ContentEffects": [ + { + "EffectType": "SetNearestBlockCanMove", + "Params": { + "SourceType": "5;7" + } + } + ] + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Cell/ChessRogueCellInstance.cs b/GameServer/Game/ChessRogue/Cell/ChessRogueCellInstance.cs index 1517e7c2..8cde53a6 100644 --- a/GameServer/Game/ChessRogue/Cell/ChessRogueCellInstance.cs +++ b/GameServer/Game/ChessRogue/Cell/ChessRogueCellInstance.cs @@ -34,6 +34,7 @@ public class ChessRogueCellInstance public ChessRogueInstance Instance { get; set; } public ChessRogueBoardCellStatus CellStatus { get; set; } = ChessRogueBoardCellStatus.Idle; public ChessRogueRoomConfig? RoomConfig { get; set; } + public RogueCellMarkTypeEnum MarkType { get; set; } = RogueCellMarkTypeEnum.None; public int SelectMonsterId { get; set; } public List SelectedDecayId { get; set; } = []; @@ -126,6 +127,14 @@ public class ChessRogueCellInstance return CellId; } + public bool IsCollapsed() + { + var curCell = Instance.CurCell; + if (curCell == null) return true; + + return curCell.PosX >= PosX; // only check the left side of the board + } + public int GetEntryId() { if (RoomConfig != null) return RoomConfig.EntranceId; @@ -156,7 +165,20 @@ public class ChessRogueCellInstance { var groupList = new List(); groupList.AddRange(RoomConfig!.DefaultLoadBasicGroup); - groupList.AddRange(RoomConfig.DefaultLoadGroup); + + switch (MarkType) + { + case RogueCellMarkTypeEnum.Choice: + groupList.AddRange(RoomConfig.SelectEventLoadGroup); + break; + case RogueCellMarkTypeEnum.Double: + groupList.AddRange(RoomConfig.DoubleEventLoadGroup); + break; + default: + groupList.AddRange(RoomConfig.DefaultLoadGroup); + break; + } + groupList.AddRange(RoomConfig.SubMonsterGroup); return groupList; @@ -173,7 +195,8 @@ public class ChessRogueCellInstance IsUnlock = true, RoomId = (uint)RoomId, PLOEJLHMONC = true, - PosX = (uint)GetRow() + PosX = (uint)GetRow(), + MarkType = (uint)MarkType }; if (CellAdvanceInfo.Count <= 0) return info; diff --git a/GameServer/Game/ChessRogue/ChessRogueInstance.cs b/GameServer/Game/ChessRogue/ChessRogueInstance.cs index 0c9384d7..f77ab82e 100644 --- a/GameServer/Game/ChessRogue/ChessRogueInstance.cs +++ b/GameServer/Game/ChessRogue/ChessRogueInstance.cs @@ -5,13 +5,18 @@ using EggLink.DanhengServer.Enums.Rogue; using EggLink.DanhengServer.GameServer.Game.Battle; using EggLink.DanhengServer.GameServer.Game.ChessRogue.Cell; using EggLink.DanhengServer.GameServer.Game.ChessRogue.Dice; +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect; +using EggLink.DanhengServer.GameServer.Game.Mission.FinishAction; +using EggLink.DanhengServer.GameServer.Game.Mission.FinishType; using EggLink.DanhengServer.GameServer.Game.Player; using EggLink.DanhengServer.GameServer.Game.Rogue; using EggLink.DanhengServer.GameServer.Game.Rogue.Buff; using EggLink.DanhengServer.GameServer.Game.Rogue.Event; using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Util; +using System.Reflection; namespace EggLink.DanhengServer.GameServer.Game.ChessRogue; @@ -29,9 +34,19 @@ public class ChessRogueInstance : BaseRogueInstance Layers = areaExcel.LayerIDList; CurLayer = Layers.First(); EventManager = new RogueEventManager(player, this); - RogueType = rogueSubMode == RogueSubModeEnum.ChessRogueNous ? 160 : 130; + + var types = Assembly.GetExecutingAssembly().GetTypes(); + foreach (var type in types) + { + var attr = type.GetCustomAttribute(); + if (attr == null) continue; + + var handler = (ModifierEffectHandler)Activator.CreateInstance(type, null)!; + ModifierEffectHandlers.Add(attr.EffectType, handler); + } + foreach (var difficulty in areaExcel.DifficultyID) if (GameData.RogueDLCDifficultyData.TryGetValue(difficulty, out var diff)) DifficultyExcel.Add(diff); @@ -55,6 +70,7 @@ public class ChessRogueInstance : BaseRogueInstance public int BossAeonId { get; set; } public List DifficultyExcel { get; set; } = []; public ChessRogueDiceInstance DiceInstance { get; set; } + public Dictionary ModifierEffectHandlers { get; set; } = []; public Dictionary RogueCells { get; set; } = []; public ChessRogueCellInstance? CurCell { get; set; } @@ -70,6 +86,7 @@ public class ChessRogueInstance : BaseRogueInstance public int LayerMap { get; set; } public int ActionPoint { get; set; } = 15; + public int CurModifierId { get; set; } = 1; public List DisableAeonIds { get; set; } = []; @@ -108,6 +125,11 @@ public class ChessRogueInstance : BaseRogueInstance WaveFlag = -1 }); } + + + if (DiceInstance.Modifier == null) return; + var modifier = DiceInstance.Modifier; + modifier.BeforeBattle(this, battle); } public void CalculateDifficulty(BattleInstance battle) @@ -165,6 +187,12 @@ public class ChessRogueInstance : BaseRogueInstance await RollBuff(battle.Stages.Count); + if (DiceInstance.Modifier != null) + { + var modifier = DiceInstance.Modifier; + await modifier.AfterBattle(this, battle); + } + switch (CurCell!.BlockType) { case RogueDLCBlockTypeEnum.MonsterBoss: @@ -352,6 +380,12 @@ public class ChessRogueInstance : BaseRogueInstance await Player.SendPacket(new PacketChessRogueCellUpdateNotify(cell, CurBoardExcel?.ChessBoardID ?? 0)); await CostActionPoint(1); + if (DiceInstance.Modifier != null) + { + var modifier = DiceInstance.Modifier; + await modifier.SelectCell(this, cellId); + } + await Player.SendPacket(new PacketChessRogueSelectCellScRsp(cellId)); } @@ -387,7 +421,7 @@ public class ChessRogueInstance : BaseRogueInstance public async ValueTask ConfirmRoll() { - DiceInstance.DiceStatus = ChessRogueDiceStatus.ChessRogueDiceConfirmed; + await DiceInstance.ConfirmDice(); await Player.SendPacket(new PacketChessRogueUpdateDiceInfoScNotify(DiceInstance)); await Player.SendPacket(new PacketChessRogueConfirmRollScRsp(DiceInstance)); @@ -408,6 +442,30 @@ public class ChessRogueInstance : BaseRogueInstance #endregion + #region Modifier + + public async ValueTask ApplyModifier(int selectCellId) + { + if (DiceInstance.Modifier == null) return; + + var modifier = DiceInstance.Modifier; + if (selectCellId == 0) + { + modifier.IsConfirmed = true; + await Player.SendPacket(new PacketRogueModifierStageStartNotify(modifier.SourceType)); + // gain money + await GainMoney(10, 2); + + await Player.SendPacket(new PacketChessRogueUpdateDiceInfoScNotify(DiceInstance)); + return; + } + await modifier.SelectModifierCell(this, selectCellId); + + await Player.SendPacket(new PacketChessRogueUpdateDiceInfoScNotify(DiceInstance)); + } + + #endregion + #region Action Management public async ValueTask CostActionPoint(int cost) diff --git a/GameServer/Game/ChessRogue/Dice/ChessRogueDiceInstance.cs b/GameServer/Game/ChessRogue/Dice/ChessRogueDiceInstance.cs index 2ca075de..06362543 100644 --- a/GameServer/Game/ChessRogue/Dice/ChessRogueDiceInstance.cs +++ b/GameServer/Game/ChessRogue/Dice/ChessRogueDiceInstance.cs @@ -1,4 +1,8 @@ -using EggLink.DanhengServer.Database.ChessRogue; +using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Data.Custom; +using EggLink.DanhengServer.Database.ChessRogue; +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Util; @@ -6,14 +10,19 @@ namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Dice; public class ChessRogueDiceInstance(ChessRogueInstance instance, ChessRogueNousDiceData diceData) { - public int CheatTimes = 1; + public int CheatTimes { get; set; } = 1; - public int CurSurfaceId; - public ChessRogueNousDiceData DiceData = diceData; + public int CurSurfaceId { get; set; } + public ChessRogueNousDiceData DiceData { get; set; } = diceData; - public ChessRogueDiceStatus DiceStatus = ChessRogueDiceStatus.ChessRogueDiceIdle; - public ChessRogueInstance Instance = instance; - public int RerollTimes = 1; + public ChessRogueDiceStatus DiceStatus { get; set; } = ChessRogueDiceStatus.ChessRogueDiceIdle; + public ChessRogueInstance Instance { get; set; } = instance; + public int RerollTimes { get; set; } = 1; + + public ChessRogueDiceSurfaceEffectConfig? CurrentSurfaceEffectConfig => + GameData.ChessRogueDiceSurfaceEffectData.GetValueOrDefault(CurSurfaceId); + + public ChessRogueDiceModifierInstance? Modifier { get; set; } public void RollDice() { @@ -21,6 +30,23 @@ public class ChessRogueDiceInstance(ChessRogueInstance instance, ChessRogueNousD DiceStatus = ChessRogueDiceStatus.ChessRogueDiceRolled; } + public async ValueTask ConfirmDice() + { + DiceStatus = ChessRogueDiceStatus.ChessRogueDiceConfirmed; + + if (CurrentSurfaceEffectConfig == null) return; + + if (Modifier != null) // Remove the previous modifier + await Instance.Player.SendPacket(new PacketRogueModifierDelNotify(Modifier)); + + Modifier = new ChessRogueDiceModifierInstance(Instance.CurModifierId++, + CurrentSurfaceEffectConfig.ContentEffects.First()); + + await Modifier.OnConfirmed(Instance); + + await Instance.Player.SendPacket(new PacketRogueModifierAddNotify(Modifier)); + } + public ChessRogueDiceInfo ToProto() { @@ -39,7 +65,7 @@ public class ChessRogueDiceInstance(ChessRogueInstance instance, ChessRogueNousD CurSurfaceSlotId = (uint)(index > 0 ? index : 0), //DisplayId = (uint)(CurSurfaceId > 0 ? GameData.RogueNousDiceSurfaceData[CurSurfaceId].Sort : 0), CanRerollDice = RerollTimes > 0, - DiceModifier = new RogueModifier(), + DiceModifier = Modifier?.ToProto() ?? new RogueModifier(), DMHLBBFPELI = new BAKPIDLEIFI() }; } diff --git a/GameServer/Game/ChessRogue/Modifier/ChessRogueDiceModifierInstance.cs b/GameServer/Game/ChessRogue/Modifier/ChessRogueDiceModifierInstance.cs new file mode 100644 index 00000000..36fc205f --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ChessRogueDiceModifierInstance.cs @@ -0,0 +1,99 @@ +using EggLink.DanhengServer.Data.Custom; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier; + +public class ChessRogueDiceModifierInstance(int modifierId, ChessRogueDiceSurfaceContentEffect effect) +{ + public int ModifierId { get; set; } = modifierId; + public ChessRogueDiceSurfaceContentEffect EffectConfig { get; set; } = effect; + public RogueModifierSourceType SourceType { get; set; } = RogueModifierSourceType.RogueModifierSourceDiceRoll; + public List SelectableCells { get; set; } = []; + public int SelectedCell { get; set; } + public bool IsConfirmed { get; set; } + + #region Effect + + public async ValueTask SelectCell(ChessRogueInstance instance, int selectCellId) + { + var effect = EffectConfig.EffectType; + + instance.ModifierEffectHandlers.TryGetValue(effect, out var handler); + + if (handler != null) + await handler.SelectCell(this, instance, selectCellId); + else + IsConfirmed = true; + } + + public async ValueTask SelectModifierCell(ChessRogueInstance instance, int selectCellId) + { + var effect = EffectConfig.EffectType; + + instance.ModifierEffectHandlers.TryGetValue(effect, out var handler); + + if (handler != null) + await handler.SelectModifierCell(this, instance, selectCellId); + else + IsConfirmed = true; + } + + public async ValueTask OnConfirmed(ChessRogueInstance instance) + { + var effect = EffectConfig.EffectType; + + instance.ModifierEffectHandlers.TryGetValue(effect, out var handler); + + if (handler != null) + await handler.OnConfirmed(this, instance); + else + IsConfirmed = true; + } + + public void BeforeBattle(ChessRogueInstance instance, BattleInstance battle) + { + var effect = EffectConfig.EffectType; + + instance.ModifierEffectHandlers.TryGetValue(effect, out var handler); + + if (handler != null) + handler.BeforeBattle(this, battle); + else + IsConfirmed = true; + } + + public async ValueTask AfterBattle(ChessRogueInstance instance, BattleInstance battle) + { + var effect = EffectConfig.EffectType; + + instance.ModifierEffectHandlers.TryGetValue(effect, out var handler); + + if (handler != null) + await handler.AfterBattle(this, battle); + else + IsConfirmed = true; + } + + #endregion + + public RogueModifier ToProto() + { + return new RogueModifier + { + MainModifierEffect = (ulong)ModifierId, + ModifierSourceType = SourceType, + ModifierContent = new RogueModifierContent + { + ContentModifierEffectId = (uint)EffectConfig.EffectType, + ModifierContentType = RogueModifierContentType.RogueModifierContentDefinite + }, + ModifierInfo = new ChessRogueModifierInfo + { + LBMGNJJEPFM = { SelectableCells.Select(x => (uint)x) }, + SelectCellId = (uint)SelectedCell, + Confirm = IsConfirmed + } + }; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectChangeSelectCellType.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectChangeSelectCellType.cs new file mode 100644 index 00000000..7bfab754 --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectChangeSelectCellType.cs @@ -0,0 +1,57 @@ +using EggLink.DanhengServer.Enums.Rogue; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; +using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Util; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect.Effects; + +[ModifierEffect(ModifierEffectTypeEnum.ChangeSelectCellType)] +public class ModifierEffectChangeSelectCellType : ModifierEffectHandler +{ + public override async ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance) + { + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed()); + modifierInstance.SelectableCells.AddRange(cells.Select(x => x.Key)); + } + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + var cell = chessRogueInstance.RogueCells[selectCellId]; + + modifierInstance.SelectedCell = selectCellId; + modifierInstance.IsConfirmed = true; + + await chessRogueInstance.Player.SendPacket(new PacketRogueModifierStageStartNotify(modifierInstance.SourceType)); + + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("TargetType", "3").Split(";"); + var targetType = types.Select(x => (RogueDLCBlockTypeEnum)int.Parse(x)).ToList().RandomElement(); + + cell.BlockType = targetType; + + await chessRogueInstance.Player.SendPacket(new PacketChessRogueCellUpdateNotify(cell, chessRogueInstance.CurBoardExcel?.ChessBoardID ?? 0, modifierInstance.SourceType, ChessRogueCellUpdateReason.Modifier)); + } + + public override async ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + } + + public override async ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + await ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateCurCellToSelectCell.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateCurCellToSelectCell.cs new file mode 100644 index 00000000..1f13819e --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateCurCellToSelectCell.cs @@ -0,0 +1,54 @@ +using EggLink.DanhengServer.Enums.Rogue; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect.Effects; + +[ModifierEffect(ModifierEffectTypeEnum.ReplicateCurCellToSelectCell)] +public class ModifierEffectReplicateCurCellToSelectCell : ModifierEffectHandler +{ + public override async ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance) + { + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed()); + modifierInstance.SelectableCells.AddRange(cells.Select(x => x.Key)); + } + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await chessRogueInstance.Player.SendPacket(new PacketRogueModifierStageStartNotify(modifierInstance.SourceType)); + + modifierInstance.SelectedCell = selectCellId; + modifierInstance.IsConfirmed = true; + var targetCell = chessRogueInstance.RogueCells[selectCellId]; + var curCell = chessRogueInstance.CurCell; + + targetCell.BlockType = curCell?.BlockType ?? RogueDLCBlockTypeEnum.Empty; + + // Send packet to update the cell + await chessRogueInstance.Player.SendPacket(new PacketChessRogueCellUpdateNotify(targetCell, chessRogueInstance.CurBoardExcel?.ChessBoardID ?? 0, modifierInstance.SourceType, ChessRogueCellUpdateReason.Modifier)); + } + + public override async ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + } + + public override async ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + await ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateSelectCellToAround.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateSelectCellToAround.cs new file mode 100644 index 00000000..f2418e29 --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectReplicateSelectCellToAround.cs @@ -0,0 +1,79 @@ +using EggLink.DanhengServer.Enums.Rogue; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Cell; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using System.Collections.Generic; +using EggLink.DanhengServer.Util; +using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect.Effects; + +[ModifierEffect(ModifierEffectTypeEnum.ReplicateSelectCellToAround)] +public class ModifierEffectReplicateSelectCellToAround : ModifierEffectHandler +{ + public override async ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance) + { + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => + x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed()); + modifierInstance.SelectableCells.AddRange(cells.Select(x => x.Key)); + } + + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await chessRogueInstance.Player.SendPacket(new PacketRogueModifierStageStartNotify(modifierInstance.SourceType)); + modifierInstance.SelectedCell = selectCellId; + modifierInstance.IsConfirmed = true; + + var targetCell = chessRogueInstance.RogueCells[selectCellId]; + var count = int.Parse(modifierInstance.EffectConfig.Params.GetValueOrDefault("Count", "1")); + List targetCells = []; + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => + x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed() && + Math.Abs(x.Value.PosX - targetCell.PosX) <= 1 && Math.Abs(x.Value.PosY - targetCell.PosY) <= 1); + + targetCells.AddRange(cells.Select(x => x.Value)); + } + targetCells.Remove(targetCell); + + List updated = []; + for (var i = 0; i < count; i++) + { + if (targetCells.Count == 0) + break; + var cell = targetCells.RandomElement(); + cell.BlockType = targetCell.BlockType; + targetCells.Remove(cell); + updated.Add(cell); + } + + // Send packet to update the cell + await chessRogueInstance.Player.SendPacket(new PacketChessRogueCellUpdateNotify(updated, chessRogueInstance.CurBoardExcel?.ChessBoardID ?? 0, modifierInstance.SourceType, ChessRogueCellUpdateReason.Modifier)); + } + + public override async ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + } + + public override async ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + await ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectSetCellTypeAndTakeReward.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectSetCellTypeAndTakeReward.cs new file mode 100644 index 00000000..7c7ce5b6 --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectSetCellTypeAndTakeReward.cs @@ -0,0 +1,100 @@ +using EggLink.DanhengServer.Enums.Rogue; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; +using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Util; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect.Effects; + +[ModifierEffect(ModifierEffectTypeEnum.SetCellTypeAndTakeReward)] +public class ModifierEffectSetCellTypeAndTakeReward : ModifierEffectHandler +{ + public override async ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance) + { + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed()); + modifierInstance.SelectableCells.AddRange(cells.Select(x => x.Key)); + } + + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await chessRogueInstance.Player.SendPacket(new PacketRogueModifierStageStartNotify(modifierInstance.SourceType)); + modifierInstance.SelectedCell = selectCellId; + modifierInstance.IsConfirmed = true; + + var cell = chessRogueInstance.RogueCells[selectCellId]; + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("TargetType", "3").Split(";"); + var targetType = types.Select(x => (RogueDLCBlockTypeEnum)int.Parse(x)).ToList().RandomElement(); + var rewards = modifierInstance.EffectConfig.Params.GetValueOrDefault("Reward", "").Split(";"); + foreach (var reward in rewards) + { + var param = reward.Split(","); + if (param.Length != 2) continue; + + switch (param[0]) + { + case "Area": + if (cell.BlockType == RogueDLCBlockTypeEnum.MonsterElite) + { + await chessRogueInstance.RollBuff(1, 100003); + await chessRogueInstance.GainMoney(Random.Shared.Next(70, 150), 2); + } + else + { + await chessRogueInstance.RollBuff(1, 100004); + await chessRogueInstance.GainMoney(Random.Shared.Next(40, 60), 2); + } + break; + case "Event": + var eventCount = cell.MarkType switch + { + RogueCellMarkTypeEnum.Choice => 3, + RogueCellMarkTypeEnum.Double => 2, + _ => 1 + }; + + switch (param[1]) + { + case "Buff": + await chessRogueInstance.RollBuff(eventCount, 100004); + break; + case "Money": + await chessRogueInstance.GainMoney( + int.Parse(modifierInstance.EffectConfig.Params.GetValueOrDefault("Count", "10")), 2); + break; + } + + break; + } + } + + cell.BlockType = targetType; + + await chessRogueInstance.Player.SendPacket(new PacketChessRogueCellUpdateNotify(cell, + chessRogueInstance.CurBoardExcel?.ChessBoardID ?? 0, modifierInstance.SourceType, + ChessRogueCellUpdateReason.Modifier)); + } + + public override async ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + } + + public override async ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + await ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTrunAroundToEmptyGetBuff.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTrunAroundToEmptyGetBuff.cs new file mode 100644 index 00000000..0b159852 --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTrunAroundToEmptyGetBuff.cs @@ -0,0 +1,69 @@ +using EggLink.DanhengServer.Enums.Rogue; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Cell; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect.Effects; + +[ModifierEffect(ModifierEffectTypeEnum.TrunAroundToEmptyGetBuff)] // I don't know why it's called TrunAround instead of TurnAround, maybe miHoYo r sleeping lol +public class ModifierEffectTrunAroundToEmptyGetBuff : ModifierEffectHandler +{ + public override async ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance) + { + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await chessRogueInstance.Player.SendPacket(new PacketRogueModifierStageStartNotify(modifierInstance.SourceType)); + var targetCell = chessRogueInstance.RogueCells[selectCellId]; + modifierInstance.IsConfirmed = true; + + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + + List targetCells = []; + var count = 0; + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => + x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed() && + Math.Abs(x.Value.PosX - targetCell.PosX) <= 1 && Math.Abs(x.Value.PosY - targetCell.PosY) <= 1); + + targetCells.AddRange(cells.Select(x => x.Value)); + } + + foreach (var cell in targetCells) + { + if (cell.BlockType != RogueDLCBlockTypeEnum.Empty) + count++; + cell.BlockType = RogueDLCBlockTypeEnum.Empty; + } + + await chessRogueInstance.Player.SendPacket(new PacketChessRogueCellUpdateNotify(targetCells, + chessRogueInstance.CurBoardExcel?.ChessBoardID ?? 0, modifierInstance.SourceType, + ChessRogueCellUpdateReason.Modifier)); + + if (count > 0) + { + await chessRogueInstance.RollBuff(count, 100004); + } + } + + public override void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + } + + public override async ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + await ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTurnRandomCellBlockType.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTurnRandomCellBlockType.cs new file mode 100644 index 00000000..b1d0bcff --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/Effects/ModifierEffectTurnRandomCellBlockType.cs @@ -0,0 +1,68 @@ +using EggLink.DanhengServer.Enums.Rogue; +using EggLink.DanhengServer.GameServer.Game.Battle; +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Cell; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; +using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Util; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect.Effects; + +[ModifierEffect(ModifierEffectTypeEnum.TurnRandomCellBlockType)] +public class ModifierEffectTurnRandomCellBlockType : ModifierEffectHandler +{ + public override async ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance) + { + await chessRogueInstance.Player.SendPacket(new PacketRogueModifierStageStartNotify(modifierInstance.SourceType)); + + List targetCells = []; + var types = modifierInstance.EffectConfig.Params.GetValueOrDefault("SourceType", "3").Split(";"); + var targetTypes = modifierInstance.EffectConfig.Params.GetValueOrDefault("TargetType", "3").Split(";").Select(x => (RogueDLCBlockTypeEnum)int.Parse(x)).ToList(); + var count = int.Parse(modifierInstance.EffectConfig.Params.GetValueOrDefault("Count", "1")); + foreach (var type in types) + { + var cells = chessRogueInstance.RogueCells.Where(x => + x.Value.BlockType == (RogueDLCBlockTypeEnum)int.Parse(type) && !x.Value.IsCollapsed()); + + targetCells.AddRange(cells.Select(x => x.Value)); + } + + List updated = []; + for (var i = 0; i < count; i++) + { + if (targetCells.Count == 0) + break; + var targetCell = targetCells.RandomElement(); + targetCell.BlockType = targetTypes.RandomElement(); + targetCells.Remove(targetCell); + updated.Add(targetCell); + } + + await chessRogueInstance.Player.SendPacket(new PacketChessRogueCellUpdateNotify(updated, + chessRogueInstance.CurBoardExcel?.ChessBoardID ?? 0, modifierInstance.SourceType, + ChessRogueCellUpdateReason.Modifier)); + + modifierInstance.IsConfirmed = true; + } + + public override async ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override async ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, + int selectCellId) + { + await ValueTask.CompletedTask; + } + + public override void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + } + + public override async ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle) + { + await ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectAttribute.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectAttribute.cs new file mode 100644 index 00000000..1843b9e6 --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectAttribute.cs @@ -0,0 +1,10 @@ +using EggLink.DanhengServer.Enums.Rogue; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect +{ + [AttributeUsage(AttributeTargets.Class)] + public class ModifierEffectAttribute(ModifierEffectTypeEnum effectType) : Attribute + { + public ModifierEffectTypeEnum EffectType { get; } = effectType; + } +} diff --git a/GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectHandler.cs b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectHandler.cs new file mode 100644 index 00000000..0431b9dc --- /dev/null +++ b/GameServer/Game/ChessRogue/Modifier/ModifierEffect/ModifierEffectHandler.cs @@ -0,0 +1,13 @@ +using EggLink.DanhengServer.GameServer.Game.Battle; + +namespace EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect +{ + public abstract class ModifierEffectHandler + { + public abstract ValueTask OnConfirmed(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance); + public abstract ValueTask SelectModifierCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, int selectCellId); + public abstract ValueTask SelectCell(ChessRogueDiceModifierInstance modifierInstance, ChessRogueInstance chessRogueInstance, int selectCellId); + public abstract void BeforeBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle); + public abstract ValueTask AfterBattle(ChessRogueDiceModifierInstance modifierInstance, BattleInstance battle); + } +} diff --git a/GameServer/Game/Rogue/Buff/RogueBuffSelectMenu.cs b/GameServer/Game/Rogue/Buff/RogueBuffSelectMenu.cs index ae531fb7..4463139a 100644 --- a/GameServer/Game/Rogue/Buff/RogueBuffSelectMenu.cs +++ b/GameServer/Game/Rogue/Buff/RogueBuffSelectMenu.cs @@ -27,9 +27,9 @@ public class RogueBuffSelectMenu(BaseRogueInstance rogue) foreach (var buff in buffs) if (buff.RogueBuffType == rogue.RogueBuffType) - list.Add(buff, (int)(20f / (int)buff.RogueBuffCategory * 2.5)); + list.Add(buff, 20); else - list.Add(buff, (int)(20f / (int)buff.RogueBuffCategory * 0.7)); + list.Add(buff, 15); var result = new List(); for (var i = 0; i < count; i++) diff --git a/GameServer/Server/Packet/Recv/Player/HandlerPlayerLoginFinishCsReq.cs b/GameServer/Server/Packet/Recv/Player/HandlerPlayerLoginFinishCsReq.cs index 213b0c01..9a53a86c 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerPlayerLoginFinishCsReq.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerPlayerLoginFinishCsReq.cs @@ -9,6 +9,10 @@ public class HandlerPlayerLoginFinishCsReq : Handler { await connection.SendPacket(CmdIds.PlayerLoginFinishScRsp); //var list = connection.Player!.MissionManager!.GetRunningSubMissionIdList(); - //connection.SendPacket(new PacketMissionAcceptScNotify(list)); + //await connection.SendPacket(new PacketMonthCardRewardNotify([new ItemData + //{ + // ItemId = 1, + // Count = 90 + //}])); } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/Player/HandlerQueryProductInfoCsReq.cs b/GameServer/Server/Packet/Recv/Player/HandlerQueryProductInfoCsReq.cs new file mode 100644 index 00000000..23b4513a --- /dev/null +++ b/GameServer/Server/Packet/Recv/Player/HandlerQueryProductInfoCsReq.cs @@ -0,0 +1,13 @@ +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; +using EggLink.DanhengServer.Kcp; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.Player; + +[Opcode(CmdIds.QueryProductInfoCsReq)] +public class HandlerQueryProductInfoCsReq : Handler +{ + public override async Task OnHandle(Connection connection, byte[] header, byte[] data) + { + await connection.SendPacket(new PacketQueryProductInfoScRsp()); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/RogueModifier/HandlerRogueModifierSelectCellCsReq.cs b/GameServer/Server/Packet/Recv/RogueModifier/HandlerRogueModifierSelectCellCsReq.cs new file mode 100644 index 00000000..51f690d2 --- /dev/null +++ b/GameServer/Server/Packet/Recv/RogueModifier/HandlerRogueModifierSelectCellCsReq.cs @@ -0,0 +1,20 @@ +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.RogueModifier; + +[Opcode(CmdIds.RogueModifierSelectCellCsReq)] +public class HandlerRogueModifierSelectCellCsReq : Handler +{ + public override async Task OnHandle(Connection connection, byte[] header, byte[] data) + { + var req = RogueModifierSelectCellCsReq.Parser.ParseFrom(data); + + if (connection.Player!.ChessRogueManager?.RogueInstance == null) return; + + await connection.Player!.ChessRogueManager!.RogueInstance.ApplyModifier((int)req.CellId); + + await connection.SendPacket(new PacketRogueModifierSelectCellScRsp(req.CellId)); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/ChessRogue/PacketChessRogueCellUpdateNotify.cs b/GameServer/Server/Packet/Send/ChessRogue/PacketChessRogueCellUpdateNotify.cs index c699863d..28ba9830 100644 --- a/GameServer/Server/Packet/Send/ChessRogue/PacketChessRogueCellUpdateNotify.cs +++ b/GameServer/Server/Packet/Send/ChessRogue/PacketChessRogueCellUpdateNotify.cs @@ -6,16 +6,39 @@ namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.ChessRogue; public class PacketChessRogueCellUpdateNotify : BasePacket { - public PacketChessRogueCellUpdateNotify(ChessRogueCellInstance cell, int boardId) : base( + public PacketChessRogueCellUpdateNotify(ChessRogueCellInstance cell, int boardId, + RogueModifierSourceType source = RogueModifierSourceType.RogueModifierSourceNone, + ChessRogueCellUpdateReason reason = ChessRogueCellUpdateReason.None) : base( CmdIds.ChessRogueCellUpdateNotify) { var proto = new ChessRogueCellUpdateNotify { - BoardId = (uint)boardId + BoardId = (uint)boardId, + ModifierSource = source, + Reason = reason }; proto.CellList.Add(cell.ToProto()); SetData(proto); } + + + public PacketChessRogueCellUpdateNotify(List cells, int boardId, + RogueModifierSourceType source = RogueModifierSourceType.RogueModifierSourceNone, + ChessRogueCellUpdateReason reason = ChessRogueCellUpdateReason.None) : base( + CmdIds.ChessRogueCellUpdateNotify) + { + var proto = new ChessRogueCellUpdateNotify + { + BoardId = (uint)boardId, + ModifierSource = source, + Reason = reason + }; + + foreach (var cell in cells) + proto.CellList.Add(cell.ToProto()); + + SetData(proto); + } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs b/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs new file mode 100644 index 00000000..66c24035 --- /dev/null +++ b/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs @@ -0,0 +1,17 @@ +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; + +public class PacketQueryProductInfoScRsp : BasePacket +{ + public PacketQueryProductInfoScRsp() : base(CmdIds.QueryProductInfoScRsp) + { + var proto = new QueryProductInfoScRsp + { + //PEKJLBINDGG = (ulong)Extensions.GetUnixSec() + 8640000, // 100 day + }; + + SetData(proto); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierAddNotify.cs b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierAddNotify.cs new file mode 100644 index 00000000..01ccdaf3 --- /dev/null +++ b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierAddNotify.cs @@ -0,0 +1,18 @@ +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; + +public class PacketRogueModifierAddNotify : BasePacket +{ + public PacketRogueModifierAddNotify(ChessRogueDiceModifierInstance modifier) : base(CmdIds.RogueModifierAddNotify) + { + var proto = new RogueModifierAddNotify + { + Modifier = modifier.ToProto() + }; + + SetData(proto); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierDelNotify.cs b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierDelNotify.cs new file mode 100644 index 00000000..3d971e98 --- /dev/null +++ b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierDelNotify.cs @@ -0,0 +1,18 @@ +using EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; + +public class PacketRogueModifierDelNotify : BasePacket +{ + public PacketRogueModifierDelNotify(ChessRogueDiceModifierInstance modifier) : base(CmdIds.RogueModifierDelNotify) + { + var proto = new RogueModifierDelNotify + { + MainModifierEffect = (ulong)modifier.ModifierId + }; + + SetData(proto); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierSelectCellScRsp.cs b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierSelectCellScRsp.cs new file mode 100644 index 00000000..548d1c12 --- /dev/null +++ b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierSelectCellScRsp.cs @@ -0,0 +1,17 @@ +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; + +public class PacketRogueModifierSelectCellScRsp : BasePacket +{ + public PacketRogueModifierSelectCellScRsp(uint cellId) : base(CmdIds.RogueModifierSelectCellScRsp) + { + var proto = new RogueModifierSelectCellScRsp + { + CellId = cellId + }; + + SetData(proto); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierStageStartNotify.cs b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierStageStartNotify.cs new file mode 100644 index 00000000..37388ea5 --- /dev/null +++ b/GameServer/Server/Packet/Send/RogueModifier/PacketRogueModifierStageStartNotify.cs @@ -0,0 +1,17 @@ +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueModifier; + +public class PacketRogueModifierStageStartNotify : BasePacket +{ + public PacketRogueModifierStageStartNotify(RogueModifierSourceType source) : base(CmdIds.RogueModifierStageStartNotify) + { + var proto = new RogueModifierStageStartNotify + { + ModifierSourceType = source + }; + + SetData(proto); + } +} \ No newline at end of file