From 57219895fb5e71e0770821b857ce61e8effd6b40 Mon Sep 17 00:00:00 2001 From: milimoe <110188673+milimoe@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:25:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E8=AE=A1=20Item=20=E7=B1=BB=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=E5=BA=94=E7=9A=84=20Converter?= =?UTF-8?q?=EF=BC=9B=E6=96=B0=E5=A2=9E=E4=BC=A4=E5=AE=B3=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 设计 Item 类,添加对应的 Converter * 新增伤害统计和 AlterActionTypeBeforeAction --- Api/Factory/EffectFactory.cs | 15 + Api/Factory/ItemFactory.cs | 18 +- Api/Factory/SkillFactory.cs | 15 + Api/Utility/ActionQueue.cs | 295 +++++++++++++----- Api/Utility/Factory.cs | 25 +- Api/Utility/General.cs | 36 +++ Entity/Character/Character.cs | 26 +- Entity/Character/CharacterProfile.cs | 6 + Entity/Character/EquipSlot.cs | 33 ++ Entity/Character/MagicResistance.cs | 33 +- Entity/Item/Item.cs | 123 +++++++- Entity/Item/SkillGroup.cs | 18 ++ Entity/Skill/Effect.cs | 34 +- Entity/Skill/Skill.cs | 28 +- Entity/Statistics/CharacterStatistics.cs | 46 +-- Interface/Entity/Typical/IItem.cs | 3 +- .../JsonConverter/CharacterConverter.cs | 12 +- .../Common/JsonConverter/EffectConverter.cs | 37 +++ .../JsonConverter/EquipSlotConverter.cs | 90 ++++++ Library/Common/JsonConverter/ItemConverter.cs | 42 +++ .../JsonConverter/MagicResistanceConverter.cs | 157 +++------- .../Common/JsonConverter/SkillConverter.cs | 42 +++ Library/Constant/TypeEnum.cs | 76 ++++- Service/JsonManager.cs | 2 +- 24 files changed, 906 insertions(+), 306 deletions(-) create mode 100644 Api/Factory/EffectFactory.cs create mode 100644 Api/Factory/SkillFactory.cs create mode 100644 Entity/Character/EquipSlot.cs create mode 100644 Entity/Item/SkillGroup.cs create mode 100644 Library/Common/JsonConverter/EffectConverter.cs create mode 100644 Library/Common/JsonConverter/EquipSlotConverter.cs create mode 100644 Library/Common/JsonConverter/ItemConverter.cs create mode 100644 Library/Common/JsonConverter/SkillConverter.cs diff --git a/Api/Factory/EffectFactory.cs b/Api/Factory/EffectFactory.cs new file mode 100644 index 0000000..ef16e7f --- /dev/null +++ b/Api/Factory/EffectFactory.cs @@ -0,0 +1,15 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Interface.Base; + +namespace Milimoe.FunGame.Core.Api.Factory +{ + internal class EffectFactory : IFactory + { + public Type EntityType => typeof(Effect); + + public Effect Create() + { + return new(); + } + } +} diff --git a/Api/Factory/ItemFactory.cs b/Api/Factory/ItemFactory.cs index f686d81..00b8329 100644 --- a/Api/Factory/ItemFactory.cs +++ b/Api/Factory/ItemFactory.cs @@ -1,29 +1,15 @@ using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Interface.Base; -using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Api.Factory { internal class ItemFactory : IFactory { - public Type EntityType => _EntityType; - - private Type _EntityType = typeof(Item); - - public Item Create(ItemType type = ItemType.Passive) - { - _EntityType = typeof(Item); - return type switch - { - ItemType.Passive => new(false), - ItemType.Active => new(true), - _ => new(false) - }; - } + public Type EntityType => typeof(Item); public Item Create() { - return Create(ItemType.Passive); + return new(); } } } diff --git a/Api/Factory/SkillFactory.cs b/Api/Factory/SkillFactory.cs new file mode 100644 index 0000000..336d87f --- /dev/null +++ b/Api/Factory/SkillFactory.cs @@ -0,0 +1,15 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Interface.Base; + +namespace Milimoe.FunGame.Core.Api.Factory +{ + internal class SkillFactory : IFactory + { + public Type EntityType => typeof(Skill); + + public Skill Create() + { + return new(); + } + } +} diff --git a/Api/Utility/ActionQueue.cs b/Api/Utility/ActionQueue.cs index ab868ac..e00746a 100644 --- a/Api/Utility/ActionQueue.cs +++ b/Api/Utility/ActionQueue.cs @@ -1,4 +1,5 @@ using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Api.Utility @@ -13,6 +14,27 @@ namespace Milimoe.FunGame.Core.Api.Utility /// public Action WriteLine { get; } + /// + /// 当前已死亡的角色顺序(第一个是最早死的) + /// + public List Eliminated => _eliminated; + + /// + /// 角色数据 + /// + public Dictionary CharacterStatistics => _stats; + + /// + /// 游戏运行的时间 + /// + public double TotalTime { get; set; } = 0; + + /// + /// 游戏运行的回合 + /// 对于某角色而言,在其行动的回合叫 Turn,而所有角色行动的回合,都称之为 Round。 + /// + public int TotalRound { get; set; } = 0; + /// /// 当前的行动顺序 /// @@ -52,12 +74,17 @@ namespace Milimoe.FunGame.Core.Api.Utility /// 角色被插队次数 /// protected readonly Dictionary _cutCount = []; - + /// /// 助攻伤害 /// protected readonly Dictionary _assistDamage = []; + /// + /// 角色数据 + /// + protected readonly Dictionary _stats = []; + /// /// 游戏是否结束 /// @@ -91,6 +118,7 @@ namespace Milimoe.FunGame.Core.Api.Utility Character character = group.First(); AddCharacter(character, Calculation.Round2Digits(_queue.Count * 0.1), false); _assistDamage.Add(character, new AssistDetail(character, characters.Where(c => c != character))); + _stats.Add(character, new()); // 初始化技能 foreach (Skill skill in character.Skills) { @@ -144,6 +172,7 @@ namespace Milimoe.FunGame.Core.Api.Utility { AddCharacter(selectedCharacter, Calculation.Round2Digits(_queue.Count * 0.1), false); _assistDamage.Add(selectedCharacter, new AssistDetail(selectedCharacter, characters.Where(c => c != selectedCharacter))); + _stats.Add(selectedCharacter, new()); // 初始化技能 foreach (Skill skill in selectedCharacter.Skills) { @@ -284,6 +313,8 @@ namespace Milimoe.FunGame.Core.Api.Utility /// 是否结束游戏 public bool ProcessTurn(Character character) { + TotalRound++; + if (!BeforeTurn(character)) { return _isGameEnd; @@ -307,107 +338,124 @@ namespace Milimoe.FunGame.Core.Api.Utility // 技能列表 List skills = [.. character.Skills.Where(s => s.Level > 0 && s.SkillType != SkillType.Passive && s.Enable && !s.IsInEffect && s.CurrentCD == 0 && (((s.SkillType == SkillType.SuperSkill || s.SkillType == SkillType.Skill) && s.EPCost <= character.EP) || (s.SkillType == SkillType.Magic && s.MPCost <= character.MP)))]; + + // 物品列表 + List items = [.. character.Items.Where(i => i.IsActive && i.Skills.Active != null && i.Enable && + i.Skills.Active.SkillType == SkillType.Item && i.Skills.Active.Enable && !i.Skills.Active.IsInEffect && i.Skills.Active.CurrentCD == 0 && i.Skills.Active.MPCost <= character.MP && i.Skills.Active.EPCost <= character.EP)]; // 作出了什么行动 CharacterActionType type = CharacterActionType.None; - if (character.CharacterState == CharacterState.Actionable) + // 是否能使用物品和释放技能 + bool canUseItem = items.Count > 0; + bool canCastSkill = skills.Count > 0; + + // 使用物品和释放技能、使用普通攻击的概率 + double pUseItem = 0.33; + double pCastSkill = 0.33; + double pNormalAttack = 0.34; + + // 不允许在吟唱和预释放状态下,修改角色的行动 + if (character.CharacterState != CharacterState.Casting && character.CharacterState != CharacterState.PreCastSuperSkill) { - if (character.CharacterState == CharacterState.ActionRestricted) + CharacterActionType actionTypeTemp = CharacterActionType.None; + foreach (Effect e in character.Effects.Where(e => e.Level > 0).ToList()) { - // 行动受限,只能使用特殊物品 - if (character.Items.Count > 0) - { - type = CharacterActionType.UseItem; - } + actionTypeTemp = e.AlterActionTypeBeforeAction(character, character.CharacterState, ref canUseItem, ref canCastSkill, ref pUseItem, ref pCastSkill, ref pNormalAttack); } - else if (character.CharacterState == CharacterState.BattleRestricted) + if (actionTypeTemp != CharacterActionType.None && actionTypeTemp != CharacterActionType.CastSkill && actionTypeTemp != CharacterActionType.CastSuperSkill) { - // 战斗不能,只能使用物品 - if (character.Items.Count > 0) - { - type = CharacterActionType.UseItem; - } + type = actionTypeTemp; } - else if (character.CharacterState == CharacterState.SkillRestricted) + } + + if (type == CharacterActionType.None) + { + if (character.CharacterState != CharacterState.NotActionable && character.CharacterState != CharacterState.Casting && character.CharacterState != CharacterState.PreCastSuperSkill) { - // 技能受限,无法使用技能,可以使用物品 - if (character.Items.Count > 0) + if (character.CharacterState == CharacterState.Actionable) { - if (new Random().NextDouble() > 0.5) + // 可以任意行动 + if (canUseItem && canCastSkill) { - type = CharacterActionType.UseItem; + // 不做任何处理 + } + else if (canUseItem && !canCastSkill) + { + pCastSkill = 0; + } + else if (!canUseItem && canCastSkill) + { + pUseItem = 0; } else { - type = CharacterActionType.NormalAttack; + pUseItem = 0; + pCastSkill = 0; } } - else + else if (character.CharacterState == CharacterState.ActionRestricted) { - type = CharacterActionType.NormalAttack; + // 行动受限,只能使用特殊物品 + if (canUseItem) + { + pCastSkill = 0; + pNormalAttack = 0; + } + else + { + pUseItem = 0; + pCastSkill = 0; + pNormalAttack = 0; + } } + else if (character.CharacterState == CharacterState.BattleRestricted) + { + // 战斗不能,只能使用物品 + if (canUseItem) + { + pCastSkill = 0; + pNormalAttack = 0; + } + else + { + pUseItem = 0; + pCastSkill = 0; + pNormalAttack = 0; + } + } + else if (character.CharacterState == CharacterState.SkillRestricted) + { + // 技能受限,无法使用技能,可以使用物品 + if (canUseItem) + { + pCastSkill = 0; + } + else + { + pUseItem = 0; + pCastSkill = 0; + } + } + type = GetActionType(pUseItem, pCastSkill, pNormalAttack); + _stats[character].ActionTurn += 1; + } + else if (character.CharacterState == CharacterState.Casting) + { + // 如果角色上一次吟唱了魔法,这次的行动则是结算这个魔法 + type = CharacterActionType.CastSkill; + } + else if (character.CharacterState == CharacterState.PreCastSuperSkill) + { + // 角色使用回合外爆发技插队 + type = CharacterActionType.CastSuperSkill; } else { - // 可以任意行动 - bool canUseItem = character.Items.Count > 0; - bool canCastSkill = skills.Count > 0; - if (canUseItem && canCastSkill) - { - double dowhat = new Random().NextDouble(); - if (dowhat < 0.33) - { - type = CharacterActionType.UseItem; - } - else if (dowhat < 0.66) - { - type = CharacterActionType.PreCastSkill; - } - else - { - type = CharacterActionType.NormalAttack; - } - } - else if (canUseItem && !canCastSkill) - { - if (new Random().NextDouble() > 0.5) - { - type = CharacterActionType.UseItem; - } - else - { - type = CharacterActionType.NormalAttack; - } - } - else if (!canUseItem && canCastSkill) - { - if (new Random().NextDouble() > 0.5) - { - type = CharacterActionType.PreCastSkill; - } - else - { - type = CharacterActionType.NormalAttack; - } - } - else type = CharacterActionType.NormalAttack; + WriteLine("[ " + character + $" ] 完全行动不能!"); + type = CharacterActionType.None; } } - else if (character.CharacterState == CharacterState.Casting) - { - // 如果角色上一次吟唱了魔法,这次的行动则是结算这个魔法 - type = CharacterActionType.CastSkill; - } - else if (character.CharacterState == CharacterState.PreCastSuperSkill) - { - // 角色使用回合外爆发技插队 - type = CharacterActionType.CastSuperSkill; - } - else - { - WriteLine("[ " + character + $" ] 完全行动不能!"); - } List enemysTemp = new(enemys); List teammatesTemp = new(teammates); @@ -463,7 +511,7 @@ namespace Milimoe.FunGame.Core.Api.Utility skill.CurrentCD = Calculation.Round2Digits(Math.Max(1, skill.CD * (1 - character.CDR))); skill.Enable = false; - WriteLine("[ " + character + $" ] 消耗了 {cost:f2} 点能量,释放了{(skill.IsSuperSkill ? "爆发技" : "战技")} {skill.Name}!"); + WriteLine("[ " + character + $" ] 消耗了 {cost:0.##} 点能量,释放了{(skill.IsSuperSkill ? "爆发技" : "战技")} {skill.Name}!"); skill.OnSkillCasted(this, character, enemys, teammates); foreach (Effect effect in character.Effects.Where(e => e.Level > 0).ToList()) @@ -488,7 +536,7 @@ namespace Milimoe.FunGame.Core.Api.Utility skill.CurrentCD = Calculation.Round2Digits(Math.Max(1, skill.CD * (1 - character.CDR))); skill.Enable = false; - WriteLine("[ " + character + $" ] 消耗了 {cost:f2} 点魔法值,释放了技能 {skill.Name}!"); + WriteLine("[ " + character + $" ] 消耗了 {cost:0.##} 点魔法值,释放了技能 {skill.Name}!"); skill.OnSkillCasted(this, character, enemys, teammates); } else @@ -518,7 +566,7 @@ namespace Milimoe.FunGame.Core.Api.Utility skill.CurrentCD = Calculation.Round2Digits(Math.Max(1, skill.CD * (1 - character.CDR))); skill.Enable = false; - WriteLine("[ " + character + $" ] 消耗了 {cost:f2} 点能量值,释放了爆发技 {skill.Name}!"); + WriteLine("[ " + character + $" ] 消耗了 {cost:0.##} 点能量值,释放了爆发技 {skill.Name}!"); skill.OnSkillCasted(this, character, enemys, teammates); } else @@ -613,14 +661,22 @@ namespace Milimoe.FunGame.Core.Api.Utility // 获取第一个角色的硬直时间 double timeToReduce = _hardnessTimes[_queue[0]]; + TotalTime = Calculation.Round2Digits(TotalTime + timeToReduce); WriteLine("时间流逝:" + timeToReduce); - // 减少所有角色的硬直时间 foreach (Character character in _queue) { + // 减少所有角色的硬直时间 _hardnessTimes[character] = Calculation.Round2Digits(_hardnessTimes[character] - timeToReduce); + // 统计 + _stats[character].LiveRound += 1; + _stats[character].LiveTime = Calculation.Round2Digits(_stats[character].LiveTime + timeToReduce); + _stats[character].DamagePerRound = Calculation.Round2Digits(_stats[character].TotalDamage / TotalRound); + _stats[character].DamagePerTurn = Calculation.Round2Digits(_stats[character].TotalDamage / _stats[character].LiveRound); + _stats[character].DamagePerSecond = Calculation.Round2Digits(_stats[character].TotalDamage / _stats[character].LiveTime); + // 回血回蓝 double recoveryHP = Calculation.Round2Digits(character.HR * timeToReduce); double recoveryMP = Calculation.Round2Digits(character.MR * timeToReduce); @@ -727,6 +783,9 @@ namespace Milimoe.FunGame.Core.Api.Utility else WriteLine("[ " + enemy + $" ] 受到了 {damage} 点物理伤害!"); enemy.HP = Calculation.Round2Digits(enemy.HP - damage); + // 统计伤害 + CalculateCharacterDamageStatistics(actor, damage, isMagicDamage); + // 计算助攻 _assistDamage[actor][enemy] += damage; @@ -789,7 +848,7 @@ namespace Milimoe.FunGame.Core.Api.Utility { bool isMagic = false; MagicType magicType = MagicType.None; - foreach(Effect effect in actor.Effects.Union(enemy.Effects).Where(e => e.Level > 0).ToList()) + foreach (Effect effect in actor.Effects.Union(enemy.Effects).Where(e => e.Level > 0).ToList()) { effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref isMagic, ref magicType); } @@ -904,7 +963,7 @@ namespace Milimoe.FunGame.Core.Api.Utility } } - MagicResistance magicResistance = magicType switch + double MDF = magicType switch { MagicType.Starmark => enemy.MDF.Starmark, MagicType.PurityNatural => enemy.MDF.PurityNatural, @@ -918,7 +977,7 @@ namespace Milimoe.FunGame.Core.Api.Utility }; // 魔法穿透后的魔法抗性 - double MDF = Calculation.Round2Digits((1 - actor.MagicalPenetration) * magicResistance.Value); + MDF = Calculation.Round2Digits((1 - actor.MagicalPenetration) * MDF); // 最终的魔法伤害 finalDamage = Calculation.Round2Digits(expectedDamage * (1 - MDF)); @@ -1008,7 +1067,7 @@ namespace Milimoe.FunGame.Core.Api.Utility { WriteLine("[ " + killer + " ] 已经" + continuousKilling + "!拜托谁去杀了他吧!!!"); } - + if (!_earnedMoney.TryAdd(killer, money)) _earnedMoney[killer] += money; _eliminated.Add(death); @@ -1146,5 +1205,69 @@ namespace Milimoe.FunGame.Core.Api.Utility } } } + + /// + /// 通过概率计算角色要干嘛 + /// + /// + /// + /// + /// + public static CharacterActionType GetActionType(double pUseItem, double pCastSkill, double pNormalAttack) + { + if (pUseItem == 0 && pCastSkill == 0 && pNormalAttack == 0) + { + return CharacterActionType.None; + } + + double total = pUseItem + pCastSkill + pNormalAttack; + + // 浮点数比较时处理误差 + if (Math.Abs(total - 1) > 1e-6) + { + pUseItem /= total; + pCastSkill /= total; + pNormalAttack /= total; + } + + double rand = new Random().NextDouble(); + + // 按概率进行检查 + if (rand < pUseItem) + { + return CharacterActionType.UseItem; + } + + if (rand < pUseItem + pCastSkill) + { + return CharacterActionType.PreCastSkill; + } + + if (rand < pUseItem + pCastSkill + pNormalAttack) + { + return CharacterActionType.NormalAttack; + } + + return CharacterActionType.None; + } + + /// + /// 计算角色的数据 + /// + public void CalculateCharacterDamageStatistics(Character character, double damage, bool isMagic) + { + if (_stats.TryGetValue(character, out CharacterStatistics? stats) && stats != null) + { + if (isMagic) + { + stats.TotalMagicDamage = Calculation.Round2Digits(stats.TotalMagicDamage + damage); + } + else + { + stats.TotalPhysicalDamage = Calculation.Round2Digits(stats.TotalPhysicalDamage + damage); + } + stats.TotalDamage = Calculation.Round2Digits(stats.TotalDamage + damage); + } + } } } diff --git a/Api/Utility/Factory.cs b/Api/Utility/Factory.cs index 39a216f..e5894ba 100644 --- a/Api/Utility/Factory.cs +++ b/Api/Utility/Factory.cs @@ -10,6 +10,8 @@ namespace Milimoe.FunGame.Core.Api.Utility { private readonly static CharacterFactory CharacterFactory = new(); private readonly static InventoryFactory InventoryFactory = new(); + private readonly static SkillFactory SkillFactory = new(); + private readonly static EffectFactory EffectFactory = new(); private readonly static ItemFactory ItemFactory = new(); private readonly static RoomFactory RoomFactory = new(); private readonly static UserFactory UserFactory = new(); @@ -32,14 +34,31 @@ namespace Milimoe.FunGame.Core.Api.Utility return InventoryFactory.Create(); } + /// + /// 获取技能实例 + /// + /// + public static Skill GetSkill() + { + return SkillFactory.Create(); + } + + /// + /// 获取技能特效实例 + /// + /// + public static Effect GetEffect() + { + return EffectFactory.Create(); + } + /// /// 获取物品实例 /// - /// Item类型 主动 或 被动 /// - public static Item GetItem(ItemType type = ItemType.Passive) + public static Item GetItem() { - return ItemFactory.Create(type); + return ItemFactory.Create(); } /// diff --git a/Api/Utility/General.cs b/Api/Utility/General.cs index 3d440a4..058971a 100644 --- a/Api/Utility/General.cs +++ b/Api/Utility/General.cs @@ -245,6 +245,42 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// public static T? JsonDeserializeFromHashtable(Hashtable hashtable, string key, JsonSerializerOptions options) => Service.JsonManager.GetObject(hashtable, key, options); + + // 创建一个静态 HttpClient 实例,供整个应用程序生命周期使用 + private static readonly HttpClient client = new(); + + /// + /// 发送 GET 请求 + /// + /// + /// + public static async Task HttpGet(string url) + { + HttpResponseMessage response = await client.GetAsync(url); + response.EnsureSuccessStatusCode(); + + string content = await response.Content.ReadAsStringAsync(); + T? result = JsonDeserialize(content); + return result; + } + + /// + /// 发送 POST 请求 + /// + /// + /// + /// + /// + public static async Task HttpPost(string url, string json) + { + HttpContent content = new StringContent(json, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(url, content); + response.EnsureSuccessStatusCode(); + + string read = await response.Content.ReadAsStringAsync(); + T? result = JsonDeserialize(read); + return result; + } } #endregion diff --git a/Entity/Character/Character.cs b/Entity/Character/Character.cs index c164797..d9e9cd9 100644 --- a/Entity/Character/Character.cs +++ b/Entity/Character/Character.cs @@ -37,6 +37,11 @@ namespace Milimoe.FunGame.Core.Entity /// public CharacterProfile Profile { get; set; } + /// + /// 角色的详细资料 + /// + public EquipSlot EquipSlot { get; set; } + /// /// 魔法属性 /// @@ -140,7 +145,7 @@ namespace Milimoe.FunGame.Core.Entity /// 角色目前被特效施加的状态 [ 用于设置角色是否被控制的状态 ] /// public Dictionary> CharacterEffectStates { get; } = []; - + /// /// 角色目前被特效施加的控制效果 [ 用于特效判断是否需要在移除特效时更改角色状态 ] /// @@ -366,7 +371,7 @@ namespace Milimoe.FunGame.Core.Entity /// /// 魔法抗性(%) [ 与技能和物品相关 ] /// - public MDF MDF { get; set; } + public MagicResistance MDF { get; set; } /// /// 物理穿透(%) [ 与技能和物品相关 ] @@ -723,12 +728,12 @@ namespace Milimoe.FunGame.Core.Entity /// 生命值 /// private double _HP = 0; - + /// /// 魔法值 /// private double _MP = 0; - + /// /// 能量值 /// @@ -748,6 +753,7 @@ namespace Milimoe.FunGame.Core.Entity { User = General.UnknownUserInstance; Profile = new(Name, FirstName, NickName); + EquipSlot = new(); MDF = new(); NormalAttack = new(this); } @@ -767,7 +773,7 @@ namespace Milimoe.FunGame.Core.Entity MP = MaxMP; if (EP != -1) this.EP = EP; } - + /// /// 按时间回复状态 /// @@ -810,13 +816,13 @@ namespace Milimoe.FunGame.Core.Entity } /// - /// 比较一个角色(只比较 ) + /// 比较一个角色(只比较 ) /// /// /// public override bool Equals(IBaseEntity? other) { - return other is Character c && c.Name == Name; + return other is Character c && c.ToString() == ToString(); } /// @@ -891,8 +897,8 @@ namespace Milimoe.FunGame.Core.Entity builder.AppendLine($"能量值:{EP} / 200"); builder.AppendLine($"攻击力:{ATK}" + (ExATK + ExATK2 > 0 ? $" [{BaseATK} + {ExATK + ExATK2}]" : "")); builder.AppendLine($"物理护甲:{DEF}" + (ExDEF + ExDEF2 > 0 ? $" [{BaseDEF} + {ExDEF + ExDEF2}]" : "") + $" ({PDR * 100:f2}%)"); - double mdf = Calculation.Round4Digits((MDF.None.Value + MDF.Starmark.Value + MDF.PurityNatural.Value + MDF.PurityContemporary.Value + - MDF.Bright.Value + MDF.Shadow.Value + MDF.Element.Value + MDF.Fleabane.Value + MDF.Particle.Value) / 9); + double mdf = Calculation.Round4Digits((MDF.None + MDF.Starmark + MDF.PurityNatural + MDF.PurityContemporary + + MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9); builder.AppendLine($"魔法抗性:{mdf * 100:f2}%(平均)"); double exSPD = Calculation.Round2Digits(AGI * 0.65 + ExSPD); builder.AppendLine($"行动速度:{SPD}" + (exSPD > 0 ? $" [{InitialSPD} + {exSPD}]" : "") + $" ({ActionCoefficient * 100:f2}%)"); @@ -945,7 +951,7 @@ namespace Milimoe.FunGame.Core.Entity builder.Append(item.ToString()); } } - + if (Effects.Count > 0) { builder.AppendLine("== 状态栏 =="); diff --git a/Entity/Character/CharacterProfile.cs b/Entity/Character/CharacterProfile.cs index 2373b9f..30fde0b 100644 --- a/Entity/Character/CharacterProfile.cs +++ b/Entity/Character/CharacterProfile.cs @@ -2,6 +2,12 @@ namespace Milimoe.FunGame.Core.Entity { + /// + /// 角色的一些个人信息 + /// + /// + /// + /// public class CharacterProfile(string name, string firstname, string nickname) { /// diff --git a/Entity/Character/EquipSlot.cs b/Entity/Character/EquipSlot.cs new file mode 100644 index 0000000..1a6894e --- /dev/null +++ b/Entity/Character/EquipSlot.cs @@ -0,0 +1,33 @@ +namespace Milimoe.FunGame.Core.Entity +{ + /// + /// 角色的装备槽位 + /// + public class EquipSlot() + { + /// + /// 魔法卡包 + /// + public Item? MagicCardPack { get; set; } = null; + /// + /// 武器 + /// + public Item? Weapon { get; set; } = null; + /// + /// 防具 + /// + public Item? Armor { get; set; } = null; + /// + /// 鞋子 + /// + public Item? Shoes { get; set; } = null; + /// + /// 饰品1 + /// + public Item? Accessory1 { get; set; } = null; + /// + /// 饰品2 + /// + public Item? Accessory2 { get; set; } = null; + } +} diff --git a/Entity/Character/MagicResistance.cs b/Entity/Character/MagicResistance.cs index f36c64b..f05edb3 100644 --- a/Entity/Character/MagicResistance.cs +++ b/Entity/Character/MagicResistance.cs @@ -1,23 +1,18 @@ -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.Core.Entity +namespace Milimoe.FunGame.Core.Entity { - public class MDF() + /// + /// 角色的魔法抗性,对不同的魔法类型有不同抗性 + /// + public class MagicResistance() { - public MagicResistance None { get; } = new(MagicType.None); - public MagicResistance Starmark { get; } = new(MagicType.Starmark); - public MagicResistance PurityNatural { get; } = new(MagicType.PurityNatural); - public MagicResistance PurityContemporary { get; } = new(MagicType.PurityContemporary); - public MagicResistance Bright { get; } = new(MagicType.Bright); - public MagicResistance Shadow { get; } = new(MagicType.Shadow); - public MagicResistance Element { get; } = new(MagicType.Element); - public MagicResistance Fleabane { get; } = new(MagicType.Fleabane); - public MagicResistance Particle { get; } = new(MagicType.Particle); - } - - public class MagicResistance(MagicType type = MagicType.None, double value = 0) - { - public MagicType MagicType { get; } = type; - public double Value { get; set; } = value; + public double None { get; set; } = 0; + public double Starmark { get; set; } = 0; + public double PurityNatural { get; set; } = 0; + public double PurityContemporary { get; set; } = 0; + public double Bright { get; set; } = 0; + public double Shadow { get; set; } = 0; + public double Element { get; set; } = 0; + public double Fleabane { get; set; } = 0; + public double Particle { get; set; } = 0; } } diff --git a/Entity/Item/Item.cs b/Entity/Item/Item.cs index 57f6c96..8a88cbe 100644 --- a/Entity/Item/Item.cs +++ b/Entity/Item/Item.cs @@ -1,25 +1,126 @@ -using Milimoe.FunGame.Core.Interface.Entity; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Interface.Entity; +using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Entity { + /// + /// 和 一样,需要继承构造 + /// public class Item : BaseEntity, IItem { - public string Describe { get; set; } = ""; - public double Price { get; set; } - public char Key { get; set; } - public bool IsActive { get; set; } - public bool Enable { get; set; } - public Character? Character { get; set; } = null; - public Skill? Skill { get; set; } = null; + /// + /// 物品的描述 + /// + public string Description { get; } = ""; - internal Item(bool active = false) + /// + /// 物品类型 + /// + public virtual ItemType ItemType { get; set; } = ItemType.Others; + + /// + /// 物品槽位 + /// + public virtual EquipSlotType EquipSlotType { get; set; } = EquipSlotType.None; + + /// + /// 物品的价格 + /// + public double Price { get; set; } = 0; + + /// + /// 快捷键 + /// + public char Key { get; set; } = '/'; + + /// + /// 是否是主动物品 + /// + public bool IsActive => Skills.Active != null; + + /// + /// 是否可用(涉及冷却和禁用等) + /// + public bool Enable { get; set; } = true; + + /// + /// 物品所属的角色 + /// + public Character? Character { get; set; } = null; + + /// + /// 物品拥有的技能 + /// + public SkillGroup Skills { get; set; } = new(); + + /// + /// 当获得物品时 + /// + public void OnItemGained() { - IsActive = active; + foreach (Skill skill in Skills.Passive) + { + if (!skill.IsActive && skill.Level > 0) + { + foreach (Effect e in skill.AddInactiveEffectToCharacter()) + { + e.ActionQueue = skill.ActionQueue; + if (Character != null && !Character.Effects.Contains(e)) + { + Character.Effects.Add(e); + e.OnEffectGained(Character); + } + } + } + } } + /// + /// 局内使用物品触发 + /// + public void UseItem(ActionQueue queue, List enemys, List teammates) + { + if (Skills.Active != null && Character != null) + { + Skills.Active.OnSkillCasted(queue, Character, enemys, teammates); + } + OnItemUsed(); + } + + /// + /// 局外(库存)使用物品触发 + /// + public void UseItem(/*Inventory inventory*/) + { + + OnItemUsed(); + } + + /// + /// 当物品被使用时 + /// + public virtual void OnItemUsed() + { + + } + + protected Item(ItemType type, EquipSlotType slot = EquipSlotType.None) + { + ItemType = type; + EquipSlotType = slot; + } + + internal Item() { } + + /// + /// 判断两个物品是否相同 检查Id.Name + /// + /// + /// public override bool Equals(IBaseEntity? other) { - return other is Item c && c.Name == Name; + return other is Item c && c.Id + "." + c.Name == Id + "." + Name; } } } diff --git a/Entity/Item/SkillGroup.cs b/Entity/Item/SkillGroup.cs new file mode 100644 index 0000000..af95058 --- /dev/null +++ b/Entity/Item/SkillGroup.cs @@ -0,0 +1,18 @@ +namespace Milimoe.FunGame.Core.Entity +{ + /// + /// 物品只有一个主动技能,但是可以有很多个被动技能 + /// + public class SkillGroup + { + /// + /// 唯一的主动技能 + /// + public Skill? Active { get; set; } = null; + + /// + /// 被动技能组 + /// + public HashSet Passive { get; set; } = []; + } +} diff --git a/Entity/Skill/Effect.cs b/Entity/Skill/Effect.cs index 7519396..8b9d1e6 100644 --- a/Entity/Skill/Effect.cs +++ b/Entity/Skill/Effect.cs @@ -8,12 +8,12 @@ namespace Milimoe.FunGame.Core.Entity /// /// 特殊效果类,需要继承 /// - public abstract class Effect(Skill skill) : BaseEntity + public class Effect : BaseEntity { /// /// 所属的技能 /// - public Skill Skill { get; } = skill; + public Skill Skill { get; } /// /// 特殊效果类型 @@ -101,6 +101,16 @@ namespace Milimoe.FunGame.Core.Entity } } + protected Effect(Skill skill) + { + Skill = skill; + } + + internal Effect() + { + Skill = Factory.GetSkill(); + } + /// /// 获得此特效时 /// @@ -131,7 +141,7 @@ namespace Milimoe.FunGame.Core.Entity { } - + /// /// 在伤害计算前修改预期伤害 /// @@ -359,6 +369,22 @@ namespace Milimoe.FunGame.Core.Entity return false; } + /// + /// 行动开始前,指定角色的行动,而不是使用顺序表自带的逻辑;或者修改对应的操作触发概率 + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual CharacterActionType AlterActionTypeBeforeAction(Character character, CharacterState state, ref bool canUseItem, ref bool canCastSkill, ref double pUseItem, ref double pCastSkill, ref double pNormalAttack) + { + return CharacterActionType.None; + } + /// /// 对敌人造成技能伤害 [ 强烈建议使用此方法造成伤害而不是自行调用 ] /// @@ -415,7 +441,7 @@ namespace Milimoe.FunGame.Core.Entity /// public override bool Equals(IBaseEntity? other) { - return other is Effect c && c.Name == Name; + return other is Effect c && c.Id + "." + Name == Id + "." + Name; } } } diff --git a/Entity/Skill/Skill.cs b/Entity/Skill/Skill.cs index 6d46887..21a8426 100644 --- a/Entity/Skill/Skill.cs +++ b/Entity/Skill/Skill.cs @@ -20,11 +20,6 @@ namespace Milimoe.FunGame.Core.Entity /// public virtual string Description { get; set; } = ""; - /// - /// 快捷键 - /// - public char Key { get; set; } = '/'; - /// /// 技能等级,等于 0 时可以称之为尚未学习 /// @@ -43,11 +38,11 @@ namespace Milimoe.FunGame.Core.Entity } /// - /// 技能 [ 此项为最高优先级 ] + /// 技能类型 [ 此项为最高优先级 ] /// [InitRequired] public SkillType SkillType { get; set; } - + /// /// 是否是主动技能 [ 此项为高优先级 ] /// @@ -138,12 +133,22 @@ namespace Milimoe.FunGame.Core.Entity /// public ActionQueue? ActionQueue { get; set; } = null; + /// + /// 继承此类实现时,调用基类的构造函数 + /// + /// + /// protected Skill(SkillType type, Character? character = null) { SkillType = type; Character = character; } + /// + /// 用于构造 JSON + /// + internal Skill() { } + /// /// 触发技能升级 /// @@ -185,7 +190,7 @@ namespace Milimoe.FunGame.Core.Entity e.OnSkillCasting(caster); } } - + /// /// 触发技能效果 /// @@ -257,9 +262,14 @@ namespace Milimoe.FunGame.Core.Entity return builder.ToString(); } + /// + /// 判断两个技能是否相同 检查Id.Name + /// + /// + /// public override bool Equals(IBaseEntity? other) { - return other is Skill c && c.Name == Name; + return other is Skill c && c.Id + "." + c.Name == Id + "." + Name; } /// diff --git a/Entity/Statistics/CharacterStatistics.cs b/Entity/Statistics/CharacterStatistics.cs index 0ec8bbc..88e9e87 100644 --- a/Entity/Statistics/CharacterStatistics.cs +++ b/Entity/Statistics/CharacterStatistics.cs @@ -1,24 +1,32 @@ -using System.Collections; - -namespace Milimoe.FunGame.Core.Entity +namespace Milimoe.FunGame.Core.Entity { public class CharacterStatistics { - public int Id { get; set; } - public Character? Character { get; set; } = null; - public Hashtable? DamageStats { get; set; } = new Hashtable(); - public Hashtable? PhysicalDamageStats { get; set; } = new Hashtable(); - public Hashtable? MagicDamageStats { get; set; } = new Hashtable(); - public Hashtable? RealDamageStats { get; set; } = new Hashtable(); - public Hashtable? AvgDamageStats { get; set; } = new Hashtable(); - public Hashtable? AvgLiveRoundStats { get; set; } = new Hashtable(); - public Hashtable? AvgDamageRoundStats { get; set; } = new Hashtable(); - public Hashtable? KillStats { get; set; } = new Hashtable(); - public Hashtable? DeathStats { get; set; } = new Hashtable(); - public Hashtable? AssistStats { get; set; } = new Hashtable(); - public Hashtable? Plays { get; set; } = new Hashtable(); - public Hashtable? Wins { get; set; } = new Hashtable(); - public Hashtable? Loses { get; set; } = new Hashtable(); - public Hashtable? Winrates { get; set; } = new Hashtable(); + public double TotalDamage { get; set; } = 0; + public double TotalPhysicalDamage { get; set; } = 0; + public double TotalMagicDamage { get; set; } = 0; + public double TotalRealDamage { get; set; } = 0; + public double AvgDamage { get; set; } = 0; + public double AvgPhysicalDamage { get; set; } = 0; + public double AvgMagicDamage { get; set; } = 0; + public double AvgRealDamage { get; set; } = 0; + public int LiveRound { get; set; } = 0; + public int AvgLiveRound { get; set; } = 0; + public int ActionTurn { get; set; } = 0; + public int AvgActionTurn { get; set; } = 0; + public double LiveTime { get; set; } = 0; + public double AvgLiveTime { get; set; } = 0; + public double DamagePerRound { get; set; } = 0; + public double DamagePerTurn { get; set; } = 0; + public double DamagePerSecond { get; set; } = 0; + public double TotalEarnedMoney { get; set; } = 0; + public double AvgEarnedMoney { get; set; } = 0; + public double Kills { get; set; } = 0; + public double Deaths { get; set; } = 0; + public double Assists { get; set; } = 0; + public double Plays { get; set; } = 0; + public double Wins { get; set; } = 0; + public double Loses { get; set; } = 0; + public double Winrates { get; set; } = 0; } } diff --git a/Interface/Entity/Typical/IItem.cs b/Interface/Entity/Typical/IItem.cs index c70e573..7272f75 100644 --- a/Interface/Entity/Typical/IItem.cs +++ b/Interface/Entity/Typical/IItem.cs @@ -2,8 +2,7 @@ { public interface IItem : IActiveEnable, IRelateCharacter { - public string Describe { get; set; } + public string Description { get; } public double Price { get; set; } - public char Key { get; set; } } } diff --git a/Library/Common/JsonConverter/CharacterConverter.cs b/Library/Common/JsonConverter/CharacterConverter.cs index 0cf09be..55f8eba 100644 --- a/Library/Common/JsonConverter/CharacterConverter.cs +++ b/Library/Common/JsonConverter/CharacterConverter.cs @@ -26,6 +26,12 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Character.NickName): result.NickName = reader.GetString() ?? ""; break; + case nameof(Character.Profile): + result.Profile = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(result.Name, result.FirstName, result.NickName); + break; + case nameof(Character.EquipSlot): + result.EquipSlot = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + break; case nameof(Character.MagicType): result.MagicType = (MagicType)reader.GetInt32(); break; @@ -84,7 +90,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter result.ExDEF2 = reader.GetDouble(); break; case nameof(Character.MDF): - result.MDF = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + result.MDF = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); break; case nameof(Character.PhysicalPenetration): result.PhysicalPenetration = reader.GetDouble(); @@ -173,6 +179,10 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter writer.WriteString(nameof(Character.Name), value.Name); writer.WriteString(nameof(Character.FirstName), value.FirstName); writer.WriteString(nameof(Character.NickName), value.NickName); + writer.WritePropertyName(nameof(Character.Profile)); + JsonSerializer.Serialize(writer, value.Profile, options); + writer.WritePropertyName(nameof(Character.EquipSlot)); + JsonSerializer.Serialize(writer, value.EquipSlot, options); writer.WriteNumber(nameof(Character.MagicType), (int)value.MagicType); writer.WriteNumber(nameof(Character.FirstRoleType), (int)value.FirstRoleType); writer.WriteNumber(nameof(Character.SecondRoleType), (int)value.SecondRoleType); diff --git a/Library/Common/JsonConverter/EffectConverter.cs b/Library/Common/JsonConverter/EffectConverter.cs new file mode 100644 index 0000000..9768d15 --- /dev/null +++ b/Library/Common/JsonConverter/EffectConverter.cs @@ -0,0 +1,37 @@ +using System.Text.Json; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Architecture; + +namespace Milimoe.FunGame.Core.Library.Common.JsonConverter +{ + public class EffectConverter : BaseEntityConverter + { + public override Effect NewInstance() + { + return new(); + } + + public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Effect result) + { + switch (propertyName) + { + case nameof(Effect.Id): + result.Id = reader.GetInt64(); + break; + case nameof(Effect.Name): + result.Name = reader.GetString() ?? ""; + break; + } + } + + public override void Write(Utf8JsonWriter writer, Effect value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + writer.WriteNumber(nameof(Effect.Id), (int)value.Id); + writer.WriteString(nameof(Effect.Name), value.Name); + + writer.WriteEndObject(); + } + } +} diff --git a/Library/Common/JsonConverter/EquipSlotConverter.cs b/Library/Common/JsonConverter/EquipSlotConverter.cs new file mode 100644 index 0000000..41ad97e --- /dev/null +++ b/Library/Common/JsonConverter/EquipSlotConverter.cs @@ -0,0 +1,90 @@ +using System.Text.Json; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Architecture; + +namespace Milimoe.FunGame.Core.Library.Common.JsonConverter +{ + public class EquipSlotConverter : BaseEntityConverter + { + public override EquipSlot NewInstance() + { + return new(); + } + + public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref EquipSlot result) + { + Item temp; + switch (propertyName) + { + case nameof(EquipSlot.MagicCardPack): + temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + if (temp.EquipSlotType == Constant.EquipSlotType.MagicCardPack) + { + result.MagicCardPack = temp; + } + break; + case nameof(EquipSlot.Weapon): + temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + if (temp.EquipSlotType == Constant.EquipSlotType.Weapon) + { + result.Weapon = temp; + } + break; + case nameof(EquipSlot.Armor): + temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + if (temp.EquipSlotType == Constant.EquipSlotType.Armor) + { + result.Armor = temp; + } + break; + case nameof(EquipSlot.Shoes): + temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + if (temp.EquipSlotType == Constant.EquipSlotType.Shoes) + { + result.Shoes = temp; + } + break; + case nameof(EquipSlot.Accessory1): + temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + if (temp.EquipSlotType == Constant.EquipSlotType.Accessory1) + { + result.Accessory1 = temp; + } + break; + case nameof(EquipSlot.Accessory2): + temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); + if (temp.EquipSlotType == Constant.EquipSlotType.Accessory2) + { + result.Accessory2 = temp; + } + break; + } + } + + public override void Write(Utf8JsonWriter writer, EquipSlot value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + writer.WritePropertyName(nameof(value.MagicCardPack)); + JsonSerializer.Serialize(writer, value.MagicCardPack, options); + + writer.WritePropertyName(nameof(value.Weapon)); + JsonSerializer.Serialize(writer, value.Weapon, options); + + writer.WritePropertyName(nameof(value.Armor)); + JsonSerializer.Serialize(writer, value.Armor, options); + + writer.WritePropertyName(nameof(value.Shoes)); + JsonSerializer.Serialize(writer, value.Shoes, options); + + writer.WritePropertyName(nameof(value.Accessory1)); + JsonSerializer.Serialize(writer, value.Accessory1, options); + + writer.WritePropertyName(nameof(value.Accessory2)); + JsonSerializer.Serialize(writer, value.Accessory2, options); + + writer.WriteEndObject(); + } + } +} diff --git a/Library/Common/JsonConverter/ItemConverter.cs b/Library/Common/JsonConverter/ItemConverter.cs new file mode 100644 index 0000000..9f395cd --- /dev/null +++ b/Library/Common/JsonConverter/ItemConverter.cs @@ -0,0 +1,42 @@ +using System.Text.Json; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Core.Library.Common.JsonConverter +{ + public class ItemConverter : BaseEntityConverter + { + public override Item NewInstance() + { + return new(); + } + + public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Item result) + { + switch (propertyName) + { + case nameof(Item.Id): + result.Id = reader.GetInt64(); + break; + case nameof(Item.Name): + result.Name = reader.GetString() ?? ""; + break; + case nameof(Item.ItemType): + result.ItemType = (ItemType)reader.GetInt32(); + break; + } + } + + public override void Write(Utf8JsonWriter writer, Item value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + writer.WriteNumber(nameof(Item.Id), (int)value.Id); + writer.WriteString(nameof(Item.Name), value.Name); + writer.WriteNumber(nameof(Item.ItemType), (int)value.ItemType); + + writer.WriteEndObject(); + } + } +} diff --git a/Library/Common/JsonConverter/MagicResistanceConverter.cs b/Library/Common/JsonConverter/MagicResistanceConverter.cs index cdd20c5..689dd3e 100644 --- a/Library/Common/JsonConverter/MagicResistanceConverter.cs +++ b/Library/Common/JsonConverter/MagicResistanceConverter.cs @@ -1,124 +1,9 @@ using System.Text.Json; -using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Library.Common.Architecture; -using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Library.Common.JsonConverter { - public class MDFConverter : BaseEntityConverter - { - public override MDF NewInstance() - { - return new(); - } - - public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref MDF result) - { - MagicResistance temp; - switch (propertyName) - { - case nameof(MDF.None): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.None) - { - result.None.Value = temp.Value; - } - break; - case nameof(MDF.Starmark): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.Starmark) - { - result.Starmark.Value = temp.Value; - } - break; - case nameof(MDF.PurityNatural): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.PurityNatural) - { - result.PurityNatural.Value = temp.Value; - } - break; - case nameof(MDF.PurityContemporary): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.PurityContemporary) - { - result.PurityContemporary.Value = temp.Value; - } - break; - case nameof(MDF.Bright): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.Bright) - { - result.Bright.Value = temp.Value; - } - break; - case nameof(MDF.Shadow): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.Shadow) - { - result.Shadow.Value = temp.Value; - } - break; - case nameof(MDF.Element): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.Element) - { - result.Element.Value = temp.Value; - } - break; - case nameof(MDF.Fleabane): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.Fleabane) - { - result.Fleabane.Value = temp.Value; - } - break; - case nameof(MDF.Particle): - temp = NetworkUtility.JsonDeserialize(ref reader, options) ?? new(); - if (temp.MagicType == MagicType.Particle) - { - result.Particle.Value = temp.Value; - } - break; - } - } - - public override void Write(Utf8JsonWriter writer, MDF value, JsonSerializerOptions options) - { - writer.WriteStartObject(); - - writer.WritePropertyName(nameof(MDF.None)); - JsonSerializer.Serialize(writer, value.None, options); - - writer.WritePropertyName(nameof(MDF.Starmark)); - JsonSerializer.Serialize(writer, value.Starmark, options); - - writer.WritePropertyName(nameof(MDF.PurityNatural)); - JsonSerializer.Serialize(writer, value.PurityNatural, options); - - writer.WritePropertyName(nameof(MDF.PurityContemporary)); - JsonSerializer.Serialize(writer, value.PurityContemporary, options); - - writer.WritePropertyName(nameof(MDF.Bright)); - JsonSerializer.Serialize(writer, value.Bright, options); - - writer.WritePropertyName(nameof(MDF.Shadow)); - JsonSerializer.Serialize(writer, value.Shadow, options); - - writer.WritePropertyName(nameof(MDF.Element)); - JsonSerializer.Serialize(writer, value.Element, options); - - writer.WritePropertyName(nameof(MDF.Fleabane)); - JsonSerializer.Serialize(writer, value.Fleabane, options); - - writer.WritePropertyName(nameof(MDF.Particle)); - JsonSerializer.Serialize(writer, value.Particle, options); - - writer.WriteEndObject(); - } - } - public class MagicResistanceConverter : BaseEntityConverter { public override MagicResistance NewInstance() @@ -130,11 +15,32 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter { switch (propertyName) { - case nameof(MagicResistance.MagicType): - result = new((MagicType)reader.GetInt32(), result.Value); + case nameof(MagicResistance.None): + result.None = reader.GetDouble(); break; - case nameof(MagicResistance.Value): - result.Value = reader.GetDouble(); + case nameof(MagicResistance.Starmark): + result.Starmark = reader.GetDouble(); + break; + case nameof(MagicResistance.PurityNatural): + result.PurityNatural = reader.GetDouble(); + break; + case nameof(MagicResistance.PurityContemporary): + result.PurityContemporary = reader.GetDouble(); + break; + case nameof(MagicResistance.Bright): + result.Bright = reader.GetDouble(); + break; + case nameof(MagicResistance.Shadow): + result.Shadow = reader.GetDouble(); + break; + case nameof(MagicResistance.Element): + result.Element = reader.GetDouble(); + break; + case nameof(MagicResistance.Fleabane): + result.Fleabane = reader.GetDouble(); + break; + case nameof(MagicResistance.Particle): + result.Particle = reader.GetDouble(); break; } } @@ -142,8 +48,17 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter public override void Write(Utf8JsonWriter writer, MagicResistance value, JsonSerializerOptions options) { writer.WriteStartObject(); - writer.WriteNumber(nameof(MagicResistance.MagicType), (int)value.MagicType); - writer.WriteNumber(nameof(MagicResistance.Value), value.Value); + + writer.WriteNumber(nameof(MagicResistance.None), value.None); + writer.WriteNumber(nameof(MagicResistance.Starmark), value.Starmark); + writer.WriteNumber(nameof(MagicResistance.PurityNatural), value.PurityNatural); + writer.WriteNumber(nameof(MagicResistance.PurityContemporary), value.PurityContemporary); + writer.WriteNumber(nameof(MagicResistance.Bright), value.Bright); + writer.WriteNumber(nameof(MagicResistance.Shadow), value.Shadow); + writer.WriteNumber(nameof(MagicResistance.Element), value.Element); + writer.WriteNumber(nameof(MagicResistance.Fleabane), value.Fleabane); + writer.WriteNumber(nameof(MagicResistance.Particle), value.Particle); + writer.WriteEndObject(); } } diff --git a/Library/Common/JsonConverter/SkillConverter.cs b/Library/Common/JsonConverter/SkillConverter.cs new file mode 100644 index 0000000..312041a --- /dev/null +++ b/Library/Common/JsonConverter/SkillConverter.cs @@ -0,0 +1,42 @@ +using System.Text.Json; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Core.Library.Common.JsonConverter +{ + public class SkillConverter : BaseEntityConverter + { + public override Skill NewInstance() + { + return new(); + } + + public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Skill result) + { + switch (propertyName) + { + case nameof(Skill.Id): + result.Id = reader.GetInt64(); + break; + case nameof(Skill.Name): + result.Name = reader.GetString() ?? ""; + break; + case nameof(Skill.SkillType): + result.SkillType = (SkillType)reader.GetInt32(); + break; + } + } + + public override void Write(Utf8JsonWriter writer, Skill value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + writer.WriteNumber(nameof(Skill.Id), (int)value.Id); + writer.WriteString(nameof(Skill.Name), value.Name); + writer.WriteNumber(nameof(Skill.SkillType), (int)value.SkillType); + + writer.WriteEndObject(); + } + } +} diff --git a/Library/Constant/TypeEnum.cs b/Library/Constant/TypeEnum.cs index 1784642..ae35bce 100644 --- a/Library/Constant/TypeEnum.cs +++ b/Library/Constant/TypeEnum.cs @@ -200,7 +200,12 @@ namespace Milimoe.FunGame.Core.Library.Constant /// /// 被动,编号 4xxx /// - Passive + Passive, + + /// + /// 物品的主动技能,编号 5xxx + /// + Item } /// @@ -217,7 +222,7 @@ namespace Milimoe.FunGame.Core.Library.Constant /// 标记,目标受到某些技能的标记 /// Mark, - + /// /// 眩晕,目标无法行动 /// @@ -406,8 +411,71 @@ namespace Milimoe.FunGame.Core.Library.Constant public enum ItemType { - Active, - Passive + /// + /// 魔法卡包 编号 10xxx + /// + MagicCardPack, + + /// + /// 武器 编号 11xxx + /// + Weapon, + + /// + /// 防具 编号 12xxx + /// + Armor, + + /// + /// 鞋子 编号 13xxx + /// + Shoes, + + /// + /// 饰品 编号 14xxx + /// + Accessory, + + /// + /// 消耗品 编号 15xxx + /// + Consumable, + + /// + /// 收藏品 编号 16xxx + /// + Collectible, + + /// + /// 特殊物品 编号 17xxx + /// + SpecialItem, + + /// + /// 任务物品 编号 18xxx + /// + QuestItem, + + /// + /// 礼包 编号 19xxx + /// + GiftBox, + + /// + /// 其他 编号 20xxx + /// + Others + } + + public enum EquipSlotType + { + None, + MagicCardPack, + Weapon, + Armor, + Shoes, + Accessory1, + Accessory2 } public enum EntityType diff --git a/Service/JsonManager.cs b/Service/JsonManager.cs index af296ba..c582ac7 100644 --- a/Service/JsonManager.cs +++ b/Service/JsonManager.cs @@ -19,7 +19,7 @@ namespace Milimoe.FunGame.Core.Service Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), ReferenceHandler = ReferenceHandler.IgnoreCycles, Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(), - new CharacterConverter(), new MagicResistanceConverter(), new MDFConverter() } + new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter() } }; ///