diff --git a/Entity/Skill/Skill.cs b/Entity/Skill/Skill.cs index ee9fa3f..08eb37e 100644 --- a/Entity/Skill/Skill.cs +++ b/Entity/Skill/Skill.cs @@ -194,7 +194,7 @@ namespace Milimoe.FunGame.Core.Entity /// /// 实际魔法消耗 [ 魔法 ] /// - public double RealMPCost => Math.Max(0, MPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * GameplayEquilibriumConstant.INTtoCastMPReduce))); + public double RealMPCost => FreeCostMP ? 0 : Math.Max(0, MPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * GameplayEquilibriumConstant.INTtoCastMPReduce))); /// /// 魔法消耗 [ 魔法 ] @@ -202,6 +202,11 @@ namespace Milimoe.FunGame.Core.Entity [InitOptional] public virtual double MPCost { get; set; } = 0; + /// + /// 无魔法消耗 [ 运行时 ] + /// + public bool FreeCostMP { get; set; } = false; + /// /// 吟唱时间 [ 魔法 ] /// @@ -216,7 +221,7 @@ namespace Milimoe.FunGame.Core.Entity /// /// 实际能量消耗 [ 战技 ] /// - public double RealEPCost => CostAllEP ? Math.Max(MinCostEP, Character?.EP ?? MinCostEP) : (IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * GameplayEquilibriumConstant.INTtoCastEPReduce)))); + public double RealEPCost => FreeCostEP ? 0 : (CostAllEP ? Math.Max(MinCostEP, Character?.EP ?? MinCostEP) : (IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * GameplayEquilibriumConstant.INTtoCastEPReduce))))); /// /// 能量消耗 [ 战技 ] @@ -234,6 +239,11 @@ namespace Milimoe.FunGame.Core.Entity /// public virtual double MinCostEP { get; set; } = 100; + /// + /// 无能量消耗 [ 运行时 ] + /// + public bool FreeCostEP { get; set; } = false; + /// /// 上一次释放此技能消耗的魔法 [ 魔法 ] /// @@ -247,7 +257,7 @@ namespace Milimoe.FunGame.Core.Entity /// /// 实际冷却时间 /// - public double RealCD => Math.Max(0, CD * (1 - (Character?.CDR ?? 0))); + public double RealCD => InstantReset ? 0 : Math.Max(0, CD * (1 - (Character?.CDR ?? 0))); /// /// 冷却时间 @@ -260,6 +270,11 @@ namespace Milimoe.FunGame.Core.Entity /// public double CurrentCD { get; set; } = 0; + /// + /// 无 CD [ 运行时 ] + /// + public bool InstantReset { get; set; } = false; + /// /// 硬直时间 /// @@ -281,6 +296,25 @@ namespace Milimoe.FunGame.Core.Entity /// public double RealHardnessTime => Math.Max(0, (HardnessTime + ExHardnessTime) * (1 + ExHardnessTime2) * (1 - Calculation.PercentageCheck(Character?.ActionCoefficient ?? 0))); + /// + /// 魔法瓶颈 [ 智力相关 ] + /// + public virtual double MagicBottleneck { get; set; } = 0; + + /// + /// 魔法效能% [ 智力相关 ] 公式:魔法效能 = (角色智力 / 魔法瓶颈) ^ (魔法瓶颈 / 角色智力) + /// 该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍 + /// + public double MagicEfficacy + { + get + { + if (MagicBottleneck == 0) return 1.0; + if (Character is null || Character.INT == 0) return 0.01; + return Math.Clamp(Math.Pow((Character.INT / MagicBottleneck), (MagicBottleneck / Character.INT)), 0.01, 2.0); + } + } + /// /// 效果列表 /// @@ -858,8 +892,12 @@ namespace Milimoe.FunGame.Core.Entity skill.MPCost = skillDefined.MPCost; skill.CastTime = skillDefined.CastTime; skill.EPCost = skillDefined.EPCost; + skill.FreeCostMP = skillDefined.FreeCostMP; + skill.FreeCostEP = skillDefined.FreeCostEP; skill.CD = skillDefined.CD; + skill.InstantReset = skillDefined.InstantReset; skill.HardnessTime = skillDefined.HardnessTime; + skill.MagicBottleneck = skillDefined.MagicBottleneck; skill.GamingQueue = skillDefined.GamingQueue; if (skill is OpenSkill) { diff --git a/Library/Common/JsonConverter/SkillConverter.cs b/Library/Common/JsonConverter/SkillConverter.cs index 9acf066..3aa325f 100644 --- a/Library/Common/JsonConverter/SkillConverter.cs +++ b/Library/Common/JsonConverter/SkillConverter.cs @@ -71,6 +71,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Skill.MPCost): result.MPCost = reader.GetDouble(); break; + case nameof(Skill.FreeCostMP): + result.FreeCostMP = reader.GetBoolean(); + break; case nameof(Skill.EPCost): result.EPCost = reader.GetDouble(); break; @@ -80,6 +83,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Skill.MinCostEP): result.MinCostEP = reader.GetDouble(); break; + case nameof(Skill.FreeCostEP): + result.FreeCostEP = reader.GetBoolean(); + break; case nameof(Skill.CastTime): result.CastTime = reader.GetDouble(); break; @@ -89,6 +95,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Skill.CurrentCD): result.CurrentCD = reader.GetDouble(); break; + case nameof(Skill.InstantReset): + result.InstantReset = reader.GetBoolean(); + break; case nameof(Skill.HardnessTime): result.HardnessTime = reader.GetDouble(); break; @@ -98,6 +107,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Skill.ExHardnessTime2): result.ExHardnessTime2 = reader.GetDouble(); break; + case nameof(Skill.MagicBottleneck): + result.MagicBottleneck = reader.GetDouble(); + break; case nameof(Skill.Effects): HashSet effects = NetworkUtility.JsonDeserialize>(ref reader, options) ?? []; foreach (Effect effect in effects) @@ -141,15 +153,19 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter if (!value.Enable) writer.WriteBoolean(nameof(Skill.Enable), value.Enable); if (value.IsInEffect) writer.WriteBoolean(nameof(Skill.IsInEffect), value.IsInEffect); if (value.MPCost > 0) writer.WriteNumber(nameof(Skill.MPCost), value.MPCost); + if (!value.FreeCostMP) writer.WriteBoolean(nameof(Skill.FreeCostMP), value.FreeCostMP); if (value.EPCost > 0) writer.WriteNumber(nameof(Skill.EPCost), value.EPCost); if (value.CostAllEP) writer.WriteBoolean(nameof(Skill.CostAllEP), value.CostAllEP); if (value.MinCostEP > 0) writer.WriteNumber(nameof(Skill.MinCostEP), value.MinCostEP); + if (!value.FreeCostEP) writer.WriteBoolean(nameof(Skill.FreeCostEP), value.FreeCostEP); if (value.CastTime > 0) writer.WriteNumber(nameof(Skill.CastTime), value.CastTime); if (value.CD > 0) writer.WriteNumber(nameof(Skill.CD), value.CD); if (value.CurrentCD > 0) writer.WriteNumber(nameof(Skill.CurrentCD), value.CurrentCD); + if (!value.InstantReset) writer.WriteBoolean(nameof(Skill.InstantReset), value.InstantReset); if (value.HardnessTime > 0) writer.WriteNumber(nameof(Skill.HardnessTime), value.HardnessTime); if (value.ExHardnessTime != 0) writer.WriteNumber(nameof(Skill.ExHardnessTime), value.ExHardnessTime); if (value.ExHardnessTime2 != 0) writer.WriteNumber(nameof(Skill.ExHardnessTime2), value.ExHardnessTime2); + if (value.MagicBottleneck != 0) writer.WriteNumber(nameof(Skill.MagicBottleneck), value.MagicBottleneck); writer.WritePropertyName(nameof(Skill.Effects)); JsonSerializer.Serialize(writer, value.Effects, options); writer.WritePropertyName(nameof(Skill.Values));