特效添加是否生效和显示在状态栏的属性

This commit is contained in:
milimoe 2025-04-26 16:20:44 +08:00
parent 769d0e4281
commit 0c24d27d19
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
6 changed files with 113 additions and 73 deletions

View File

@ -1208,7 +1208,7 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public void OnAttributeChanged() public void OnAttributeChanged()
{ {
List<Effect> effects = [.. Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; List<Effect> effects = [.. Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnAttributeChanged(this); effect.OnAttributeChanged(this);
@ -1448,10 +1448,11 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
foreach (Effect effect in Effects.Where(e => e.EffectType != EffectType.Item)) foreach (Effect effect in effects)
{ {
builder.Append(effect.ToString()); builder.Append(effect.ToString());
} }
@ -1560,10 +1561,11 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine(string.Join("", types.Select(ItemSet.GetEquipSlotTypeName))); builder.AppendLine(string.Join("", types.Select(ItemSet.GetEquipSlotTypeName)));
} }
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
builder.Append(string.Join("", Effects.Where(e => e.EffectType != EffectType.Item).Select(e => e.Name))); builder.Append(string.Join("", effects.Select(e => e.Name)));
} }
} }
@ -1609,10 +1611,11 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}"); builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
foreach (Effect effect in Effects.Where(e => e.EffectType != EffectType.Item)) foreach (Effect effect in effects)
{ {
builder.Append(effect.ToString()); builder.Append(effect.ToString());
} }
@ -1644,10 +1647,11 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}" + (ExPrimaryAttributeValue != 0 ? $" [{BasePrimaryAttributeValue:0.##} {(ExPrimaryAttributeValue >= 0 ? "+" : "-")} {Math.Abs(ExPrimaryAttributeValue):0.##}]" : "")); builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}" + (ExPrimaryAttributeValue != 0 ? $" [{BasePrimaryAttributeValue:0.##} {(ExPrimaryAttributeValue >= 0 ? "+" : "-")} {Math.Abs(ExPrimaryAttributeValue):0.##}]" : ""));
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}"); builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
builder.Append(string.Join("", Effects.Where(e => e.EffectType != EffectType.Item).Select(e => e.Name))); builder.Append(string.Join("", effects.Select(e => e.Name)));
} }
return builder.ToString(); return builder.ToString();
@ -1690,10 +1694,11 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
foreach (Effect effect in Effects.Where(e => e.EffectType != EffectType.Item)) foreach (Effect effect in effects)
{ {
builder.Append(effect.ToString()); builder.Append(effect.ToString());
} }

View File

