护盾抵消伤害与实际伤害分离

This commit is contained in:
milimoe 2025-05-13 07:50:31 +08:00
parent cb44cb5672
commit 82538b9d93
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
3 changed files with 40 additions and 18 deletions

View File

@ -360,11 +360,12 @@ namespace Milimoe.FunGame.Core.Entity
/// <param name="character"></param> /// <param name="character"></param>
/// <param name="enemy"></param> /// <param name="enemy"></param>
/// <param name="damage"></param> /// <param name="damage"></param>
/// <param name="actualDamage"></param>
/// <param name="isNormalAttack"></param> /// <param name="isNormalAttack"></param>
/// <param name="isMagicDamage"></param> /// <param name="isMagicDamage"></param>
/// <param name="magicType"></param> /// <param name="magicType"></param>
/// <param name="damageResult"></param> /// <param name="damageResult"></param>
public virtual void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) public virtual void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult)
{ {
} }

View File

@ -62,7 +62,9 @@ namespace Milimoe.FunGame.Core.Library.Constant
{ {
Normal, Normal,
Critical, Critical,
Evaded Evaded,
Shield,
Immune
} }
public enum RedeemResult public enum RedeemResult

View File

@ -1132,6 +1132,7 @@ namespace Milimoe.FunGame.Core.Model
} }
else if (type == CharacterActionType.EndTurn) else if (type == CharacterActionType.EndTurn)
{ {
baseTime = 3;
decided = true; decided = true;
WriteLine($"[ {character} ] 结束了回合!"); WriteLine($"[ {character} ] 结束了回合!");
await OnCharacterDoNothingAsync(character); await OnCharacterDoNothingAsync(character);
@ -1183,8 +1184,8 @@ namespace Milimoe.FunGame.Core.Model
LastRound.CastTime = newHardnessTime; LastRound.CastTime = newHardnessTime;
} }
AddCharacter(character, newHardnessTime, isCheckProtected); AddCharacter(character, newHardnessTime, isCheckProtected);
await OnQueueUpdatedAsync(_queue, character, newHardnessTime, QueueUpdatedReason.Action, "设置角色行动后的硬直时间。");
LastRound.HardnessTime = newHardnessTime; LastRound.HardnessTime = newHardnessTime;
await OnQueueUpdatedAsync(_queue, character, newHardnessTime, QueueUpdatedReason.Action, "设置角色行动后的硬直时间。");
effects = [.. character.Effects]; effects = [.. character.Effects];
foreach (Effect effect in effects) foreach (Effect effect in effects)
@ -1340,8 +1341,10 @@ namespace Milimoe.FunGame.Core.Model
return; return;
} }
// 不管有没有暴击,都尝试往回合记录中添加目标,不暴击时不会修改原先值
if (!LastRound.IsCritical.TryAdd(enemy, damageResult == DamageResult.Critical) && damageResult == DamageResult.Critical) if (!LastRound.IsCritical.TryAdd(enemy, damageResult == DamageResult.Critical) && damageResult == DamageResult.Critical)
{ {
// 暴击了修改目标对应的值为 true
LastRound.IsCritical[enemy] = true; LastRound.IsCritical[enemy] = true;
} }
@ -1359,6 +1362,7 @@ namespace Milimoe.FunGame.Core.Model
} }
} }
damage += totalDamageBonus.Sum(kv => kv.Value); damage += totalDamageBonus.Sum(kv => kv.Value);
double actualDamage = damage;
// 闪避了就没伤害了 // 闪避了就没伤害了
if (damageResult != DamageResult.Evaded) if (damageResult != DamageResult.Evaded)
@ -1402,6 +1406,7 @@ namespace Milimoe.FunGame.Core.Model
if (isImmune) if (isImmune)
{ {
// 免疫 // 免疫
damageResult = DamageResult.Immune;
LastRound.IsImmune[enemy] = true; LastRound.IsImmune[enemy] = true;
WriteLine($"[ {enemy} ] 免疫了此伤害!"); WriteLine($"[ {enemy} ] 免疫了此伤害!");
} }
@ -1448,21 +1453,31 @@ namespace Milimoe.FunGame.Core.Model
{ {
enemy.HP -= remain; enemy.HP -= remain;
shieldMsg = $"(护盾抵消了 {shield:0.##} 点并破碎,角色承受了 {remain:0.##} 点)"; shieldMsg = $"(护盾抵消了 {shield:0.##} 点并破碎,角色承受了 {remain:0.##} 点)";
actualDamage = remain;
} }
else else
{ {
shieldMsg = $"(护盾抵消了 {shield:0.##} 点并破碎,角色没有承受伤害)"; shieldMsg = $"(护盾抵消了 {shield:0.##} 点并破碎,角色没有承受伤害)";
damageResult = DamageResult.Shield;
actualDamage = 0;
} }
} }
else else
{ {
enemy.Shield[isMagicDamage, magicType] = remain; enemy.Shield[isMagicDamage, magicType] = remain;
shieldMsg = $"(护盾抵消了 {damage:0.##} 点,剩余可用 {remain:0.##} 点)"; shieldMsg = $"(护盾抵消了 {damage:0.##} 点,剩余可用 {remain:0.##} 点)";
damageResult = DamageResult.Shield;
actualDamage = 0;
} }
} }
else if (shieldMsg.Trim() == "") else
{ {
shieldMsg = $"(护盾已使其无效化)"; if (shieldMsg.Trim() == "")
{
shieldMsg = $"(护盾已使其无效化)";
}
damageResult = DamageResult.Shield;
actualDamage = 0;
} }
} }
else enemy.HP -= damage; else enemy.HP -= damage;
@ -1474,7 +1489,7 @@ namespace Milimoe.FunGame.Core.Model
} }
else WriteLine($"[ {enemy} ] 受到了 {damage:0.##} 点物理伤害!{shieldMsg}"); else WriteLine($"[ {enemy} ] 受到了 {damage:0.##} 点物理伤害!{shieldMsg}");
// 生命偷取 // 生命偷取,攻击者为全额
double steal = damage * actor.Lifesteal; double steal = damage * actor.Lifesteal;
await HealToTargetAsync(actor, actor, steal, false); await HealToTargetAsync(actor, actor, steal, false);
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
@ -1483,7 +1498,7 @@ namespace Milimoe.FunGame.Core.Model
effect.AfterLifesteal(actor, enemy, damage, steal); effect.AfterLifesteal(actor, enemy, damage, steal);
} }
// 造成伤害和受伤都可以获得能量 // 造成伤害和受伤都可以获得能量。攻击者为全额,被攻击者为 actualDamage护盾抵消的伤害不算
double ep = GetEP(damage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax); double ep = GetEP(damage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax);
effects = [.. actor.Effects.Where(e => e.IsInEffect)]; effects = [.. actor.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
@ -1491,7 +1506,7 @@ namespace Milimoe.FunGame.Core.Model
effect.AlterEPAfterDamage(actor, ref ep); effect.AlterEPAfterDamage(actor, ref ep);
} }
actor.EP += ep; actor.EP += ep;
ep = GetEP(damage, GameplayEquilibriumConstant.TakenDamageGetEPFactor, GameplayEquilibriumConstant.TakenDamageGetEPMax); ep = GetEP(actualDamage, GameplayEquilibriumConstant.TakenDamageGetEPFactor, GameplayEquilibriumConstant.TakenDamageGetEPMax);
effects = [.. enemy.Effects.Where(e => e.IsInEffect)]; effects = [.. enemy.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
@ -1500,7 +1515,7 @@ namespace Milimoe.FunGame.Core.Model
enemy.EP += ep; enemy.EP += ep;
// 统计伤害 // 统计伤害
CalculateCharacterDamageStatistics(actor, enemy, damage, isMagicDamage); CalculateCharacterDamageStatistics(actor, enemy, damage, isMagicDamage, actualDamage);
// 计算助攻 // 计算助攻
_assistDetail[actor][enemy, TotalTime] += damage; _assistDetail[actor][enemy, TotalTime] += damage;
@ -1511,12 +1526,12 @@ namespace Milimoe.FunGame.Core.Model
LastRound.IsEvaded[enemy] = true; LastRound.IsEvaded[enemy] = true;
} }
await OnDamageToEnemyAsync(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult); await OnDamageToEnemyAsync(actor, enemy, damage, actualDamage, isNormalAttack, isMagicDamage, magicType, damageResult);
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AfterDamageCalculation(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult); effect.AfterDamageCalculation(actor, enemy, damage, actualDamage, isNormalAttack, isMagicDamage, magicType, damageResult);
} }
if (enemy.HP <= 0 && !_eliminated.Contains(enemy) && !_respawnCountdown.ContainsKey(enemy)) if (enemy.HP <= 0 && !_eliminated.Contains(enemy) && !_respawnCountdown.ContainsKey(enemy))
@ -1639,6 +1654,7 @@ namespace Milimoe.FunGame.Core.Model
if (assist != killer) if (assist != killer)
{ {
if (!_earnedMoney.TryAdd(assist, cmoney)) _earnedMoney[assist] += cmoney; if (!_earnedMoney.TryAdd(assist, cmoney)) _earnedMoney[assist] += cmoney;
assist.User.Inventory.Credits += cmoney;
_stats[assist].Assists += 1; _stats[assist].Assists += 1;
} }
else else
@ -1708,6 +1724,7 @@ namespace Milimoe.FunGame.Core.Model
} }
if (!_earnedMoney.TryAdd(killer, money)) _earnedMoney[killer] += money; if (!_earnedMoney.TryAdd(killer, money)) _earnedMoney[killer] += money;
killer.User.Inventory.Credits += money;
await OnDeathCalculation(death, killer); await OnDeathCalculation(death, killer);
@ -2635,8 +2652,9 @@ namespace Milimoe.FunGame.Core.Model
/// <summary> /// <summary>
/// 计算角色的数据 /// 计算角色的数据
/// </summary> /// </summary>
public void CalculateCharacterDamageStatistics(Character character, Character characterTaken, double damage, bool isMagic) public void CalculateCharacterDamageStatistics(Character character, Character characterTaken, double damage, bool isMagic, double takenDamage = -1)
{ {
if (takenDamage == -1) takenDamage = damage;
if (_stats.TryGetValue(character, out CharacterStatistics? stats) && stats != null) if (_stats.TryGetValue(character, out CharacterStatistics? stats) && stats != null)
{ {
if (isMagic) if (isMagic)
@ -2653,13 +2671,13 @@ namespace Milimoe.FunGame.Core.Model
{ {
if (isMagic) if (isMagic)
{ {
statsTaken.TotalTakenMagicDamage = Calculation.Round2Digits(statsTaken.TotalTakenMagicDamage + damage); statsTaken.TotalTakenMagicDamage = Calculation.Round2Digits(statsTaken.TotalTakenMagicDamage + takenDamage);
} }
else else
{ {
statsTaken.TotalTakenPhysicalDamage = Calculation.Round2Digits(statsTaken.TotalTakenPhysicalDamage + damage); statsTaken.TotalTakenPhysicalDamage = Calculation.Round2Digits(statsTaken.TotalTakenPhysicalDamage + takenDamage);
} }
statsTaken.TotalTakenDamage = Calculation.Round2Digits(statsTaken.TotalTakenDamage + damage); statsTaken.TotalTakenDamage = Calculation.Round2Digits(statsTaken.TotalTakenDamage + takenDamage);
} }
if (LastRound.Damages.TryGetValue(characterTaken, out double damageTotal)) if (LastRound.Damages.TryGetValue(characterTaken, out double damageTotal))
{ {
@ -2912,7 +2930,7 @@ namespace Milimoe.FunGame.Core.Model
await (HealToTarget?.Invoke(this, actor, target, heal, isRespawn) ?? Task.CompletedTask); await (HealToTarget?.Invoke(this, actor, target, heal, isRespawn) ?? Task.CompletedTask);
} }
public delegate Task DamageToEnemyEventHandler(GamingQueue queue, Character actor, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult); public delegate Task DamageToEnemyEventHandler(GamingQueue queue, Character actor, Character enemy, double damage, double actualDamage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult);
/// <summary> /// <summary>
/// 造成伤害事件 /// 造成伤害事件
/// </summary> /// </summary>
@ -2923,14 +2941,15 @@ namespace Milimoe.FunGame.Core.Model
/// <param name="actor"></param> /// <param name="actor"></param>
/// <param name="enemy"></param> /// <param name="enemy"></param>
/// <param name="damage"></param> /// <param name="damage"></param>
/// <param name="actualDamage"></param>
/// <param name="isNormalAttack"></param> /// <param name="isNormalAttack"></param>
/// <param name="isMagicDamage"></param> /// <param name="isMagicDamage"></param>
/// <param name="magicType"></param> /// <param name="magicType"></param>
/// <param name="damageResult"></param> /// <param name="damageResult"></param>
/// <returns></returns> /// <returns></returns>
protected async Task OnDamageToEnemyAsync(Character actor, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) protected async Task OnDamageToEnemyAsync(Character actor, Character enemy, double damage, double actualDamage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult)
{ {
await (DamageToEnemy?.Invoke(this, actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult) ?? Task.CompletedTask); await (DamageToEnemy?.Invoke(this, actor, enemy, damage, actualDamage, isNormalAttack, isMagicDamage, magicType, damageResult) ?? Task.CompletedTask);
} }
public delegate Task CharacterNormalAttackEventHandler(GamingQueue queue, Character actor, List<Character> targets); public delegate Task CharacterNormalAttackEventHandler(GamingQueue queue, Character actor, List<Character> targets);