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

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;
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)
{

View File

@ -299,19 +299,29 @@ namespace Milimoe.FunGame.Core.Entity
/// <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>
/// 魔法效能% [ 智力相关 ] 公式:魔法效能 = (角色智力 / 魔法瓶颈) ^ (魔法瓶颈 / 角色智力)
/// <para/>该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍
/// 魔法效能% [ 智力相关 ] 该值决定魔法的实际施展效果(乘算),低于 1 时会使效果低于预期,最多增长至 2 倍
/// <para/>计算方法以魔法瓶颈为100%,智力每低于瓶颈的 1%,效能就减少 1%,反之提升
/// </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);
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.##}" : "")}");
}

View File

@ -3,10 +3,15 @@
namespace Milimoe.FunGame.Core.Model
{
/// <summary>
/// 精准的分步控制伤害计算
/// 精准的分步控制伤害计算选项
/// </summary>
public class DamageCalculationOptions
public class DamageCalculationOptions(Character character)
{
/// <summary>
/// 伤害来源
/// </summary>
public Character Character { get; set; } = character;
/// <summary>
/// 完整计算伤害
/// </summary>
@ -42,6 +47,33 @@ namespace Milimoe.FunGame.Core.Model
/// </summary>
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>
@ -67,6 +99,11 @@ namespace Milimoe.FunGame.Core.Model
/// </summary>
internal Dictionary<Effect, double> AfterDamageBonus { get; set; } = [];
/// <summary>
/// 魔法效能修正
/// </summary>
internal double MagicEfficacyDamage { get; set; } = 0;
/// <summary>
/// 最终伤害
/// </summary>

View File

@ -1002,7 +1002,9 @@ namespace Milimoe.FunGame.Core.Model
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);
}
@ -2060,7 +2062,7 @@ namespace Milimoe.FunGame.Core.Model
List<Character> characters = [actor, enemy];
bool isEvaded = damageResult == DamageResult.Evaded;
List<Effect> effects = [];
options ??= new();
options ??= new(actor);
if (options.ExpectedDamage == 0) options.ExpectedDamage = damage;
Dictionary<Effect, double> 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 -
/// <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>
@ -2809,7 +2835,11 @@ namespace Milimoe.FunGame.Core.Model
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))];
// 物品列表
@ -3295,7 +3325,7 @@ namespace Milimoe.FunGame.Core.Model
/// <returns></returns>
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<Character> characters = [actor, enemy];
DamageType damageType = DamageType.Physical;
@ -3429,7 +3459,7 @@ namespace Milimoe.FunGame.Core.Model
/// <returns></returns>
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<Character> characters = [actor, enemy];
DamageType damageType = DamageType.Magical;