diff --git a/BLHX.Server.Common/Data/Data.cs b/BLHX.Server.Common/Data/Data.cs index ede4255..89eaa62 100644 --- a/BLHX.Server.Common/Data/Data.cs +++ b/BLHX.Server.Common/Data/Data.cs @@ -16,6 +16,9 @@ public static class Data [LoadData("ship_skin_template.json", LoadDataType.ShareCfg)] public static Dictionary ShipSkinTemplate { get; private set; } = null!; + [LoadData("battle_cost_template.json", LoadDataType.ShareCfg)] + public static Dictionary BattleCostTemplate { get; private set; } = null!; + [LoadData("chapter_template.json", LoadDataType.ShareCfgData)] public static Dictionary ChapterTemplate { get; private set; } = null!; diff --git a/BLHX.Server.Common/Data/JSON.cs b/BLHX.Server.Common/Data/JSON.cs index fbbcbeb..f970784 100644 --- a/BLHX.Server.Common/Data/JSON.cs +++ b/BLHX.Server.Common/Data/JSON.cs @@ -1,4 +1,5 @@ -using System.Text.Json; +using BLHX.Server.Common.Utils; +using System.Text.Json; using System.Text.RegularExpressions; namespace BLHX.Server.Common.Data; @@ -19,7 +20,7 @@ public static partial class JSON } string text = File.ReadAllText(path); - if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Dictionary<,>) && typeof(T).GetGenericArguments()[0] == typeof(int)) + if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Dictionary<,>) && typeof(T).GetGenericArguments()[0].IsTypeNumeric()) { text = DictKeyAll().Replace(text, ""); } diff --git a/BLHX.Server.Common/Data/Model/BattleCostTemplate.cs b/BLHX.Server.Common/Data/Model/BattleCostTemplate.cs new file mode 100644 index 0000000..6df64bb --- /dev/null +++ b/BLHX.Server.Common/Data/Model/BattleCostTemplate.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; + +namespace BLHX.Server.Common.Data +{ + public class BattleCostTemplate + { + [JsonPropertyName("attack_count")] + public uint AttackCount { get; set; } + + [JsonPropertyName("cat_exp_award")] + public uint CatExpAward { get; set; } + + [JsonPropertyName("end_sink_cost")] + public uint EndSinkCost { get; set; } + + [JsonPropertyName("enter_energy_cost")] + public uint EnterEnergyCost { get; set; } + + [JsonPropertyName("global_buff_effected")] + public uint GlobalBuffEffected { get; set; } + + [JsonPropertyName("id")] + public uint Id { get; set; } + + [JsonPropertyName("oil_cost")] + public uint OilCost { get; set; } + + [JsonPropertyName("ship_exp_award")] + public uint ShipExpAward { get; set; } + + [JsonPropertyName("user_exp_award")] + public uint UserExpAward { get; set; } + } +} diff --git a/BLHX.Server.Common/Database/Player.cs b/BLHX.Server.Common/Database/Player.cs index 7482980..1dd39d0 100644 --- a/BLHX.Server.Common/Database/Player.cs +++ b/BLHX.Server.Common/Database/Player.cs @@ -205,7 +205,7 @@ namespace BLHX.Server.Common.Database } if (num < 0) - res.Num = (uint)Math.Max(res.Num - num, 0); + res.Num = (uint)Math.Max(res.Num + num, 0); else res.Num = Math.Min(res.Num + (uint)num, uint.MaxValue); } diff --git a/BLHX.Server.Common/Resources/ShareCfg/battle_cost_template.json b/BLHX.Server.Common/Resources/ShareCfg/battle_cost_template.json new file mode 100644 index 0000000..7c2dc75 --- /dev/null +++ b/BLHX.Server.Common/Resources/ShareCfg/battle_cost_template.json @@ -0,0 +1,316 @@ +{ + "0": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 0, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "1": { + "attack_count": 1, + "cat_exp_award": 1, + "end_sink_cost": 1, + "enter_energy_cost": 1, + "global_buff_effected": 1, + "id": 1, + "oil_cost": 1, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "2": { + "attack_count": 1, + "cat_exp_award": 1, + "end_sink_cost": 1, + "enter_energy_cost": 1, + "global_buff_effected": 0, + "id": 2, + "oil_cost": 1, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "3": { + "attack_count": 2, + "cat_exp_award": 1, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 3, + "oil_cost": 0, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "4": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 4, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "5": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 5, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "6": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 6, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "7": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 7, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "8": { + "attack_count": 1, + "cat_exp_award": 1, + "end_sink_cost": 0, + "enter_energy_cost": 1, + "global_buff_effected": 0, + "id": 8, + "oil_cost": 1, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "9": { + "attack_count": 1, + "cat_exp_award": 1, + "end_sink_cost": 0, + "enter_energy_cost": 1, + "global_buff_effected": 0, + "id": 9, + "oil_cost": 1, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "10": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 10, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "11": { + "attack_count": 1, + "cat_exp_award": 1, + "end_sink_cost": 1, + "enter_energy_cost": 1, + "global_buff_effected": 0, + "id": 11, + "oil_cost": 1, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "12": { + "attack_count": 0, + "cat_exp_award": 1, + "end_sink_cost": 1, + "enter_energy_cost": 1, + "global_buff_effected": 0, + "id": 12, + "oil_cost": 1, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "13": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 13, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "14": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 14, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "15": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 15, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "30": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 30, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "50": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 50, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "51": { + "attack_count": 0, + "cat_exp_award": 1, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 51, + "oil_cost": 0, + "ship_exp_award": 1, + "user_exp_award": 1 + }, + "93": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 93, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "94": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 94, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "95": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 95, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "96": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 96, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "97": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 97, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "98": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 98, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "99": { + "attack_count": 0, + "cat_exp_award": 0, + "end_sink_cost": 0, + "enter_energy_cost": 0, + "global_buff_effected": 0, + "id": 99, + "oil_cost": 0, + "ship_exp_award": 0, + "user_exp_award": 0 + }, + "all": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 50, + 51, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 30 + ] +} \ No newline at end of file diff --git a/BLHX.Server.Common/Utils/TypeExtensions.cs b/BLHX.Server.Common/Utils/TypeExtensions.cs new file mode 100644 index 0000000..768683f --- /dev/null +++ b/BLHX.Server.Common/Utils/TypeExtensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLHX.Server.Common.Utils +{ + public static class TypeExtensions + { + static readonly HashSet numericTypes = + [ + typeof(byte), + typeof(sbyte), + typeof(short), + typeof(ushort), + typeof(int), + typeof(uint), + typeof(float), + typeof(long), + typeof(ulong), + typeof(decimal) + ]; + + public static bool IsTypeNumeric(this Type type) + { + return numericTypes.Contains(type); + } + } +} diff --git a/BLHX.Server.Game/Handlers/P13.cs b/BLHX.Server.Game/Handlers/P13.cs index 6e9cb97..11fef02 100644 --- a/BLHX.Server.Game/Handlers/P13.cs +++ b/BLHX.Server.Game/Handlers/P13.cs @@ -31,6 +31,7 @@ namespace BLHX.Server.Game.Handlers if (x.Flag == ChapterAttachFlag.AttachEnemy) { cellInfo.ItemType = (uint)x.Flag; + // TODO: Use weigted values cellInfo.ItemId = (uint)chapterTemplate.ExpeditionIdWeightList[Random.Shared.Next(chapterTemplate.ExpeditionIdWeightList.Length)][0]; } @@ -90,13 +91,14 @@ namespace BLHX.Server.Game.Handlers case ChapterOP.OpMove: rsp.MovePaths.Add(new() { Row = req.ActArg1, Column = req.ActArg2 }); break; + case ChapterOP.OpEnemyRound: + break; case ChapterOP.OpRetreat: case ChapterOP.OpBox: case ChapterOP.OpAmbush: case ChapterOP.OpStrategy: case ChapterOP.OpRepair: case ChapterOP.OpSupply: - case ChapterOP.OpEnemyRound: case ChapterOP.OpSubState: case ChapterOP.OpStory: case ChapterOP.OpBarrier: @@ -113,6 +115,12 @@ namespace BLHX.Server.Game.Handlers connection.Send(rsp); } + [PacketHandler(Command.Cs13106)] + static void ChapterBattleResultRequestHandler(Connection connection, Packet packet) + { + connection.Send(new Sc13105()); + } + [PacketHandler(Command.Cs13505)] static void RemasterInfoRequestHandler(Connection connection, Packet packet) { diff --git a/BLHX.Server.Game/Handlers/P40.cs b/BLHX.Server.Game/Handlers/P40.cs new file mode 100644 index 0000000..18011b1 --- /dev/null +++ b/BLHX.Server.Game/Handlers/P40.cs @@ -0,0 +1,28 @@ +using BLHX.Server.Common.Proto; +using BLHX.Server.Common.Proto.p40; + +namespace BLHX.Server.Game.Handlers +{ + internal static class P40 + { + [PacketHandler(Command.Cs40001)] + static void BeginStageHandler(Connection connection, Packet packet) + { + // TODO: Check the importance of the request data and calculate oil and gold cost pls + connection.Send(new Sc40002()); + } + + [PacketHandler(Command.Cs40003)] + static void FinishStageHandler(Connection connection, Packet packet) + { + // TODO: Calculate rewarded EXP and drop rewards + var req = packet.Decode(); + + connection.Send(new Sc40004() + { + ShipExpLists = req.Statistics.Select(x => new ShipExp() { ShipId = x.ShipId, Intimacy = 10000 }).ToList(), + Mvp = req.Statistics.First().ShipId + }); + } + } +}