完善瓶颈和效能;修复装备主动技能无法触发的问题

This commit is contained in:
milimoe 2026-01-19 01:34:22 +08:00
parent 8f2467a93a
commit 4bd706c43c
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
4 changed files with 96 additions and 15 deletions

View File

@ -981,7 +981,10 @@ namespace Milimoe.FunGame.Core.Entity
int changeCount = 0; int changeCount = 0;
DamageResult result = DamageResult.Normal; DamageResult result = DamageResult.Normal;
double damage = expectedDamage; double damage = expectedDamage;
options ??= new(); options ??= new(actor)
{
Skill = Skill
};
if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage; if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
if (options.NeedCalculate && damageType != DamageType.True) if (options.NeedCalculate && damageType != DamageType.True)
{ {

View File

@ -299,19 +299,29 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 魔法瓶颈 [ 智力相关 ] /// 魔法瓶颈 [ 智力相关 ]
/// </summary> /// </summary>
public virtual double MagicBottleneck { get; set; } = 0; public virtual double MagicBottleneck
{
get
{
return Math.Max(0, field);
}
set
{
field = Math.Max(0, value);
}
}
/// <summary> /// <summary>
/// 魔法效能% [ 智力相关 ] 公式:魔法效能 = (角色智力 / 魔法瓶颈) ^ (魔法瓶颈 / 角色智力) /// 魔法效能% [ 智力相关 ] 该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍
/// <para/>该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍 /// <para/>计算方法以魔法瓶颈为100%,智力每低于瓶颈的 1%,效能就减少 1%,反之提升
/// </summary> /// </summary>
public double MagicEfficacy public double MagicEfficacy
{ {
get get
{ {
if (MagicBottleneck == 0) return 1.0; if (MagicBottleneck == 0 || Character is null) return 1.0;
if (Character is null || Character.INT == 0) return 0.01; double percentageDiff = (Character.INT - MagicBottleneck) / MagicBottleneck;
return Math.Clamp(Math.Pow((Character.INT / MagicBottleneck), (MagicBottleneck / Character.INT)), 0.01, 2.0); return Math.Clamp(1.0 + percentageDiff, 0.01, 2.0);
} }
} }
@ -810,6 +820,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
if (IsMagic) 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($"魔法消耗:{RealMPCost:0.##}{(showOriginal && RealMPCost != MPCost ? $"{MPCost:0.##}" : "")}");
builder.AppendLine($"吟唱时间:{RealCastTime:0.##}{(showOriginal && RealCastTime != CastTime ? $"{CastTime:0.##}" : "")}"); builder.AppendLine($"吟唱时间:{RealCastTime:0.##}{(showOriginal && RealCastTime != CastTime ? $"{CastTime:0.##}" : "")}");
} }

View File

@ -3,10 +3,15 @@
namespace Milimoe.FunGame.Core.Model namespace Milimoe.FunGame.Core.Model
{ {
/// <summary> /// <summary>
/// 精准的分步控制伤害计算 /// 精准的分步控制伤害计算选项
/// </summary> /// </summary>
public class DamageCalculationOptions public class DamageCalculationOptions(Character character)
{ {
/// <summary>
/// 伤害来源
/// </summary>
public Character Character { get; set; } = character;
/// <summary> /// <summary>
/// 完整计算伤害 /// 完整计算伤害
/// </summary> /// </summary>
@ -42,6 +47,33 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
public bool IgnoreImmune { get; set; } = false; public bool IgnoreImmune { get; set; } = false;
/// <summary>
/// 如果来源是技能
/// </summary>
public Skill? Skill { get; set; } = null;
/// <summary>
/// 是魔法技能
/// </summary>
public bool IsMagicSkill => Skill?.IsMagic ?? false;
/// <summary>
/// 魔法瓶颈
/// </summary>
public double MagicBottleneck => IsMagicSkill ? (Skill?.MagicBottleneck ?? 0) : 0;
/// <summary>
/// 魔法效能%
/// </summary>
public double MagicEfficacy => IsMagicSkill ? (Skill?.MagicEfficacy ?? 1) : 1;
/// <summary>
/// 施法者智力
/// </summary>
public double INT => Character.INT;
/** == 调试数据记录 == **/
/// <summary> /// <summary>
/// 伤害基底(期望) /// 伤害基底(期望)
/// </summary> /// </summary>
@ -67,6 +99,11 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
internal Dictionary<Effect, double> AfterDamageBonus { get; set; } = []; internal Dictionary<Effect, double> AfterDamageBonus { get; set; } = [];
/// <summary>
/// 魔法效能修正
/// </summary>
internal double MagicEfficacyDamage { get; set; } = 0;
/// <summary> /// <summary>
/// 最终伤害 /// 最终伤害
/// </summary> /// </summary>

View File

@ -1002,7 +1002,9 @@ namespace Milimoe.FunGame.Core.Model
return _isGameEnd; return _isGameEnd;
} }
foreach (Skill skillTurnStart in skills) List<Skill> skillsTurnStart = [.. character.Skills];
AddCharacterEquipSlotSkills(character, skillsTurnStart);
foreach (Skill skillTurnStart in skillsTurnStart)
{ {
skillTurnStart.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items); skillTurnStart.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items);
} }
@ -2060,7 +2062,7 @@ namespace Milimoe.FunGame.Core.Model
List<Character> characters = [actor, enemy]; List<Character> characters = [actor, enemy];
bool isEvaded = damageResult == DamageResult.Evaded; bool isEvaded = damageResult == DamageResult.Evaded;
List<Effect> effects = []; List<Effect> effects = [];
options ??= new(); options ??= new(actor);
if (options.ExpectedDamage == 0) options.ExpectedDamage = damage; if (options.ExpectedDamage == 0) options.ExpectedDamage = damage;
Dictionary<Effect, double> totalDamageBonus = []; Dictionary<Effect, double> totalDamageBonus = [];
@ -2094,6 +2096,14 @@ namespace Milimoe.FunGame.Core.Model
} }
} }
options.AfterDamageBonus = totalDamageBonus; options.AfterDamageBonus = totalDamageBonus;
// 魔法效能乘区
if (options.IsMagicSkill)
{
options.MagicEfficacyDamage = damage * (options.MagicEfficacy - 1);
damage *= options.MagicEfficacy;
}
options.FinalDamage = damage; options.FinalDamage = damage;
double actualDamage = 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}")); 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.##}(护盾)"); 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); WriteLine(strDamageMessage);
@ -2796,6 +2807,21 @@ namespace Milimoe.FunGame.Core.Model
#region - #region -
/// <summary>
/// 将角色装备栏中的主动技能加入列表
/// </summary>
/// <param name="character"></param>
/// <param name="list"></param>
public static void AddCharacterEquipSlotSkills(Character character, List<Skill> 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);
}
/// <summary> /// <summary>
/// 取得回合开始时必需的列表 /// 取得回合开始时必需的列表
/// </summary> /// </summary>
@ -2809,7 +2835,11 @@ namespace Milimoe.FunGame.Core.Model
List<Character> selectableEnemys = [.. allEnemys.Where(c => _queue.Contains(c) && !c.IsUnselectable)]; List<Character> selectableEnemys = [.. allEnemys.Where(c => _queue.Contains(c) && !c.IsUnselectable)];
// 技能列表 // 技能列表
List<Skill> skills = [.. character.Skills.Where(s => s.Level > 0 && s.SkillType != SkillType.Passive && s.Enable && !s.IsInEffect && s.CurrentCD == 0 && List<Skill> 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))]; ((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
/// <returns></returns> /// <returns></returns>
public DamageResult CalculatePhysicalDamage(Character actor, Character enemy, bool isNormalAttack, double expectedDamage, out double finalDamage, ref int changeCount, ref DamageCalculationOptions? options) 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; if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
List<Character> characters = [actor, enemy]; List<Character> characters = [actor, enemy];
DamageType damageType = DamageType.Physical; DamageType damageType = DamageType.Physical;
@ -3429,7 +3459,7 @@ namespace Milimoe.FunGame.Core.Model
/// <returns></returns> /// <returns></returns>
public DamageResult CalculateMagicalDamage(Character actor, Character enemy, bool isNormalAttack, MagicType magicType, double expectedDamage, out double finalDamage, ref int changeCount, ref DamageCalculationOptions? options) 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; if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
List<Character> characters = [actor, enemy]; List<Character> characters = [actor, enemy];
DamageType damageType = DamageType.Magical; DamageType damageType = DamageType.Magical;