@ -148,10 +148,11 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
foreach (Effect effect in Effects.Where(e => e.EffectType != EffectType.Item)) foreach (Effect effect in effects)
{ {
builder.Append(effect.ToString()); builder.Append(effect.ToString());
} }
@ -249,10 +250,11 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine(string.Join("", types.Select(ItemSet.GetEquipSlotTypeName))); builder.AppendLine(string.Join("", types.Select(ItemSet.GetEquipSlotTypeName)));
} }
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
builder.Append(string.Join("", Effects.Where(e => e.EffectType != EffectType.Item).Select(e => e.Name))); builder.Append(string.Join("", effects.Select(e => e.Name)));
} }
} }
@ -301,10 +303,11 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}"); builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
foreach (Effect effect in Effects.Where(e => e.EffectType != EffectType.Item)) foreach (Effect effect in effects)
{ {
builder.Append(effect.ToString()); builder.Append(effect.ToString());
} }
@ -331,10 +334,11 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : "")); builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}"); builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
builder.Append(string.Join("", Effects.Where(e => e.EffectType != EffectType.Item).Select(e => e.Name))); builder.Append(string.Join("", effects.Select(e => e.Name)));
} }
return builder.ToString(); return builder.ToString();
@ -377,10 +381,11 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
if (Effects.Where(e => e.EffectType != EffectType.Item).Any()) Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
if (effects.Length > 0)
{ {
builder.AppendLine("== 状态栏 =="); builder.AppendLine("== 状态栏 ==");
foreach (Effect effect in Effects.Where(e => e.EffectType != EffectType.Item)) foreach (Effect effect in effects)
{ {
builder.Append(effect.ToString()); builder.Append(effect.ToString());
} }

View File

@ -55,6 +55,16 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public virtual bool DurativeWithoutDuration { get; set; } = false; public virtual bool DurativeWithoutDuration { get; set; } = false;
/// <summary>
/// 是否显示在状态栏
/// </summary>
public bool ShowInStatusBar => Skill.Item is null || (Durative && Duration > 0) || DurationTurn > 0 || DurativeWithoutDuration;
/// <summary>
/// 特效是否生效
/// </summary>
public bool IsInEffect => Level > 0 && !IsBeingTemporaryDispelled;
/// <summary> /// <summary>
/// 魔法类型 /// 魔法类型
/// </summary> /// </summary>
@ -908,7 +918,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
return; return;
} }
Effect[] effects = [.. target.Effects.Where(e => e.Level > 0 && EffectType != EffectType.Item && !e.IsBeingTemporaryDispelled)]; Effect[] effects = [.. target.Effects.Where(e => e.IsInEffect && e.ShowInStatusBar)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
if (effect.OnEffectIsBeingDispelled(dispeller, target, this, isEnemy)) if (effect.OnEffectIsBeingDispelled(dispeller, target, this, isEnemy))
@ -972,7 +982,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 复制一个特效 /// 复制一个特效
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public Effect Copy(Skill skill) public Effect Copy(Skill skill, bool copyByCode = false)
{ {
Dictionary<string, object> args = new() Dictionary<string, object> args = new()
{ {
@ -980,21 +990,24 @@ namespace Milimoe.FunGame.Core.Entity
{ "values", Values } { "values", Values }
}; };
Effect copy = Factory.OpenFactory.GetInstance<Effect>(Id, Name, args); Effect copy = Factory.OpenFactory.GetInstance<Effect>(Id, Name, args);
copy.Id = Id; if (!copyByCode)
copy.Name = Name; {
copy.Description = Description; copy.Id = Id;
copy.DispelDescription = DispelDescription; copy.Name = Name;
copy.EffectType = EffectType; copy.Description = Description;
copy.DispelType = DispelType; copy.DispelDescription = DispelDescription;
copy.DispelledType = DispelledType; copy.EffectType = EffectType;
copy.IsDebuff = IsDebuff; copy.DispelType = DispelType;
copy.IgnoreImmune = IgnoreImmune; copy.DispelledType = DispelledType;
copy.DurativeWithoutDuration = DurativeWithoutDuration; copy.IsDebuff = IsDebuff;
copy.IgnoreImmune = IgnoreImmune;
copy.DurativeWithoutDuration = DurativeWithoutDuration;
copy.MagicType = MagicType;
copy.GamingQueue = GamingQueue;
}
copy.Durative = Durative; copy.Durative = Durative;
copy.Duration = Duration; copy.Duration = Duration;
copy.DurationTurn = DurationTurn; copy.DurationTurn = DurationTurn;
copy.MagicType = MagicType;
copy.GamingQueue = GamingQueue;
return copy; return copy;
} }

View File

@ -544,7 +544,12 @@ namespace Milimoe.FunGame.Core.Entity
{ {
foreach (Effect e in skillDefined.Effects) foreach (Effect e in skillDefined.Effects)
{ {
Effect neweffect = e.Copy(skill); // 特效没法动态扩展,必须使用编程钩子实现,因此动态扩展的技能需要使用代码定义的特效
Effect neweffect = e.Copy(skill, true);
if (skill.GamingQueue != null)
{
neweffect.GamingQueue = skill.GamingQueue;
}
skill.Effects.Add(neweffect); skill.Effects.Add(neweffect);
} }
} }

View File

@ -21,6 +21,15 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Effect.Name): case nameof(Effect.Name):
result.Name = reader.GetString() ?? ""; result.Name = reader.GetString() ?? "";
break; break;
case nameof(Effect.Durative):
result.Durative = reader.GetBoolean();
break;
case nameof(Effect.Duration):
result.Duration = reader.GetDouble();
break;
case nameof(Effect.DurationTurn):
result.DurationTurn = reader.GetInt32();
break;
default: default:
if (reader.TokenType == JsonTokenType.Number) if (reader.TokenType == JsonTokenType.Number)
{ {
@ -42,8 +51,11 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
{ {
writer.WriteStartObject(); writer.WriteStartObject();
writer.WriteNumber(nameof(Effect.Id), (int)value.Id); writer.WriteNumber(nameof(Effect.Id), value.Id);
writer.WriteString(nameof(Effect.Name), value.Name); writer.WriteString(nameof(Effect.Name), value.Name);
writer.WriteBoolean(nameof(Effect.Durative), value.Durative);
writer.WriteNumber(nameof(Effect.Duration), value.Duration);
writer.WriteNumber(nameof(Effect.DurationTurn), value.DurationTurn);
foreach (var kvp in value.Values) foreach (var kvp in value.Values)
{ {

View File

@ -639,7 +639,7 @@ namespace Milimoe.FunGame.Core.Model
skillTurnStart.OnTurnStart(character, enemys, teammates, skills, items); skillTurnStart.OnTurnStart(character, enemys, teammates, skills, items);
} }
List<Effect> effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnTurnStart(character, enemys, teammates, skills, items); effect.OnTurnStart(character, enemys, teammates, skills, items);
@ -675,7 +675,7 @@ namespace Milimoe.FunGame.Core.Model
if (character.CharacterState != CharacterState.Casting && character.CharacterState != CharacterState.PreCastSuperSkill) if (character.CharacterState != CharacterState.Casting && character.CharacterState != CharacterState.PreCastSuperSkill)
{ {
CharacterActionType actionTypeTemp = CharacterActionType.None; CharacterActionType actionTypeTemp = CharacterActionType.None;
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
actionTypeTemp = effect.AlterActionTypeBeforeAction(character, character.CharacterState, ref canUseItem, ref canCastSkill, ref pUseItem, ref pCastSkill, ref pNormalAttack); actionTypeTemp = effect.AlterActionTypeBeforeAction(character, character.CharacterState, ref canUseItem, ref canCastSkill, ref pUseItem, ref pCastSkill, ref pNormalAttack);
@ -798,7 +798,7 @@ namespace Milimoe.FunGame.Core.Model
Dictionary<Character, int> continuousKillingTemp = new(_continuousKilling); Dictionary<Character, int> continuousKillingTemp = new(_continuousKilling);
Dictionary<Character, int> earnedMoneyTemp = new(_earnedMoney); Dictionary<Character, int> earnedMoneyTemp = new(_earnedMoney);
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterSelectListBeforeAction(character, enemys, teammates, skills, continuousKillingTemp, earnedMoneyTemp); effect.AlterSelectListBeforeAction(character, enemys, teammates, skills, continuousKillingTemp, earnedMoneyTemp);
@ -834,7 +834,7 @@ namespace Milimoe.FunGame.Core.Model
character.NormalAttack.Attack(this, character, targets); character.NormalAttack.Attack(this, character, targets);
baseTime = character.NormalAttack.RealHardnessTime; baseTime = character.NormalAttack.RealHardnessTime;
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterHardnessTimeAfterNormalAttack(character, ref baseTime, ref isCheckProtected); effect.AlterHardnessTimeAfterNormalAttack(character, ref baseTime, ref isCheckProtected);
@ -918,7 +918,7 @@ namespace Milimoe.FunGame.Core.Model
await OnCharacterCastSkillAsync(character, skillTarget, cost); await OnCharacterCastSkillAsync(character, skillTarget, cost);
skill.OnSkillCasted(this, character, targets); skill.OnSkillCasted(this, character, targets);
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected); effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
@ -974,7 +974,7 @@ namespace Milimoe.FunGame.Core.Model
baseTime = 3; baseTime = 3;
} }
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected); effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
@ -1027,7 +1027,7 @@ namespace Milimoe.FunGame.Core.Model
baseTime = 3; baseTime = 3;
} }
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected); effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
@ -1050,7 +1050,7 @@ namespace Milimoe.FunGame.Core.Model
decided = true; decided = true;
LastRound.Item = item; LastRound.Item = item;
baseTime = skill.RealHardnessTime; baseTime = skill.RealHardnessTime;
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected); effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
@ -1119,7 +1119,7 @@ namespace Milimoe.FunGame.Core.Model
await OnQueueUpdatedAsync(_queue, character, newHardnessTime, QueueUpdatedReason.Action, "设置角色行动后的硬直时间。"); await OnQueueUpdatedAsync(_queue, character, newHardnessTime, QueueUpdatedReason.Action, "设置角色行动后的硬直时间。");
LastRound.HardnessTime = newHardnessTime; LastRound.HardnessTime = newHardnessTime;
effects = [.. character.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnTurnEnd(character); effect.OnTurnEnd(character);
@ -1333,7 +1333,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;
Dictionary<Effect, double> totalDamageBonus = []; Dictionary<Effect, double> totalDamageBonus = [];
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
double damageBonus = effect.AlterActualDamageAfterCalculation(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult, ref isEvaded, totalDamageBonus); double damageBonus = effect.AlterActualDamageAfterCalculation(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult, ref isEvaded, totalDamageBonus);
@ -1355,7 +1355,7 @@ namespace Milimoe.FunGame.Core.Model
(!isNormalAttack && (enemy.ImmuneType == ImmuneType.All || enemy.ImmuneType == ImmuneType.Physical || enemy.ImmuneType == ImmuneType.Magical || enemy.ImmuneType == ImmuneType.Skilled)); (!isNormalAttack && (enemy.ImmuneType == ImmuneType.All || enemy.ImmuneType == ImmuneType.Physical || enemy.ImmuneType == ImmuneType.Magical || enemy.ImmuneType == ImmuneType.Skilled));
if (isImmune) if (isImmune)
{ {
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
if (isNormalAttack) if (isNormalAttack)
@ -1402,7 +1402,7 @@ namespace Milimoe.FunGame.Core.Model
bool change = false; bool change = false;
// 看特效有没有特殊护盾逻辑 // 看特效有没有特殊护盾逻辑
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
if (!effect.BeforeShieldCalculation(actor, enemy, isMagicDamage, magicType, damage, shield, ref shieldMsg)) if (!effect.BeforeShieldCalculation(actor, enemy, isMagicDamage, magicType, damage, shield, ref shieldMsg))
@ -1420,7 +1420,7 @@ namespace Milimoe.FunGame.Core.Model
enemy.Shield[isMagicDamage, magicType] = 0; enemy.Shield[isMagicDamage, magicType] = 0;
change = false; change = false;
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
if (!effect.OnShieldBroken(actor, enemy, isMagicDamage, magicType, damage, shield, remain)) if (!effect.OnShieldBroken(actor, enemy, isMagicDamage, magicType, damage, shield, remain))
@ -1462,7 +1462,7 @@ namespace Milimoe.FunGame.Core.Model
// 生命偷取 // 生命偷取
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.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AfterLifesteal(actor, enemy, damage, steal); effect.AfterLifesteal(actor, enemy, damage, steal);
@ -1470,14 +1470,14 @@ namespace Milimoe.FunGame.Core.Model
// 造成伤害和受伤都可以获得能量 // 造成伤害和受伤都可以获得能量
double ep = GetEP(damage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax); double ep = GetEP(damage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax);
effects = [.. actor.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. actor.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
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(damage, GameplayEquilibriumConstant.TakenDamageGetEPFactor, GameplayEquilibriumConstant.TakenDamageGetEPMax);
effects = [.. enemy.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. enemy.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterEPAfterGetDamage(enemy, ref ep); effect.AlterEPAfterGetDamage(enemy, ref ep);
@ -1498,7 +1498,7 @@ namespace Milimoe.FunGame.Core.Model
await OnDamageToEnemyAsync(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult); await OnDamageToEnemyAsync(actor, enemy, damage, isNormalAttack, isMagicDamage, magicType, damageResult);
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).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, isNormalAttack, isMagicDamage, magicType, damageResult);
@ -1529,7 +1529,7 @@ namespace Milimoe.FunGame.Core.Model
bool isDead = target.HP <= 0; bool isDead = target.HP <= 0;
Dictionary<Effect, double> totalHealBonus = []; Dictionary<Effect, double> totalHealBonus = [];
List<Effect> effects = [.. actor.Effects.Union(target.Effects).Distinct().Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; List<Effect> effects = [.. actor.Effects.Union(target.Effects).Distinct().Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
bool changeCanRespawn = false; bool changeCanRespawn = false;
@ -1611,7 +1611,7 @@ namespace Milimoe.FunGame.Core.Model
List<Character> characters = [actor, enemy]; List<Character> characters = [actor, enemy];
bool isMagic = false; bool isMagic = false;
MagicType magicType = MagicType.None; MagicType magicType = MagicType.None;
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
if (changeCount < 3) if (changeCount < 3)
{ {
foreach (Effect effect in effects) foreach (Effect effect in effects)
@ -1626,7 +1626,7 @@ namespace Milimoe.FunGame.Core.Model
} }
Dictionary<Effect, double> totalDamageBonus = []; Dictionary<Effect, double> totalDamageBonus = [];
effects = [.. actor.Effects.Union(enemy.Effects).Distinct().Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; effects = [.. actor.Effects.Union(enemy.Effects).Distinct().Where(e => e.IsInEffect)];
foreach (Effect effect in effects) 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, false, MagicType.None, totalDamageBonus);
@ -1640,7 +1640,7 @@ namespace Milimoe.FunGame.Core.Model
bool checkCritical = true; bool checkCritical = true;
if (isNormalAttack) if (isNormalAttack)
{ {
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
checkEvade = effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus); checkEvade = effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus);
@ -1653,7 +1653,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
finalDamage = 0; finalDamage = 0;
bool isAlterEvaded = false; bool isAlterEvaded = false;
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
if (effect.OnEvadedTriggered(actor, enemy, dice)) if (effect.OnEvadedTriggered(actor, enemy, dice))
@ -1680,7 +1680,7 @@ namespace Milimoe.FunGame.Core.Model
finalDamage = expectedDamage * (1 - Calculation.PercentageCheck(physicalDamageReduction + enemy.ExPDR)); finalDamage = expectedDamage * (1 - Calculation.PercentageCheck(physicalDamageReduction + enemy.ExPDR));
// 暴击检定 // 暴击检定
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
checkCritical = effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus); checkCritical = effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus);
@ -1693,7 +1693,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
finalDamage *= actor.CritDMG; // 暴击伤害倍率加成 finalDamage *= actor.CritDMG; // 暴击伤害倍率加成
WriteLine("暴击生效!!"); WriteLine("暴击生效!!");
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnCriticalDamageTriggered(actor, enemy, dice); effect.OnCriticalDamageTriggered(actor, enemy, dice);
@ -1721,7 +1721,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
List<Character> characters = [actor, enemy]; List<Character> characters = [actor, enemy];
bool isMagic = true; bool isMagic = true;
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
if (changeCount < 3) if (changeCount < 3)
{ {
foreach (Effect effect in effects) foreach (Effect effect in effects)
@ -1736,7 +1736,7 @@ namespace Milimoe.FunGame.Core.Model
} }
Dictionary<Effect, double> totalDamageBonus = []; Dictionary<Effect, double> totalDamageBonus = [];
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, true, magicType, totalDamageBonus); double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, true, magicType, totalDamageBonus);
@ -1750,7 +1750,7 @@ namespace Milimoe.FunGame.Core.Model
bool checkCritical = true; bool checkCritical = true;
if (isNormalAttack) if (isNormalAttack)
{ {
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
checkEvade = effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus); checkEvade = effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus);
@ -1763,7 +1763,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
finalDamage = 0; finalDamage = 0;
bool isAlterEvaded = false; bool isAlterEvaded = false;
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
if (effect.OnEvadedTriggered(actor, enemy, dice)) if (effect.OnEvadedTriggered(actor, enemy, dice))
@ -1789,7 +1789,7 @@ namespace Milimoe.FunGame.Core.Model
finalDamage = expectedDamage * (1 - MDF); finalDamage = expectedDamage * (1 - MDF);
// 暴击检定 // 暴击检定
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
checkCritical = effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus); checkCritical = effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus);
@ -1802,7 +1802,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
finalDamage *= actor.CritDMG; // 暴击伤害倍率加成 finalDamage *= actor.CritDMG; // 暴击伤害倍率加成
WriteLine("暴击生效!!"); WriteLine("暴击生效!!");
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnCriticalDamageTriggered(actor, enemy, dice); effect.OnCriticalDamageTriggered(actor, enemy, dice);
@ -1829,7 +1829,7 @@ namespace Milimoe.FunGame.Core.Model
} }
// 给所有角色的特效广播角色死亡结算 // 给所有角色的特效广播角色死亡结算
List<Effect> effects = [.. _queue.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled))]; List<Effect> effects = [.. _queue.SelectMany(c => c.Effects.Where(e => e.IsInEffect))];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AfterDeathCalculation(death, character, _continuousKilling, _earnedMoney); effect.AfterDeathCalculation(death, character, _continuousKilling, _earnedMoney);
@ -2339,7 +2339,7 @@ namespace Milimoe.FunGame.Core.Model
if (skill != null) if (skill != null)
{ {
WriteLine($"[ {caster} ] 的施法被 [ {interrupter} ] 打断了!!"); WriteLine($"[ {caster} ] 的施法被 [ {interrupter} ] 打断了!!");
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnSkillCastInterrupted(caster, skill, interrupter); effect.OnSkillCastInterrupted(caster, skill, interrupter);
@ -2361,7 +2361,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
Skill skill = skillTarget.Skill; Skill skill = skillTarget.Skill;
WriteLine($"[ {interrupter} ] 打断了 [ {caster} ] 的施法!!"); WriteLine($"[ {interrupter} ] 打断了 [ {caster} ] 的施法!!");
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)]; List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.OnSkillCastInterrupted(caster, skill, interrupter); effect.OnSkillCastInterrupted(caster, skill, interrupter);
@ -2781,7 +2781,7 @@ namespace Milimoe.FunGame.Core.Model
/// <returns></returns> /// <returns></returns>
public virtual async Task<List<Character>> SelectTargetsAsync(Character caster, Skill skill, List<Character> enemys, List<Character> teammates) public virtual async Task<List<Character>> SelectTargetsAsync(Character caster, Skill skill, List<Character> enemys, List<Character> teammates)
{ {
List<Effect> effects = [.. caster.Effects.Where(e => e.Level > 0)]; List<Effect> effects = [.. caster.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterSelectListBeforeSelection(caster, skill, enemys, teammates); effect.AlterSelectListBeforeSelection(caster, skill, enemys, teammates);
@ -2804,7 +2804,7 @@ namespace Milimoe.FunGame.Core.Model
/// <returns></returns> /// <returns></returns>
public virtual async Task<List<Character>> SelectTargetsAsync(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates) public virtual async Task<List<Character>> SelectTargetsAsync(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates)
{ {
List<Effect> effects = [.. character.Effects.Where(e => e.Level > 0)]; List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterSelectListBeforeSelection(character, attack, enemys, teammates); effect.AlterSelectListBeforeSelection(character, attack, enemys, teammates);
@ -2844,7 +2844,7 @@ namespace Milimoe.FunGame.Core.Model
if (isImmune) if (isImmune)
{ {
Character[] characters = [character, target]; Character[] characters = [character, target];
Effect[] effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0 && !e.IsBeingTemporaryDispelled)).Distinct()]; Effect[] effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
// 自带无视免疫或者特效免疫检定不通过可无视免疫 // 自带无视免疫或者特效免疫检定不通过可无视免疫