mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2025-12-05 08:09:02 +00:00
底层支持真实伤害 (#141)
This commit is contained in:
parent
a2fcbce157
commit
6bf3bb09a9
@ -129,9 +129,13 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
}
|
||||
set
|
||||
{
|
||||
int past = _Level;
|
||||
_Level = Math.Min(Math.Max(1, value), GameplayEquilibriumConstant.MaxLevel);
|
||||
OnAttributeChanged();
|
||||
Recovery();
|
||||
if (past != _Level)
|
||||
{
|
||||
OnAttributeChanged();
|
||||
Recovery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -900,8 +904,8 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
{
|
||||
if (time > 0)
|
||||
{
|
||||
HP = Math.Min(MaxHP, HP + HR * time);
|
||||
MP = Math.Min(MaxMP, MP + MR * time);
|
||||
HP += HR * time;
|
||||
MP += MR * time;
|
||||
if (EP != -1) this.EP = EP;
|
||||
}
|
||||
}
|
||||
@ -915,10 +919,16 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// <param name="pastMaxMP"></param>
|
||||
public void Recovery(double pastHP, double pastMP, double pastMaxHP, double pastMaxMP)
|
||||
{
|
||||
double pHP = pastHP / pastMaxHP;
|
||||
double pMP = pastMP / pastMaxMP;
|
||||
HP = MaxHP * pHP;
|
||||
MP = MaxMP * pMP;
|
||||
if (pastHP > 0 && pastMaxHP > 0)
|
||||
{
|
||||
double pHP = pastHP / pastMaxHP;
|
||||
HP = MaxHP * pHP;
|
||||
}
|
||||
if (pastMP > 0 && pastMaxMP > 0)
|
||||
{
|
||||
double pMP = pastMP / pastMaxMP;
|
||||
MP = MaxMP * pMP;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1147,6 +1157,32 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置角色等级,并默认完全回复状态
|
||||
/// </summary>
|
||||
/// <param name="level">新的等级</param>
|
||||
/// <param name="recovery">false 为按百分比回复</param>
|
||||
public void SetLevel(int level, bool recovery = true)
|
||||
{
|
||||
if (!recovery)
|
||||
{
|
||||
double pastHP = HP;
|
||||
double pastMP = MP;
|
||||
double pastMaxHP = MaxHP;
|
||||
double pastMaxMP = MaxMP;
|
||||
int pastLevel = Level;
|
||||
Level = level;
|
||||
if (pastLevel != Level)
|
||||
{
|
||||
Recovery(pastHP, pastMP, pastMaxHP, pastMaxMP);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Level = level;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 角色升级
|
||||
/// </summary>
|
||||
|
||||
@ -218,9 +218,9 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// <param name="character"></param>
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
public virtual void AlterDamageTypeBeforeCalculation(Character character, Character enemy, ref bool isNormalAttack, ref bool isMagicDamage, ref MagicType magicType)
|
||||
public virtual void AlterDamageTypeBeforeCalculation(Character character, Character enemy, ref bool isNormalAttack, ref DamageType damageType, ref MagicType magicType)
|
||||
{
|
||||
|
||||
}
|
||||
@ -232,11 +232,11 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="totalDamageBonus"></param>
|
||||
/// <returns>返回伤害增减值</returns>
|
||||
public virtual double AlterExpectedDamageBeforeCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, Dictionary<Effect, double> totalDamageBonus)
|
||||
public virtual double AlterExpectedDamageBeforeCalculation(Character character, Character enemy, double damage, bool isNormalAttack, DamageType damageType, MagicType magicType, Dictionary<Effect, double> totalDamageBonus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -248,13 +248,13 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damageResult"></param>
|
||||
/// <param name="isEvaded"></param>
|
||||
/// <param name="totalDamageBonus"></param>
|
||||
/// <returns>返回伤害增减值</returns>
|
||||
public virtual double AlterActualDamageAfterCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult, ref bool isEvaded, Dictionary<Effect, double> totalDamageBonus)
|
||||
public virtual double AlterActualDamageAfterCalculation(Character character, Character enemy, double damage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult, ref bool isEvaded, Dictionary<Effect, double> totalDamageBonus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -335,7 +335,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对目标触发技能效果
|
||||
/// 对目标触发技能效果(局外)
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="targets"></param>
|
||||
@ -363,10 +363,10 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="actualDamage"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damageResult"></param>
|
||||
public virtual void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult)
|
||||
public virtual void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
|
||||
{
|
||||
|
||||
}
|
||||
@ -656,13 +656,13 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// </summary>
|
||||
/// <param name="character"></param>
|
||||
/// <param name="attacker"></param>
|
||||
/// <param name="isMagic"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="damageReduce"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns>返回 false 可以跳过护盾结算</returns>
|
||||
public virtual bool BeforeShieldCalculation(Character character, Character attacker, bool isMagic, MagicType magicType, double damage, ref double damageReduce, ref string message)
|
||||
public virtual bool BeforeShieldCalculation(Character character, Character attacker, DamageType damageType, MagicType magicType, double damage, ref double damageReduce, ref string message)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -672,11 +672,11 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// </summary>
|
||||
/// <param name="character"></param>
|
||||
/// <param name="attacker"></param>
|
||||
/// <param name="isMagic"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="shieldType"></param>
|
||||
public virtual void OnShieldNeutralizeDamage(Character character, Character attacker, bool isMagic, MagicType magicType, double damage, ShieldType shieldType)
|
||||
public virtual void OnShieldNeutralizeDamage(Character character, Character attacker, DamageType damageType, MagicType magicType, double damage, ShieldType shieldType)
|
||||
{
|
||||
|
||||
}
|
||||
@ -726,11 +726,11 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// <param name="actor"></param>
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagic"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <returns>false:免疫检定不通过</returns>
|
||||
public virtual bool OnDamageImmuneCheck(Character actor, Character enemy, bool isNormalAttack, bool isMagic, MagicType magicType, double damage)
|
||||
public virtual bool OnDamageImmuneCheck(Character actor, Character enemy, bool isNormalAttack, DamageType damageType, MagicType magicType, double damage)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -740,16 +740,21 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// </summary>
|
||||
/// <param name="actor"></param>
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="isMagic"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="expectedDamage"></param>
|
||||
/// <returns></returns>
|
||||
public DamageResult DamageToEnemy(Character actor, Character enemy, bool isMagic, MagicType magicType, double expectedDamage)
|
||||
public DamageResult DamageToEnemy(Character actor, Character enemy, DamageType damageType, MagicType magicType, double expectedDamage)
|
||||
{
|
||||
if (GamingQueue is null) return DamageResult.Evaded;
|
||||
int changeCount = 0;
|
||||
DamageResult result = !isMagic ? GamingQueue.CalculatePhysicalDamage(actor, enemy, false, expectedDamage, out double damage, ref changeCount) : GamingQueue.CalculateMagicalDamage(actor, enemy, false, MagicType, expectedDamage, out damage, ref changeCount);
|
||||
GamingQueue.DamageToEnemyAsync(actor, enemy, damage, false, isMagic, magicType, result);
|
||||
DamageResult result = DamageResult.Normal;
|
||||
double damage = expectedDamage;
|
||||
if (damageType != DamageType.True)
|
||||
{
|
||||
result = damageType == DamageType.Physical ? GamingQueue.CalculatePhysicalDamage(actor, enemy, false, expectedDamage, out damage, ref changeCount) : GamingQueue.CalculateMagicalDamage(actor, enemy, false, MagicType, expectedDamage, out damage, ref changeCount);
|
||||
}
|
||||
GamingQueue.DamageToEnemyAsync(actor, enemy, damage, false, damageType, magicType, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -181,7 +181,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
double expected = Damage;
|
||||
int changeCount = 0;
|
||||
DamageResult result = IsMagic ? queue.CalculateMagicalDamage(attacker, enemy, true, MagicType, expected, out double damage, ref changeCount) : queue.CalculatePhysicalDamage(attacker, enemy, true, expected, out damage, ref changeCount);
|
||||
queue.DamageToEnemyAsync(attacker, enemy, damage, true, IsMagic, MagicType, result);
|
||||
queue.DamageToEnemyAsync(attacker, enemy, damage, true, IsMagic ? DamageType.Magical : DamageType.Physical, MagicType, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,19 +5,19 @@
|
||||
public double TotalDamage { get; set; } = 0;
|
||||
public double TotalPhysicalDamage { get; set; } = 0;
|
||||
public double TotalMagicDamage { get; set; } = 0;
|
||||
public double TotalRealDamage { get; set; } = 0;
|
||||
public double TotalTrueDamage { get; set; } = 0;
|
||||
public double TotalTakenDamage { get; set; } = 0;
|
||||
public double TotalTakenPhysicalDamage { get; set; } = 0;
|
||||
public double TotalTakenMagicDamage { get; set; } = 0;
|
||||
public double TotalTakenRealDamage { get; set; } = 0;
|
||||
public double TotalTakenTrueDamage { get; set; } = 0;
|
||||
public double AvgDamage { get; set; } = 0;
|
||||
public double AvgPhysicalDamage { get; set; } = 0;
|
||||
public double AvgMagicDamage { get; set; } = 0;
|
||||
public double AvgRealDamage { get; set; } = 0;
|
||||
public double AvgTrueDamage { get; set; } = 0;
|
||||
public double AvgTakenDamage { get; set; } = 0;
|
||||
public double AvgTakenPhysicalDamage { get; set; } = 0;
|
||||
public double AvgTakenMagicDamage { get; set; } = 0;
|
||||
public double AvgTakenRealDamage { get; set; } = 0;
|
||||
public double AvgTakenTrueDamage { get; set; } = 0;
|
||||
public double TotalHeal { get; set; } = 0;
|
||||
public double AvgHeal { get; set; } = 0;
|
||||
public double TotalShield { get; set; } = 0;
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
namespace Milimoe.FunGame.Core.Entity
|
||||
{
|
||||
public class GameStatistics
|
||||
public class GameStatistics(Room Room)
|
||||
{
|
||||
public long Id => Room.Id;
|
||||
public Room Room { get; }
|
||||
public Room Room { get; } = Room;
|
||||
public DateTime RecordTime { get; set; } = DateTime.Now;
|
||||
public string Record { get; set; } = "";
|
||||
public Dictionary<User, double> DamageStats { get; set; } = new();
|
||||
public Dictionary<User, double> PhysicalDamageStats { get; } = new();
|
||||
public Dictionary<User, double> MagicDamageStats { get; } = new();
|
||||
public Dictionary<User, double> RealDamageStats { get; } = new();
|
||||
public Dictionary<User, double> DamageStats { get; set; } = [];
|
||||
public Dictionary<User, double> PhysicalDamageStats { get; } = [];
|
||||
public Dictionary<User, double> MagicDamageStats { get; } = [];
|
||||
public Dictionary<User, double> TrueDamageStats { get; } = [];
|
||||
public double AvgDamageStats
|
||||
{
|
||||
get
|
||||
@ -46,30 +46,25 @@
|
||||
return Math.Round(total / MagicDamageStats.Count, 2);
|
||||
}
|
||||
}
|
||||
public double AvgRealDamageStats
|
||||
public double AvgTrueDamageStats
|
||||
{
|
||||
get
|
||||
{
|
||||
double total = 0;
|
||||
foreach (User user in RealDamageStats.Keys)
|
||||
foreach (User user in TrueDamageStats.Keys)
|
||||
{
|
||||
total += RealDamageStats[user];
|
||||
total += TrueDamageStats[user];
|
||||
}
|
||||
return Math.Round(total / RealDamageStats.Count, 2);
|
||||
return Math.Round(total / TrueDamageStats.Count, 2);
|
||||
}
|
||||
}
|
||||
public Dictionary<User, double> KillStats { get; } = new();
|
||||
public Dictionary<User, Dictionary<User, int>> KillDetailStats { get; } = new(); // 子字典记录的是被击杀者以及被击杀次数
|
||||
public Dictionary<User, double> DeathStats { get; } = new();
|
||||
public Dictionary<User, Dictionary<User, int>> DeathDetailStats { get; } = new(); // 子字典记录的是击杀者以及击杀次数
|
||||
public Dictionary<User, long> AssistStats { get; } = new();
|
||||
public Dictionary<User, double> RatingStats { get; } = new(); // 结算后的Rating
|
||||
public Dictionary<User, double> EloStats { get; } = new(); // Elo分数变化(+/-)
|
||||
public Dictionary<User, string> RankStats { get; } = new(); // 结算后的Rank(非比赛前)
|
||||
|
||||
public GameStatistics(Room Room)
|
||||
{
|
||||
this.Room = Room;
|
||||
}
|
||||
public Dictionary<User, double> KillStats { get; } = [];
|
||||
public Dictionary<User, Dictionary<User, int>> KillDetailStats { get; } = []; // 子字典记录的是被击杀者以及被击杀次数
|
||||
public Dictionary<User, double> DeathStats { get; } = [];
|
||||
public Dictionary<User, Dictionary<User, int>> DeathDetailStats { get; } = []; // 子字典记录的是击杀者以及击杀次数
|
||||
public Dictionary<User, long> AssistStats { get; } = [];
|
||||
public Dictionary<User, double> RatingStats { get; } = []; // 结算后的Rating
|
||||
public Dictionary<User, double> EloStats { get; } = []; // Elo分数变化(+/-)
|
||||
public Dictionary<User, string> RankStats { get; } = []; // 结算后的Rank(非比赛前)
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
public Dictionary<long, double> DamageStats { get; } = [];
|
||||
public Dictionary<long, double> PhysicalDamageStats { get; } = [];
|
||||
public Dictionary<long, double> MagicDamageStats { get; } = [];
|
||||
public Dictionary<long, double> RealDamageStats { get; } = [];
|
||||
public Dictionary<long, double> TrueDamageStats { get; } = [];
|
||||
public Dictionary<long, double> AvgDamageStats
|
||||
{
|
||||
get
|
||||
@ -66,7 +66,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
return avgdamage;
|
||||
}
|
||||
}
|
||||
public Dictionary<long, double> AvgRealDamageStats
|
||||
public Dictionary<long, double> AvgTrueDamageStats
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -75,9 +75,9 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
{
|
||||
long plays = Plays[key];
|
||||
double total = 0;
|
||||
if (RealDamageStats.ContainsKey(key))
|
||||
if (TrueDamageStats.ContainsKey(key))
|
||||
{
|
||||
total = RealDamageStats.Values.Sum();
|
||||
total = TrueDamageStats.Values.Sum();
|
||||
}
|
||||
avgdamage.Add(key, Math.Round(total / plays, 2));
|
||||
}
|
||||
|
||||
@ -79,10 +79,10 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damageResult"></param>
|
||||
public Task DamageToEnemyAsync(Character actor, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage = false, MagicType magicType = MagicType.None, DamageResult damageResult = DamageResult.Normal);
|
||||
public Task DamageToEnemyAsync(Character actor, Character enemy, double damage, bool isNormalAttack, DamageType damageType = DamageType.Physical, MagicType magicType = MagicType.None, DamageResult damageResult = DamageResult.Normal);
|
||||
|
||||
/// <summary>
|
||||
/// 治疗一个目标
|
||||
@ -198,5 +198,15 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
||||
/// <param name="isPercentage">是否是百分比</param>
|
||||
/// <param name="isCheckProtected">是否使用插队保护机制</param>
|
||||
public void ChangeCharacterHardnessTime(Character character, double addValue, bool isPercentage, bool isCheckProtected);
|
||||
|
||||
/// <summary>
|
||||
/// 计算角色的数据
|
||||
/// </summary>
|
||||
/// <param name="character"></param>
|
||||
/// <param name="characterTaken"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="takenDamage"></param>
|
||||
public void CalculateCharacterDamageStatistics(Character character, Character characterTaken, double damage, DamageType damageType, double takenDamage = -1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,6 +455,16 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
||||
_ => "★"
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetDamageTypeName(DamageType damageType, MagicType magicType = MagicType.None)
|
||||
{
|
||||
return damageType switch
|
||||
{
|
||||
DamageType.Magical => GetMagicDamageName(magicType),
|
||||
DamageType.True => "真实伤害",
|
||||
_ => "物理伤害"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemSet
|
||||
|
||||
@ -312,12 +312,12 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
||||
Poison,
|
||||
|
||||
/// <summary>
|
||||
/// 燃烧,目标受到火焰伤害,持续一段时间
|
||||
/// 燃烧,目标受到伤害,持续一段时间
|
||||
/// </summary>
|
||||
Burn,
|
||||
|
||||
/// <summary>
|
||||
/// 流血,目标持续受到物理伤害
|
||||
/// 流血,目标持续受到伤害
|
||||
/// </summary>
|
||||
Bleed,
|
||||
|
||||
@ -1039,4 +1039,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
||||
Mix,
|
||||
Effect
|
||||
}
|
||||
|
||||
public enum DamageType
|
||||
{
|
||||
Physical,
|
||||
Magical,
|
||||
True
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,6 +226,11 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// </summary>
|
||||
protected bool _isGameEnd = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在回合内
|
||||
/// </summary>
|
||||
protected bool _isInRound = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
@ -537,7 +542,8 @@ namespace Milimoe.FunGame.Core.Model
|
||||
TotalTime = Calculation.Round2Digits(TotalTime + timeToReduce);
|
||||
WriteLine("时间流逝:" + timeToReduce);
|
||||
|
||||
foreach (Character character in _queue)
|
||||
Character[] characters = [.. _queue];
|
||||
foreach (Character character in characters)
|
||||
{
|
||||
// 减少所有角色的硬直时间
|
||||
_hardnessTimes[character] = Calculation.Round2Digits(_hardnessTimes[character] - timeToReduce);
|
||||
@ -635,15 +641,17 @@ namespace Milimoe.FunGame.Core.Model
|
||||
|
||||
if (effect.Durative)
|
||||
{
|
||||
effect.RemainDuration -= timeToReduce;
|
||||
if (effect.RemainDuration <= 0)
|
||||
if (effect.RemainDuration < timeToReduce)
|
||||
{
|
||||
// 移除特效前也完成剩余时间内的效果
|
||||
effect.OnTimeElapsed(character, effect.RemainDuration);
|
||||
effect.RemainDuration = 0;
|
||||
character.Effects.Remove(effect);
|
||||
effect.OnEffectLost(character);
|
||||
}
|
||||
else
|
||||
{
|
||||
effect.RemainDuration -= timeToReduce;
|
||||
effect.OnTimeElapsed(character, timeToReduce);
|
||||
}
|
||||
}
|
||||
@ -688,11 +696,13 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <returns>是否结束游戏</returns>
|
||||
public async Task<bool> ProcessTurnAsync(Character character)
|
||||
{
|
||||
_isInRound = true;
|
||||
LastRound.Actor = character;
|
||||
_roundDeaths.Clear();
|
||||
|
||||
if (!await BeforeTurnAsync(character))
|
||||
{
|
||||
_isInRound = false;
|
||||
return _isGameEnd;
|
||||
}
|
||||
|
||||
@ -723,6 +733,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
// 如果事件全程接管回合操作,需要注意触发特效
|
||||
if (!await OnTurnStartAsync(character, enemys, teammates, skills, items))
|
||||
{
|
||||
_isInRound = false;
|
||||
return _isGameEnd;
|
||||
}
|
||||
|
||||
@ -806,7 +817,9 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
else if (character.CharacterState == CharacterState.ActionRestricted)
|
||||
{
|
||||
// 行动受限,只能使用特殊物品
|
||||
// 行动受限,只能使用消耗品
|
||||
items = [.. items.Where(i => i.ItemType == ItemType.Consumable)];
|
||||
canUseItem = items.Count > 0;
|
||||
if (canUseItem)
|
||||
{
|
||||
pCastSkill = 0;
|
||||
@ -1131,7 +1144,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
decided = true;
|
||||
LastRound.Item = item;
|
||||
baseTime = skill.RealHardnessTime;
|
||||
baseTime = skill.RealHardnessTime > 0 ? skill.RealHardnessTime : 5;
|
||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
@ -1148,7 +1161,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
character.CharacterState == CharacterState.BattleRestricted)
|
||||
{
|
||||
baseTime += 5;
|
||||
WriteLine($"角色 [ {character} ] 状态为:{CharacterSet.GetCharacterState(character.CharacterState)},放弃行动将额外获得 5 {GameplayEquilibriumConstant.InGameTime}硬直时间!");
|
||||
WriteLine($"[ {character} ] {CharacterSet.GetCharacterState(character.CharacterState)},放弃行动将额外获得 5 {GameplayEquilibriumConstant.InGameTime}硬直时间!");
|
||||
}
|
||||
decided = true;
|
||||
WriteLine($"[ {character} ] 结束了回合!");
|
||||
@ -1185,6 +1198,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
|
||||
await AfterTurnAsync(character);
|
||||
|
||||
_isInRound = false;
|
||||
return _isGameEnd;
|
||||
}
|
||||
|
||||
@ -1242,6 +1256,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
await AfterTurnAsync(character);
|
||||
|
||||
WriteLine("");
|
||||
_isInRound = false;
|
||||
return _isGameEnd;
|
||||
}
|
||||
|
||||
@ -1348,10 +1363,10 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damageResult"></param>
|
||||
public async Task DamageToEnemyAsync(Character actor, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage = false, MagicType magicType = MagicType.None, DamageResult damageResult = DamageResult.Normal)
|
||||
public async Task DamageToEnemyAsync(Character actor, Character enemy, double damage, bool isNormalAttack, DamageType damageType = DamageType.Physical, MagicType magicType = MagicType.None, DamageResult damageResult = DamageResult.Normal)
|
||||
{
|
||||
// 如果敌人在结算伤害之前就已经死亡,将不会继续下去
|
||||
if (enemy.HP <= 0)
|
||||
@ -1368,169 +1383,220 @@ namespace Milimoe.FunGame.Core.Model
|
||||
|
||||
List<Character> characters = [actor, enemy];
|
||||
bool isEvaded = damageResult == DamageResult.Evaded;
|
||||
Dictionary<Effect, double> totalDamageBonus = [];
|
||||
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
List<Effect> effects = [];
|
||||
|
||||
// 真实伤害跳过伤害加成区间
|
||||
if (damageType != DamageType.True)
|
||||
{
|
||||
double damageBonus = effect.AlterActualDamageAfterCalculation(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult, ref isEvaded, totalDamageBonus);
|
||||
totalDamageBonus[effect] = damageBonus;
|
||||
if (isEvaded)
|
||||
Dictionary<Effect, double> totalDamageBonus = [];
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
damageResult = DamageResult.Evaded;
|
||||
double damageBonus = effect.AlterActualDamageAfterCalculation(actor, enemy, damage, isNormalAttack, damageType, magicType, damageResult, ref isEvaded, totalDamageBonus);
|
||||
totalDamageBonus[effect] = damageBonus;
|
||||
if (isEvaded)
|
||||
{
|
||||
damageResult = DamageResult.Evaded;
|
||||
}
|
||||
}
|
||||
damage += totalDamageBonus.Sum(kv => kv.Value);
|
||||
}
|
||||
damage += totalDamageBonus.Sum(kv => kv.Value);
|
||||
double actualDamage = damage;
|
||||
|
||||
// 闪避了就没伤害了
|
||||
if (damageResult != DamageResult.Evaded)
|
||||
{
|
||||
// 开始计算伤害免疫
|
||||
// 此变量为是否无视免疫
|
||||
bool ignore = false;
|
||||
// 技能免疫无法免疫普通攻击,但是魔法免疫和物理免疫可以
|
||||
bool isImmune = (isNormalAttack && (enemy.ImmuneType == ImmuneType.All || enemy.ImmuneType == ImmuneType.Physical || enemy.ImmuneType == ImmuneType.Magical)) ||
|
||||
(!isNormalAttack && (enemy.ImmuneType == ImmuneType.All || enemy.ImmuneType == ImmuneType.Physical || enemy.ImmuneType == ImmuneType.Magical || enemy.ImmuneType == ImmuneType.Skilled));
|
||||
if (isImmune)
|
||||
bool isImmune = false;
|
||||
// 真实伤害跳过免疫
|
||||
if (damageType != DamageType.True)
|
||||
{
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
// 此变量为是否无视免疫
|
||||
bool ignore = false;
|
||||
// 技能免疫无法免疫普通攻击,但是魔法免疫和物理免疫可以
|
||||
isImmune = (isNormalAttack && (enemy.ImmuneType == ImmuneType.All || enemy.ImmuneType == ImmuneType.Physical || enemy.ImmuneType == ImmuneType.Magical)) ||
|
||||
(!isNormalAttack && (enemy.ImmuneType == ImmuneType.All || enemy.ImmuneType == ImmuneType.Physical || enemy.ImmuneType == ImmuneType.Magical || enemy.ImmuneType == ImmuneType.Skilled));
|
||||
if (isImmune)
|
||||
{
|
||||
if (isNormalAttack)
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (actor.NormalAttack.IgnoreImmune == ImmuneType.All ||
|
||||
(!isMagicDamage && actor.NormalAttack.IgnoreImmune == ImmuneType.Physical) ||
|
||||
(isMagicDamage && actor.NormalAttack.IgnoreImmune == ImmuneType.Magical) ||
|
||||
!effect.OnDamageImmuneCheck(actor, enemy, isNormalAttack, isMagicDamage, magicType, damage))
|
||||
if (isNormalAttack)
|
||||
{
|
||||
ignore = true;
|
||||
if (actor.NormalAttack.IgnoreImmune == ImmuneType.All ||
|
||||
(damageType == DamageType.Physical && actor.NormalAttack.IgnoreImmune == ImmuneType.Physical) ||
|
||||
(damageType == DamageType.Magical && actor.NormalAttack.IgnoreImmune == ImmuneType.Magical) ||
|
||||
!effect.OnDamageImmuneCheck(actor, enemy, isNormalAttack, damageType, magicType, damage))
|
||||
{
|
||||
ignore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!effect.OnDamageImmuneCheck(actor, enemy, isNormalAttack, isMagicDamage, magicType, damage))
|
||||
else
|
||||
{
|
||||
ignore = true;
|
||||
if (!effect.OnDamageImmuneCheck(actor, enemy, isNormalAttack, damageType, magicType, damage))
|
||||
{
|
||||
ignore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ignore)
|
||||
{
|
||||
// 无视免疫
|
||||
isImmune = false;
|
||||
}
|
||||
|
||||
if (isImmune)
|
||||
{
|
||||
// 免疫
|
||||
damageResult = DamageResult.Immune;
|
||||
LastRound.IsImmune[enemy] = true;
|
||||
WriteLine($"[ {enemy} ] 免疫了此伤害!");
|
||||
actualDamage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignore)
|
||||
{
|
||||
// 无视免疫
|
||||
isImmune = false;
|
||||
}
|
||||
|
||||
if (isImmune)
|
||||
{
|
||||
// 免疫
|
||||
damageResult = DamageResult.Immune;
|
||||
LastRound.IsImmune[enemy] = true;
|
||||
WriteLine($"[ {enemy} ] 免疫了此伤害!");
|
||||
actualDamage = 0;
|
||||
}
|
||||
else
|
||||
// 继续计算伤害
|
||||
if (!isImmune)
|
||||
{
|
||||
if (damage < 0) damage = 0;
|
||||
|
||||
string damageType = isMagicDamage ? CharacterSet.GetMagicDamageName(magicType) : "物理伤害";
|
||||
|
||||
// 在护盾结算前,特效可以有自己的逻辑
|
||||
bool change = false;
|
||||
string damageTypeString = CharacterSet.GetDamageTypeName(damageType, magicType);
|
||||
string shieldMsg = "";
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
double damageReduce = 0;
|
||||
if (!effect.BeforeShieldCalculation(enemy, actor, isMagicDamage, magicType, damage, ref damageReduce, ref shieldMsg))
|
||||
{
|
||||
change = true;
|
||||
}
|
||||
if (damageReduce != 0)
|
||||
{
|
||||
actualDamage -= damageReduce;
|
||||
if (actualDamage < 0) actualDamage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查护盾
|
||||
if (!change)
|
||||
// 真实伤害跳过护盾结算
|
||||
if (damageType != DamageType.True)
|
||||
{
|
||||
double remain = actualDamage;
|
||||
|
||||
// 检查特效护盾
|
||||
effects = [.. enemy.Shield.ShieldOfEffects.Keys];
|
||||
// 在护盾结算前,特效可以有自己的逻辑
|
||||
bool change = false;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
ShieldOfEffect soe = enemy.Shield.ShieldOfEffects[effect];
|
||||
if (soe.IsMagic == isMagicDamage && (!isMagicDamage || soe.MagicType == magicType) && soe.Shield > 0)
|
||||
double damageReduce = 0;
|
||||
if (!effect.BeforeShieldCalculation(enemy, actor, damageType, magicType, damage, ref damageReduce, ref shieldMsg))
|
||||
{
|
||||
double effectShield = soe.Shield;
|
||||
// 判断护盾余额
|
||||
if (enemy.Shield.CalculateShieldOfEffect(effect, remain) > 0)
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 发动了 [ {effect.Skill.Name} ] 的护盾效果,抵消了 {remain:0.##} 点{damageType}!");
|
||||
remain = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 发动了 [ {effect.Skill.Name} ] 的护盾效果,抵消了 {effectShield:0.##} 点{damageType},护盾已破碎!");
|
||||
remain -= effectShield;
|
||||
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect2 in effects2)
|
||||
{
|
||||
if (!effect2.OnShieldBroken(enemy, actor, effect, remain))
|
||||
{
|
||||
WriteLine($"[ {(enemy.Effects.Contains(effect2) ? enemy : actor)} ] 因护盾破碎而发动了 [ {effect2.Skill.Name} ],化解了本次伤害!");
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remain <= 0)
|
||||
{
|
||||
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect2 in effects2)
|
||||
{
|
||||
effect2.OnShieldNeutralizeDamage(enemy, actor, isMagicDamage, magicType, damage, ShieldType.Effect);
|
||||
}
|
||||
break;
|
||||
}
|
||||
change = true;
|
||||
}
|
||||
if (damageReduce != 0)
|
||||
{
|
||||
actualDamage -= damageReduce;
|
||||
if (actualDamage < 0) actualDamage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果伤害仍然大于0,继续检查护盾
|
||||
if (remain > 0)
|
||||
// 检查护盾
|
||||
if (!change)
|
||||
{
|
||||
// 检查指定类型的护盾值
|
||||
double shield = enemy.Shield[isMagicDamage, magicType];
|
||||
if (shield > 0)
|
||||
double remain = actualDamage;
|
||||
|
||||
// 检查特效护盾
|
||||
effects = [.. enemy.Shield.ShieldOfEffects.Keys];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
shield -= remain;
|
||||
string shieldTypeString = isMagicDamage ? "魔法" : "物理";
|
||||
ShieldType shieldType = isMagicDamage ? ShieldType.Magical : ShieldType.Physical;
|
||||
if (shield > 0)
|
||||
ShieldOfEffect soe = enemy.Shield.ShieldOfEffects[effect];
|
||||
if (soe.IsMagic == (damageType == DamageType.Magical) && (damageType == DamageType.Physical || soe.MagicType == magicType) && soe.Shield > 0)
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的{shieldTypeString}护盾抵消了 {remain:0.##} 点{damageType}!");
|
||||
enemy.Shield[isMagicDamage, magicType] -= remain;
|
||||
remain = 0;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
double effectShield = soe.Shield;
|
||||
// 判断护盾余额
|
||||
if (enemy.Shield.CalculateShieldOfEffect(effect, remain) > 0)
|
||||
{
|
||||
effect.OnShieldNeutralizeDamage(enemy, actor, isMagicDamage, magicType, damage, shieldType);
|
||||
WriteLine($"[ {enemy} ] 发动了 [ {effect.Skill.Name} ] 的护盾效果,抵消了 {remain:0.##} 点{damageTypeString}!");
|
||||
remain = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 发动了 [ {effect.Skill.Name} ] 的护盾效果,抵消了 {effectShield:0.##} 点{damageTypeString},护盾已破碎!");
|
||||
remain -= effectShield;
|
||||
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect2 in effects2)
|
||||
{
|
||||
if (!effect2.OnShieldBroken(enemy, actor, effect, remain))
|
||||
{
|
||||
WriteLine($"[ {(enemy.Effects.Contains(effect2) ? enemy : actor)} ] 因护盾破碎而发动了 [ {effect2.Skill.Name} ],化解了本次伤害!");
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remain <= 0)
|
||||
{
|
||||
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect2 in effects2)
|
||||
{
|
||||
effect2.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, ShieldType.Effect);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
// 如果伤害仍然大于0,继续检查护盾
|
||||
if (remain > 0)
|
||||
{
|
||||
// 检查指定类型的护盾值
|
||||
bool isMagicDamage = damageType == DamageType.Magical;
|
||||
double shield = enemy.Shield[isMagicDamage, magicType];
|
||||
if (shield > 0)
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的{shieldTypeString}护盾抵消了 {enemy.Shield[isMagicDamage, magicType]:0.##} 点{damageType}并破碎!");
|
||||
remain -= enemy.Shield[isMagicDamage, magicType];
|
||||
enemy.Shield[isMagicDamage, magicType] = 0;
|
||||
if (isMagicDamage && enemy.Shield.TotalMagicial <= 0 || !isMagicDamage && enemy.Shield.TotalPhysical <= 0)
|
||||
shield -= remain;
|
||||
string shieldTypeString = isMagicDamage ? "魔法" : "物理";
|
||||
ShieldType shieldType = isMagicDamage ? ShieldType.Magical : ShieldType.Physical;
|
||||
if (shield > 0)
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的{shieldTypeString}护盾抵消了 {remain:0.##} 点{damageTypeString}!");
|
||||
enemy.Shield[isMagicDamage, magicType] -= remain;
|
||||
remain = 0;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (!effect.OnShieldBroken(enemy, actor, shieldType, remain))
|
||||
effect.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, shieldType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的{shieldTypeString}护盾抵消了 {enemy.Shield[isMagicDamage, magicType]:0.##} 点{damageTypeString}并破碎!");
|
||||
remain -= enemy.Shield[isMagicDamage, magicType];
|
||||
enemy.Shield[isMagicDamage, magicType] = 0;
|
||||
if (isMagicDamage && enemy.Shield.TotalMagicial <= 0 || !isMagicDamage && enemy.Shield.TotalPhysical <= 0)
|
||||
{
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (!effect.OnShieldBroken(enemy, actor, shieldType, remain))
|
||||
{
|
||||
WriteLine($"[ {(enemy.Effects.Contains(effect) ? enemy : actor)} ] 因护盾破碎而发动了 [ {effect.Skill.Name} ],化解了本次伤害!");
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查混合护盾
|
||||
if (remain > 0 && enemy.Shield.Mix > 0)
|
||||
{
|
||||
shield = enemy.Shield.Mix;
|
||||
shield -= remain;
|
||||
if (shield > 0)
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {remain:0.##} 点{damageTypeString}!");
|
||||
enemy.Shield.Mix -= remain;
|
||||
remain = 0;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, ShieldType.Mix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {enemy.Shield.Mix:0.##} 点{damageTypeString}并破碎!");
|
||||
remain -= enemy.Shield.Mix;
|
||||
enemy.Shield.Mix = 0;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (!effect.OnShieldBroken(enemy, actor, ShieldType.Mix, remain))
|
||||
{
|
||||
WriteLine($"[ {(enemy.Effects.Contains(effect) ? enemy : actor)} ] 因护盾破碎而发动了 [ {effect.Skill.Name} ],化解了本次伤害!");
|
||||
remain = 0;
|
||||
@ -1540,51 +1606,18 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
}
|
||||
|
||||
// 检查混合护盾
|
||||
if (remain > 0 && enemy.Shield.Mix > 0)
|
||||
{
|
||||
shield = enemy.Shield.Mix;
|
||||
shield -= remain;
|
||||
if (shield > 0)
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {remain:0.##} 点{damageType}!");
|
||||
enemy.Shield.Mix -= remain;
|
||||
remain = 0;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.OnShieldNeutralizeDamage(enemy, actor, isMagicDamage, magicType, damage, ShieldType.Mix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {enemy.Shield.Mix:0.##} 点{damageType}并破碎!");
|
||||
remain -= enemy.Shield.Mix;
|
||||
enemy.Shield.Mix = 0;
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (!effect.OnShieldBroken(enemy, actor, ShieldType.Mix, remain))
|
||||
{
|
||||
WriteLine($"[ {(enemy.Effects.Contains(effect) ? enemy : actor)} ] 因护盾破碎而发动了 [ {effect.Skill.Name} ],化解了本次伤害!");
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
actualDamage = remain;
|
||||
}
|
||||
|
||||
actualDamage = remain;
|
||||
}
|
||||
|
||||
// 统计护盾
|
||||
if (damage > actualDamage && _stats.TryGetValue(actor, out CharacterStatistics? stats) && stats != null)
|
||||
{
|
||||
stats.TotalShield += damage - actualDamage;
|
||||
// 统计护盾
|
||||
if (damage > actualDamage && _stats.TryGetValue(actor, out CharacterStatistics? stats) && stats != null)
|
||||
{
|
||||
stats.TotalShield += damage - actualDamage;
|
||||
}
|
||||
}
|
||||
|
||||
enemy.HP -= actualDamage;
|
||||
WriteLine($"[ {enemy} ] 受到了 {actualDamage:0.##} 点{damageType}!{shieldMsg}");
|
||||
WriteLine($"[ {enemy} ] 受到了 {actualDamage:0.##} 点{damageTypeString}!{shieldMsg}");
|
||||
|
||||
// 生命偷取,攻击者为全额
|
||||
double steal = damage * actor.Lifesteal;
|
||||
@ -1618,7 +1651,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
|
||||
// 统计伤害
|
||||
CalculateCharacterDamageStatistics(actor, enemy, damage, isMagicDamage, actualDamage);
|
||||
CalculateCharacterDamageStatistics(actor, enemy, damage, damageType, actualDamage);
|
||||
|
||||
// 计算助攻
|
||||
_assistDetail[actor][enemy, TotalTime] += damage;
|
||||
@ -1630,12 +1663,12 @@ namespace Milimoe.FunGame.Core.Model
|
||||
actualDamage = 0;
|
||||
}
|
||||
|
||||
await OnDamageToEnemyAsync(actor, enemy, damage, actualDamage, isNormalAttack, isMagicDamage, magicType, damageResult);
|
||||
await OnDamageToEnemyAsync(actor, enemy, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult);
|
||||
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.AfterDamageCalculation(actor, enemy, damage, actualDamage, isNormalAttack, isMagicDamage, magicType, damageResult);
|
||||
effect.AfterDamageCalculation(actor, enemy, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult);
|
||||
}
|
||||
|
||||
if (enemy.HP <= 0 && !_eliminated.Contains(enemy) && !_respawnCountdown.ContainsKey(enemy))
|
||||
@ -1680,8 +1713,14 @@ namespace Milimoe.FunGame.Core.Model
|
||||
return;
|
||||
}
|
||||
|
||||
double realHeal = heal;
|
||||
if (target.HP > 0 || (isDead && canRespawn))
|
||||
{
|
||||
// 用于数据统计,不能是全额,溢出的部分需要扣除
|
||||
if (target.HP + heal > target.MaxHP)
|
||||
{
|
||||
realHeal = target.MaxHP - target.HP;
|
||||
}
|
||||
target.HP += heal;
|
||||
if (!LastRound.Heals.TryAdd(target, heal))
|
||||
{
|
||||
@ -1717,7 +1756,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
// 统计数据
|
||||
if (_stats.TryGetValue(actor, out CharacterStatistics? stats) && stats != null)
|
||||
{
|
||||
stats.TotalHeal += heal;
|
||||
stats.TotalHeal += realHeal;
|
||||
}
|
||||
|
||||
await OnHealToTargetAsync(actor, target, heal, isRespawn);
|
||||
@ -1928,8 +1967,8 @@ namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
caster.CharacterState = CharacterState.Actionable;
|
||||
}
|
||||
WriteLine($"[ {caster} ] 终止了 [ {st.Skill.Name} ] 的施法" + (_hardnessTimes[caster] > 3 ? $",并获得了 3 {GameplayEquilibriumConstant.InGameTime}的硬直时间的补偿。" : "。"));
|
||||
if (_hardnessTimes[caster] > 3)
|
||||
WriteLine($"[ {caster} ] 终止了 [ {st.Skill.Name} ] 的施法" + (_hardnessTimes[caster] > 3 && _isInRound ? $",并获得了 3 {GameplayEquilibriumConstant.InGameTime}的硬直时间的补偿。" : "。"));
|
||||
if (_hardnessTimes[caster] > 3 && _isInRound)
|
||||
{
|
||||
AddCharacter(caster, 3, false);
|
||||
}
|
||||
@ -1966,16 +2005,21 @@ namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
LastRound.Targets = [.. targets];
|
||||
|
||||
WriteLine($"[ {character} ] 使用了物品 [ {item.Name} ]!");
|
||||
item.ReduceTimesAndRemove();
|
||||
if (item.IsReduceTimesAfterUse && item.RemainUseTimes == 0)
|
||||
{
|
||||
character.Items.Remove(item);
|
||||
}
|
||||
await OnCharacterUseItemAsync(character, item, targets);
|
||||
|
||||
string line = $"[ {character} ] 使用了物品 [ {item.Name} ]!\r\n[ {character} ] ";
|
||||
|
||||
skill.OnSkillCasting(this, character, targets);
|
||||
skill.BeforeSkillCasted();
|
||||
|
||||
skill.CurrentCD = skill.RealCD;
|
||||
skill.Enable = false;
|
||||
|
||||
string line = $"[ {character} ] ";
|
||||
if (costMP > 0)
|
||||
{
|
||||
character.MP -= costMP;
|
||||
@ -2017,7 +2061,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
if (pUseItem == 0 && pCastSkill == 0 && pNormalAttack == 0)
|
||||
{
|
||||
return CharacterActionType.None;
|
||||
return CharacterActionType.EndTurn;
|
||||
}
|
||||
|
||||
double total = pUseItem + pCastSkill + pNormalAttack;
|
||||
@ -2048,7 +2092,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
return CharacterActionType.NormalAttack;
|
||||
}
|
||||
|
||||
return CharacterActionType.None;
|
||||
return CharacterActionType.EndTurn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -2113,7 +2157,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
if (skill.SkillType == SkillType.Magic)
|
||||
{
|
||||
cost = skill.RealMPCost;
|
||||
if (cost > 0 && cost <= caster.MP)
|
||||
if (cost >= 0 && cost <= caster.MP)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -2125,7 +2169,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
else
|
||||
{
|
||||
cost = skill.RealEPCost;
|
||||
if (cost > 0 && cost <= caster.EP)
|
||||
if (cost >= 0 && cost <= caster.EP)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -2158,7 +2202,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
costEP = skill.RealEPCost;
|
||||
bool isMPOk = false;
|
||||
bool isEPOk = false;
|
||||
if (costMP > 0 && costMP <= caster.MP)
|
||||
if (costMP >= 0 && costMP <= caster.MP)
|
||||
{
|
||||
isMPOk = true;
|
||||
}
|
||||
@ -2167,7 +2211,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
WriteLine("[ " + caster + $" ] 魔法不足!");
|
||||
}
|
||||
costEP = skill.RealEPCost;
|
||||
if (costEP > 0 && costEP <= caster.EP)
|
||||
if (costEP >= 0 && costEP <= caster.EP)
|
||||
{
|
||||
isEPOk = true;
|
||||
}
|
||||
@ -2191,16 +2235,16 @@ namespace Milimoe.FunGame.Core.Model
|
||||
public DamageResult CalculatePhysicalDamage(Character actor, Character enemy, bool isNormalAttack, double expectedDamage, out double finalDamage, ref int changeCount)
|
||||
{
|
||||
List<Character> characters = [actor, enemy];
|
||||
bool isMagic = false;
|
||||
DamageType damageType = DamageType.Physical;
|
||||
MagicType magicType = MagicType.None;
|
||||
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
if (changeCount < 3)
|
||||
{
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref isMagic, ref magicType);
|
||||
effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref damageType, ref magicType);
|
||||
}
|
||||
if (isMagic)
|
||||
if (damageType == DamageType.Magical)
|
||||
{
|
||||
changeCount++;
|
||||
return CalculateMagicalDamage(actor, enemy, isNormalAttack, magicType, expectedDamage, out finalDamage, ref changeCount);
|
||||
@ -2211,7 +2255,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
effects = [.. actor.Effects.Union(enemy.Effects).Distinct().Where(e => e.IsInEffect)];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, false, MagicType.None, totalDamageBonus);
|
||||
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, DamageType.Physical, MagicType.None, totalDamageBonus);
|
||||
totalDamageBonus[effect] = damageBonus;
|
||||
}
|
||||
expectedDamage += totalDamageBonus.Sum(kv => kv.Value);
|
||||
@ -2308,15 +2352,15 @@ namespace Milimoe.FunGame.Core.Model
|
||||
public DamageResult CalculateMagicalDamage(Character actor, Character enemy, bool isNormalAttack, MagicType magicType, double expectedDamage, out double finalDamage, ref int changeCount)
|
||||
{
|
||||
List<Character> characters = [actor, enemy];
|
||||
bool isMagic = true;
|
||||
DamageType damageType = DamageType.Magical;
|
||||
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
if (changeCount < 3)
|
||||
{
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref isMagic, ref magicType);
|
||||
effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref damageType, ref magicType);
|
||||
}
|
||||
if (!isMagic)
|
||||
if (damageType == DamageType.Physical)
|
||||
{
|
||||
changeCount++;
|
||||
return CalculatePhysicalDamage(actor, enemy, isNormalAttack, expectedDamage, out finalDamage, ref changeCount);
|
||||
@ -2327,7 +2371,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, true, magicType, totalDamageBonus);
|
||||
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, DamageType.Magical, magicType, totalDamageBonus);
|
||||
totalDamageBonus[effect] = damageBonus;
|
||||
}
|
||||
expectedDamage += totalDamageBonus.Sum(kv => kv.Value);
|
||||
@ -2812,12 +2856,16 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <summary>
|
||||
/// 计算角色的数据
|
||||
/// </summary>
|
||||
public void CalculateCharacterDamageStatistics(Character character, Character characterTaken, double damage, bool isMagic, double takenDamage = -1)
|
||||
public void CalculateCharacterDamageStatistics(Character character, Character characterTaken, double damage, DamageType damageType, double takenDamage = -1)
|
||||
{
|
||||
if (takenDamage == -1) takenDamage = damage;
|
||||
if (_stats.TryGetValue(character, out CharacterStatistics? stats) && stats != null)
|
||||
{
|
||||
if (isMagic)
|
||||
if (damageType == DamageType.True)
|
||||
{
|
||||
stats.TotalTrueDamage += damage;
|
||||
}
|
||||
if (damageType == DamageType.Magical)
|
||||
{
|
||||
stats.TotalMagicDamage += damage;
|
||||
}
|
||||
@ -2829,7 +2877,11 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
if (_stats.TryGetValue(characterTaken, out CharacterStatistics? statsTaken) && statsTaken != null)
|
||||
{
|
||||
if (isMagic)
|
||||
if (damageType == DamageType.True)
|
||||
{
|
||||
statsTaken.TotalTakenTrueDamage = Calculation.Round2Digits(statsTaken.TotalTakenTrueDamage + takenDamage);
|
||||
}
|
||||
if (damageType == DamageType.Magical)
|
||||
{
|
||||
statsTaken.TotalTakenMagicDamage = Calculation.Round2Digits(statsTaken.TotalTakenMagicDamage + takenDamage);
|
||||
}
|
||||
@ -3090,7 +3142,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
await (HealToTarget?.Invoke(this, actor, target, heal, isRespawn) ?? Task.CompletedTask);
|
||||
}
|
||||
|
||||
public delegate Task DamageToEnemyEventHandler(GamingQueue queue, Character actor, Character enemy, double damage, double actualDamage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult);
|
||||
public delegate Task DamageToEnemyEventHandler(GamingQueue queue, Character actor, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult);
|
||||
/// <summary>
|
||||
/// 造成伤害事件
|
||||
/// </summary>
|
||||
@ -3103,13 +3155,13 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="damage"></param>
|
||||
/// <param name="actualDamage"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="isMagicDamage"></param>
|
||||
/// <param name="damageType"></param>
|
||||
/// <param name="magicType"></param>
|
||||
/// <param name="damageResult"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task OnDamageToEnemyAsync(Character actor, Character enemy, double damage, double actualDamage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult)
|
||||
protected async Task OnDamageToEnemyAsync(Character actor, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
|
||||
{
|
||||
await (DamageToEnemy?.Invoke(this, actor, enemy, damage, actualDamage, isNormalAttack, isMagicDamage, magicType, damageResult) ?? Task.CompletedTask);
|
||||
await (DamageToEnemy?.Invoke(this, actor, enemy, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult) ?? Task.CompletedTask);
|
||||
}
|
||||
|
||||
public delegate Task CharacterNormalAttackEventHandler(GamingQueue queue, Character actor, List<Character> targets);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user