Skill 添加无魔法消耗、无能量消耗、无 CD、魔法瓶颈、魔法效能% 属性

This commit is contained in:
milimoe 2026-01-18 04:18:38 +08:00
parent 787b5a12e0
commit 8f2467a93a
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
2 changed files with 57 additions and 3 deletions

View File

@ -194,7 +194,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 实际魔法消耗 [ 魔法 ] /// 实际魔法消耗 [ 魔法 ]
/// </summary> /// </summary>
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)));
/// <summary> /// <summary>
/// 魔法消耗 [ 魔法 ] /// 魔法消耗 [ 魔法 ]
@ -202,6 +202,11 @@ namespace Milimoe.FunGame.Core.Entity
[InitOptional] [InitOptional]
public virtual double MPCost { get; set; } = 0; public virtual double MPCost { get; set; } = 0;
/// <summary>
/// 无魔法消耗 [ 运行时 ]
/// </summary>
public bool FreeCostMP { get; set; } = false;
/// <summary> /// <summary>
/// 吟唱时间 [ 魔法 ] /// 吟唱时间 [ 魔法 ]
/// </summary> /// </summary>
@ -216,7 +221,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 实际能量消耗 [ 战技 ] /// 实际能量消耗 [ 战技 ]
/// </summary> /// </summary>
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)))));
/// <summary> /// <summary>
/// 能量消耗 [ 战技 ] /// 能量消耗 [ 战技 ]
@ -234,6 +239,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public virtual double MinCostEP { get; set; } = 100; public virtual double MinCostEP { get; set; } = 100;
/// <summary>
/// 无能量消耗 [ 运行时 ]
/// </summary>
public bool FreeCostEP { get; set; } = false;
/// <summary> /// <summary>
/// 上一次释放此技能消耗的魔法 [ 魔法 ] /// 上一次释放此技能消耗的魔法 [ 魔法 ]
/// </summary> /// </summary>
@ -247,7 +257,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 实际冷却时间 /// 实际冷却时间
/// </summary> /// </summary>
public double RealCD => Math.Max(0, CD * (1 - (Character?.CDR ?? 0))); public double RealCD => InstantReset ? 0 : Math.Max(0, CD * (1 - (Character?.CDR ?? 0)));
/// <summary> /// <summary>
/// 冷却时间 /// 冷却时间
@ -260,6 +270,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public double CurrentCD { get; set; } = 0; public double CurrentCD { get; set; } = 0;
/// <summary>
/// 无 CD [ 运行时 ]
/// </summary>
public bool InstantReset { get; set; } = false;
/// <summary> /// <summary>
/// 硬直时间 /// 硬直时间
/// </summary> /// </summary>
@ -281,6 +296,25 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public double RealHardnessTime => Math.Max(0, (HardnessTime + ExHardnessTime) * (1 + ExHardnessTime2) * (1 - Calculation.PercentageCheck(Character?.ActionCoefficient ?? 0))); public double RealHardnessTime => Math.Max(0, (HardnessTime + ExHardnessTime) * (1 + ExHardnessTime2) * (1 - Calculation.PercentageCheck(Character?.ActionCoefficient ?? 0)));
/// <summary>
/// 魔法瓶颈 [ 智力相关 ]
/// </summary>
public virtual double MagicBottleneck { get; set; } = 0;
/// <summary>
/// 魔法效能% [ 智力相关 ] 公式:魔法效能 = (角色智力 / 魔法瓶颈) ^ (魔法瓶颈 / 角色智力)
/// <para/>该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍
/// </summary>
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);
}
}
/// <summary> /// <summary>
/// 效果列表 /// 效果列表
/// </summary> /// </summary>
@ -858,8 +892,12 @@ namespace Milimoe.FunGame.Core.Entity
skill.MPCost = skillDefined.MPCost; skill.MPCost = skillDefined.MPCost;
skill.CastTime = skillDefined.CastTime; skill.CastTime = skillDefined.CastTime;
skill.EPCost = skillDefined.EPCost; skill.EPCost = skillDefined.EPCost;
skill.FreeCostMP = skillDefined.FreeCostMP;
skill.FreeCostEP = skillDefined.FreeCostEP;
skill.CD = skillDefined.CD; skill.CD = skillDefined.CD;
skill.InstantReset = skillDefined.InstantReset;
skill.HardnessTime = skillDefined.HardnessTime; skill.HardnessTime = skillDefined.HardnessTime;
skill.MagicBottleneck = skillDefined.MagicBottleneck;
skill.GamingQueue = skillDefined.GamingQueue; skill.GamingQueue = skillDefined.GamingQueue;
if (skill is OpenSkill) if (skill is OpenSkill)
{ {

View File

@ -71,6 +71,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Skill.MPCost): case nameof(Skill.MPCost):
result.MPCost = reader.GetDouble(); result.MPCost = reader.GetDouble();
break; break;
case nameof(Skill.FreeCostMP):
result.FreeCostMP = reader.GetBoolean();
break;
case nameof(Skill.EPCost): case nameof(Skill.EPCost):
result.EPCost = reader.GetDouble(); result.EPCost = reader.GetDouble();
break; break;
@ -80,6 +83,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Skill.MinCostEP): case nameof(Skill.MinCostEP):
result.MinCostEP = reader.GetDouble(); result.MinCostEP = reader.GetDouble();
break; break;
case nameof(Skill.FreeCostEP):
result.FreeCostEP = reader.GetBoolean();
break;
case nameof(Skill.CastTime): case nameof(Skill.CastTime):
result.CastTime = reader.GetDouble(); result.CastTime = reader.GetDouble();
break; break;
@ -89,6 +95,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Skill.CurrentCD): case nameof(Skill.CurrentCD):
result.CurrentCD = reader.GetDouble(); result.CurrentCD = reader.GetDouble();
break; break;
case nameof(Skill.InstantReset):
result.InstantReset = reader.GetBoolean();
break;
case nameof(Skill.HardnessTime): case nameof(Skill.HardnessTime):
result.HardnessTime = reader.GetDouble(); result.HardnessTime = reader.GetDouble();
break; break;
@ -98,6 +107,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Skill.ExHardnessTime2): case nameof(Skill.ExHardnessTime2):
result.ExHardnessTime2 = reader.GetDouble(); result.ExHardnessTime2 = reader.GetDouble();
break; break;
case nameof(Skill.MagicBottleneck):
result.MagicBottleneck = reader.GetDouble();
break;
case nameof(Skill.Effects): case nameof(Skill.Effects):
HashSet<Effect> effects = NetworkUtility.JsonDeserialize<HashSet<Effect>>(ref reader, options) ?? []; HashSet<Effect> effects = NetworkUtility.JsonDeserialize<HashSet<Effect>>(ref reader, options) ?? [];
foreach (Effect effect in effects) 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.Enable) writer.WriteBoolean(nameof(Skill.Enable), value.Enable);
if (value.IsInEffect) writer.WriteBoolean(nameof(Skill.IsInEffect), value.IsInEffect); if (value.IsInEffect) writer.WriteBoolean(nameof(Skill.IsInEffect), value.IsInEffect);
if (value.MPCost > 0) writer.WriteNumber(nameof(Skill.MPCost), value.MPCost); 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.EPCost > 0) writer.WriteNumber(nameof(Skill.EPCost), value.EPCost);
if (value.CostAllEP) writer.WriteBoolean(nameof(Skill.CostAllEP), value.CostAllEP); if (value.CostAllEP) writer.WriteBoolean(nameof(Skill.CostAllEP), value.CostAllEP);
if (value.MinCostEP > 0) writer.WriteNumber(nameof(Skill.MinCostEP), value.MinCostEP); 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.CastTime > 0) writer.WriteNumber(nameof(Skill.CastTime), value.CastTime);
if (value.CD > 0) writer.WriteNumber(nameof(Skill.CD), value.CD); if (value.CD > 0) writer.WriteNumber(nameof(Skill.CD), value.CD);
if (value.CurrentCD > 0) writer.WriteNumber(nameof(Skill.CurrentCD), value.CurrentCD); 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.HardnessTime > 0) writer.WriteNumber(nameof(Skill.HardnessTime), value.HardnessTime);
if (value.ExHardnessTime != 0) writer.WriteNumber(nameof(Skill.ExHardnessTime), value.ExHardnessTime); if (value.ExHardnessTime != 0) writer.WriteNumber(nameof(Skill.ExHardnessTime), value.ExHardnessTime);
if (value.ExHardnessTime2 != 0) writer.WriteNumber(nameof(Skill.ExHardnessTime2), value.ExHardnessTime2); 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)); writer.WritePropertyName(nameof(Skill.Effects));
JsonSerializer.Serialize(writer, value.Effects, options); JsonSerializer.Serialize(writer, value.Effects, options);
writer.WritePropertyName(nameof(Skill.Values)); writer.WritePropertyName(nameof(Skill.Values));