diff --git a/Entity/Skill/Effect.cs b/Entity/Skill/Effect.cs
index 43befac..7b87ec0 100644
--- a/Entity/Skill/Effect.cs
+++ b/Entity/Skill/Effect.cs
@@ -981,7 +981,10 @@ namespace Milimoe.FunGame.Core.Entity
int changeCount = 0;
DamageResult result = DamageResult.Normal;
double damage = expectedDamage;
- options ??= new();
+ options ??= new(actor)
+ {
+ Skill = Skill
+ };
if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
if (options.NeedCalculate && damageType != DamageType.True)
{
diff --git a/Entity/Skill/Skill.cs b/Entity/Skill/Skill.cs
index 08eb37e..2d51983 100644
--- a/Entity/Skill/Skill.cs
+++ b/Entity/Skill/Skill.cs
@@ -299,19 +299,29 @@ namespace Milimoe.FunGame.Core.Entity
///
/// 魔法瓶颈 [ 智力相关 ]
///
- public virtual double MagicBottleneck { get; set; } = 0;
+ public virtual double MagicBottleneck
+ {
+ get
+ {
+ return Math.Max(0, field);
+ }
+ set
+ {
+ field = Math.Max(0, value);
+ }
+ }
///
- /// 魔法效能% [ 智力相关 ] 公式:魔法效能 = (角色智力 / 魔法瓶颈) ^ (魔法瓶颈 / 角色智力)
- /// 该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍
+ /// 魔法效能% [ 智力相关 ] 该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍
+ /// 计算方法:以魔法瓶颈为100%,智力每低于瓶颈的 1%,效能就减少 1%,反之提升
///
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);
+ if (MagicBottleneck == 0 || Character is null) return 1.0;
+ double percentageDiff = (Character.INT - MagicBottleneck) / MagicBottleneck;
+ return Math.Clamp(1.0 + percentageDiff, 0.01, 2.0);
}
}
@@ -810,6 +820,7 @@ namespace Milimoe.FunGame.Core.Entity
{
if (IsMagic)
{
+ if (MagicBottleneck > 0) builder.AppendLine($"魔法瓶颈:{MagicBottleneck:0.##}{(Character != null ? $"({MagicEfficacy * 100:0.##}%)" : "")}");
builder.AppendLine($"魔法消耗:{RealMPCost:0.##}{(showOriginal && RealMPCost != MPCost ? $"(原始值:{MPCost:0.##})" : "")}");
builder.AppendLine($"吟唱时间:{RealCastTime:0.##}{(showOriginal && RealCastTime != CastTime ? $"(原始值:{CastTime:0.##})" : "")}");
}
diff --git a/Model/DamageCalculationOptions.cs b/Model/DamageCalculationOptions.cs
index 52f0b26..d0aa5ce 100644
--- a/Model/DamageCalculationOptions.cs
+++ b/Model/DamageCalculationOptions.cs
@@ -3,10 +3,15 @@
namespace Milimoe.FunGame.Core.Model
{
///
- /// 精准的分步控制伤害计算
+ /// 精准的分步控制伤害计算选项
///
- public class DamageCalculationOptions
+ public class DamageCalculationOptions(Character character)
{
+ ///
+ /// 伤害来源
+ ///
+ public Character Character { get; set; } = character;
+
///
/// 完整计算伤害
///
@@ -42,6 +47,33 @@ namespace Milimoe.FunGame.Core.Model
///
public bool IgnoreImmune { get; set; } = false;
+ ///
+ /// 如果来源是技能
+ ///
+ public Skill? Skill { get; set; } = null;
+
+ ///
+ /// 是魔法技能
+ ///
+ public bool IsMagicSkill => Skill?.IsMagic ?? false;
+
+ ///
+ /// 魔法瓶颈
+ ///
+ public double MagicBottleneck => IsMagicSkill ? (Skill?.MagicBottleneck ?? 0) : 0;
+
+ ///
+ /// 魔法效能%
+ ///
+ public double MagicEfficacy => IsMagicSkill ? (Skill?.MagicEfficacy ?? 1) : 1;
+
+ ///
+ /// 施法者智力
+ ///
+ public double INT => Character.INT;
+
+ /** == 调试数据记录 == **/
+
///
/// 伤害基底(期望)
///
@@ -67,6 +99,11 @@ namespace Milimoe.FunGame.Core.Model
///
internal Dictionary AfterDamageBonus { get; set; } = [];
+ ///
+ /// 魔法效能修正
+ ///
+ internal double MagicEfficacyDamage { get; set; } = 0;
+
///
/// 最终伤害
///
diff --git a/Model/GamingQueue.cs b/Model/GamingQueue.cs
index 7d8c05c..4b9f2e7 100644
--- a/Model/GamingQueue.cs
+++ b/Model/GamingQueue.cs
@@ -1002,7 +1002,9 @@ namespace Milimoe.FunGame.Core.Model
return _isGameEnd;
}
- foreach (Skill skillTurnStart in skills)
+ List skillsTurnStart = [.. character.Skills];
+ AddCharacterEquipSlotSkills(character, skillsTurnStart);
+ foreach (Skill skillTurnStart in skillsTurnStart)
{
skillTurnStart.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items);
}
@@ -2060,7 +2062,7 @@ namespace Milimoe.FunGame.Core.Model
List characters = [actor, enemy];
bool isEvaded = damageResult == DamageResult.Evaded;
List effects = [];
- options ??= new();
+ options ??= new(actor);
if (options.ExpectedDamage == 0) options.ExpectedDamage = damage;
Dictionary totalDamageBonus = [];
@@ -2094,6 +2096,14 @@ namespace Milimoe.FunGame.Core.Model
}
}
options.AfterDamageBonus = totalDamageBonus;
+
+ // 魔法效能乘区
+ if (options.IsMagicSkill)
+ {
+ options.MagicEfficacyDamage = damage * (options.MagicEfficacy - 1);
+ damage *= options.MagicEfficacy;
+ }
+
options.FinalDamage = damage;
double actualDamage = damage;
@@ -2351,8 +2361,9 @@ namespace Milimoe.FunGame.Core.Model
{
strAfterBonus = string.Join("", options.AfterDamageBonus.Select(kv => $"{(kv.Value >= 0 ? " + " : " - ")}{Math.Abs(kv.Value):0.##}({kv.Key.Name})"));
}
+ string strMagicEfficacyDamage = options.MagicEfficacyDamage == 0 ? "" : ($"{(options.MagicEfficacyDamage >= 0 ? " + " : " - ")}{Math.Abs(options.MagicEfficacyDamage):0.##}(魔法效能:{options.MagicEfficacy * 100:0.##}%)");
string strShieldReduction = options.ShieldReduction == 0 ? "" : ($"{(options.ShieldReduction >= 0 ? " - " : " + ")}{Math.Abs(options.ShieldReduction):0.##}(护盾)");
- strDamageMessage += $"【{options.ExpectedDamage:0.##}(基础){strBeforeBonus}{strDefenseReduction}{strCriticalDamage}{strAfterBonus}{strShieldReduction} = {options.ActualDamage:0.##} 点{damageTypeString}】";
+ strDamageMessage += $"【{options.ExpectedDamage:0.##}(基础){strBeforeBonus}{strDefenseReduction}{strCriticalDamage}{strAfterBonus}{strMagicEfficacyDamage}{strShieldReduction} = {options.ActualDamage:0.##} 点{damageTypeString}】";
}
WriteLine(strDamageMessage);
@@ -2796,6 +2807,21 @@ namespace Milimoe.FunGame.Core.Model
#region 回合内-辅助方法
+ ///
+ /// 将角色装备栏中的主动技能加入列表
+ ///
+ ///
+ ///
+ public static void AddCharacterEquipSlotSkills(Character character, List list)
+ {
+ if (character.EquipSlot.MagicCardPack?.Skills.Active != null) list.Add(character.EquipSlot.MagicCardPack.Skills.Active);
+ if (character.EquipSlot.Weapon?.Skills.Active != null) list.Add(character.EquipSlot.Weapon.Skills.Active);
+ if (character.EquipSlot.Armor?.Skills.Active != null) list.Add(character.EquipSlot.Armor.Skills.Active);
+ if (character.EquipSlot.Shoes?.Skills.Active != null) list.Add(character.EquipSlot.Shoes.Skills.Active);
+ if (character.EquipSlot.Accessory1?.Skills.Active != null) list.Add(character.EquipSlot.Accessory1.Skills.Active);
+ if (character.EquipSlot.Accessory2?.Skills.Active != null) list.Add(character.EquipSlot.Accessory2.Skills.Active);
+ }
+
///
/// 取得回合开始时必需的列表
///
@@ -2809,7 +2835,11 @@ namespace Milimoe.FunGame.Core.Model
List selectableEnemys = [.. allEnemys.Where(c => _queue.Contains(c) && !c.IsUnselectable)];
// 技能列表
- List skills = [.. character.Skills.Where(s => s.Level > 0 && s.SkillType != SkillType.Passive && s.Enable && !s.IsInEffect && s.CurrentCD == 0 &&
+ List skills = [.. character.Skills];
+
+ // 将角色装备栏中的主动技能加入技能列表以供筛选
+ AddCharacterEquipSlotSkills(character, skills);
+ skills = [.. 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.RealEPCost <= character.EP || s.SkillType == SkillType.Magic && s.RealMPCost <= character.MP))];
// 物品列表
@@ -3295,7 +3325,7 @@ namespace Milimoe.FunGame.Core.Model
///
public DamageResult CalculatePhysicalDamage(Character actor, Character enemy, bool isNormalAttack, double expectedDamage, out double finalDamage, ref int changeCount, ref DamageCalculationOptions? options)
{
- options ??= new();
+ options ??= new(actor);
if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
List characters = [actor, enemy];
DamageType damageType = DamageType.Physical;
@@ -3429,7 +3459,7 @@ namespace Milimoe.FunGame.Core.Model
///
public DamageResult CalculateMagicalDamage(Character actor, Character enemy, bool isNormalAttack, MagicType magicType, double expectedDamage, out double finalDamage, ref int changeCount, ref DamageCalculationOptions? options)
{
- options ??= new();
+ options ??= new(actor);
if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
List characters = [actor, enemy];
DamageType damageType = DamageType.Magical;