diff --git a/GameServer/ECS-Effects/AmnesiaECSEffect.cs b/GameServer/ECS-Effects/AmnesiaECSEffect.cs
index 4c7dffdb88..a517be6a3a 100644
--- a/GameServer/ECS-Effects/AmnesiaECSEffect.cs
+++ b/GameServer/ECS-Effects/AmnesiaECSEffect.cs
@@ -1,15 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace DOL.GS
+namespace DOL.GS
{
public class AmnesiaECSEffect : ECSGameSpellEffect
{
- public AmnesiaECSEffect(ECSGameEffectInitParams initParams)
- : base(initParams) { }
+ public AmnesiaECSEffect(ECSGameEffectInitParams initParams) : base(initParams) { }
public override void OnStartEffect()
{
diff --git a/GameServer/ai/brain/StandardMob/StandardMobBrain.cs b/GameServer/ai/brain/StandardMob/StandardMobBrain.cs
index f08986bdce..ba5a467b9b 100644
--- a/GameServer/ai/brain/StandardMob/StandardMobBrain.cs
+++ b/GameServer/ai/brain/StandardMob/StandardMobBrain.cs
@@ -589,13 +589,11 @@ public virtual bool CanAggroTarget(GameLiving target)
public virtual void OnAttackedByEnemy(AttackData ad)
{
- if (!Body.IsAlive || Body.ObjectState != GameObject.eObjectState.Active)
+ if (!Body.IsAlive || Body.ObjectState != GameObject.eObjectState.Active || FSM.GetCurrentState() == FSM.GetState(eFSMStateType.PASSIVE))
return;
- if (FSM.GetCurrentState() == FSM.GetState(eFSMStateType.PASSIVE))
- return;
-
- ConvertDamageToAggroAmount(ad.Attacker, Math.Max(1, ad.Damage + ad.CriticalDamage));
+ if (ad.GeneratesAggro)
+ ConvertDamageToAggroAmount(ad.Attacker, Math.Max(1, ad.Damage + ad.CriticalDamage));
if (FSM.GetCurrentState() != FSM.GetState(eFSMStateType.AGGRO) && HasAggro)
{
diff --git a/GameServer/gameutils/AttackData.cs b/GameServer/gameutils/AttackData.cs
index 6085520450..b95d8b4422 100644
--- a/GameServer/gameutils/AttackData.cs
+++ b/GameServer/gameutils/AttackData.cs
@@ -316,5 +316,7 @@ public bool CausesCombat
get { return m_causesCombat; }
set { m_causesCombat = value; }
}
+
+ public bool GeneratesAggro => SpellHandler == null || SpellHandler.Spell.SpellType is not eSpellType.Amnesia || IsSpellResisted;
}
}
diff --git a/GameServer/spells/AmnesiaSpellHandler.cs b/GameServer/spells/AmnesiaSpellHandler.cs
index f99d75bc95..d95c639c55 100644
--- a/GameServer/spells/AmnesiaSpellHandler.cs
+++ b/GameServer/spells/AmnesiaSpellHandler.cs
@@ -1,152 +1,61 @@
-using DOL.AI.Brain;
using DOL.GS.PacketHandler;
using DOL.Language;
namespace DOL.GS.Spells
{
- [SpellHandlerAttribute("Amnesia")]
- public class AmnesiaSpellHandler : SpellHandler
- {
- public override ECSGameSpellEffect CreateECSEffect(ECSGameEffectInitParams initParams)
- {
- return new AmnesiaECSEffect(initParams);
- }
-
- ///
- /// Execute direct damage spell
- ///
- ///
- public override void FinishSpellCast(GameLiving target)
- {
- m_caster.Mana -= PowerCost(target);
- base.FinishSpellCast(target);
- }
-
- public override void OnDirectEffect(GameLiving target)
- {
- base.OnDirectEffect(target);
- if (target == null || !target.IsAlive)
- return;
-
- /// [Atlas - Takii] This is a silly change by a silly person because disallowing Amnesia while MoC'd has never been a thing in this game.
- //if (Caster.EffectList.GetOfType() != null)
- // return;
+ [SpellHandlerAttribute("Amnesia")]
+ public class AmnesiaSpellHandler : SpellHandler
+ {
+ public AmnesiaSpellHandler(GameLiving caster, Spell spell, SpellLine line) : base(caster, spell, line) { }
+
+ public override ECSGameSpellEffect CreateECSEffect(ECSGameEffectInitParams initParams)
+ {
+ return new AmnesiaECSEffect(initParams);
+ }
+
+ public override void FinishSpellCast(GameLiving target)
+ {
+ m_caster.Mana -= PowerCost(target);
+ base.FinishSpellCast(target);
+ }
+
+ public override void OnDirectEffect(GameLiving target)
+ {
+ base.OnDirectEffect(target);
+
+ if (target == null || !target.IsAlive)
+ return;
- //have to do it here because OnAttackedByEnemy is not called to not get aggro
- //if (target.Realm == 0 || Caster.Realm == 0)
- //target.LastAttackedByEnemyTickPvE = GameLoop.GameLoopTime;
- //else target.LastAttackedByEnemyTickPvP = GameLoop.GameLoopTime;
- SendEffectAnimation(target, 0, false, 1);
+ SendEffectAnimation(target, 0, false, 1);
- if (target is GamePlayer)
- {
- ((GamePlayer)target).styleComponent.NextCombatStyle = null;
- ((GamePlayer)target).styleComponent.NextCombatBackupStyle = null;
- }
+ if (target is GamePlayer player)
+ {
+ player.styleComponent.NextCombatStyle = null;
+ player.styleComponent.NextCombatBackupStyle = null;
+ }
- //Amnesia only affects normal spells and not song activation (still affects pulses from songs though)
- if (target.CurrentSpellHandler?.Spell.InstrumentRequirement == 0)
- target.castingComponent.ClearUpSpellHandlers(); //stop even if MoC or QC
+ // Amnesia only affects normal spells and not song activation (still affects pulses from songs though)
+ if (target.CurrentSpellHandler?.Spell.InstrumentRequirement == 0)
+ target.castingComponent.ClearUpSpellHandlers();
- target.rangeAttackComponent.AutoFireTarget = null;
- //if(target is GamePlayer)
- //target.TargetObject = null;
+ target.rangeAttackComponent.AutoFireTarget = null;
if (target is GamePlayer)
MessageToLiving(target, LanguageMgr.GetTranslation((target as GamePlayer).Client, "Amnesia.MessageToTarget"), eChatType.CT_Spell);
- /*
- GameSpellEffect effect;
- effect = SpellHandler.FindEffectOnTarget(target, "Mesmerize");
- if (effect != null)
- {
- effect.Cancel(false);
- return;
- }*/
-
- //Targets next tick for pulsing speed enhancement spell will be skipped.
- // if (target.effectListComponent.ContainsEffectForEffectType(eEffect.Pulse))
- // {
- // //EffectListService.TryCancelFirstEffectOfTypeOnTarget(target, eEffect.Pulse);
- // foreach(ECSGameEffect e in target.effectListComponent.GetAllPulseEffects())
- // {
-
- // if(e is ECSGameSpellEffect effect && effect.SpellHandler.Spell.SpellType == eSpellType.SpeedEnhancement)
- // {
- // Console.WriteLine($"effect: {effect} SpellType: {effect.SpellHandler.Spell.SpellType} PulseFreq: {effect.PulseFreq} ");
- // if(effect.ExpireTick > GameLoop.GameLoopTime && effect.ExpireTick < (GameLoop.GameLoopTime + 10000))
- // {
- // effect.ExpireTick += effect.PulseFreq;
- // if(effect.ExpireTick < (GameLoop.GameLoopTime + 10000))
- // effect.ExpireTick += effect.PulseFreq;
-
- // }
- // }
- // }
- // }
-
- // //Casters next tick for pulsing speed enhancement spell will be skipped
- // if (Caster.effectListComponent.ContainsEffectForEffectType(eEffect.Pulse))
- // {
- // //EffectListService.TryCancelFirstEffectOfTypeOnTarget(target, eEffect.Pulse);
- // foreach(ECSGameEffect e in Caster.effectListComponent.GetAllPulseEffects())
- // {
-
- // if(e is ECSGameSpellEffect effect && effect.SpellHandler.Spell.SpellType == eSpellType.SpeedEnhancement)
- // {
- // Console.WriteLine($"effect: {effect} SpellType: {effect.SpellHandler.Spell.SpellType} PulseFreq: {effect.PulseFreq} Duration: {effect.Duration} ");
-
- // if(effect.ExpireTick > GameLoop.GameLoopTime && effect.ExpireTick < (GameLoop.GameLoopTime + 10000))
- // {
- // effect.ExpireTick += effect.PulseFreq;
- // if(effect.ExpireTick < (GameLoop.GameLoopTime + 10000))
- // effect.ExpireTick += effect.PulseFreq;
-
- // }
- // }
- // }
- // }
-
- // //Cancel Mez on target if Amnesia hits.
- // if (target.effectListComponent.ContainsEffectForEffectType(eEffect.Mez))
- // {
- // var effect = EffectListService.GetEffectOnTarget(target, eEffect.Mez);
-
- // if (effect != null)
- // EffectService.RequestImmediateCancelEffect(effect);
- // }
-
- if (target is GameNPC)
- {
- GameNPC npc = (GameNPC)target;
- IOldAggressiveBrain aggroBrain = npc.Brain as IOldAggressiveBrain;
- if (aggroBrain != null)
- {
- if (Util.Chance(Spell.AmnesiaChance) && npc.TargetObject != null && npc.TargetObject is GameLiving living)
- {
- aggroBrain.ClearAggroList();
- aggroBrain.AddToAggroList(living, 1);
- }
-
- }
- }
- }
-
- ///
- /// When spell was resisted
- ///
- /// the target that resisted the spell
- protected override void OnSpellResisted(GameLiving target)
- {
- base.OnSpellResisted(target);
- if (Spell.CastTime == 0)
- {
- // start interrupt even for resisted instant amnesia
- target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster);
- }
- }
-
- // constructor
- public AmnesiaSpellHandler(GameLiving caster, Spell spell, SpellLine line) : base(caster, spell, line) {}
- }
+ }
+
+ ///
+ /// When spell was resisted
+ ///
+ /// the target that resisted the spell
+ protected override void OnSpellResisted(GameLiving target)
+ {
+ base.OnSpellResisted(target);
+
+ // Start interrupt even for resisted instant amnesia.
+ if (Spell.CastTime == 0)
+ target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster);
+ }
+ }
}
diff --git a/GameServer/spells/SpellHandler.cs b/GameServer/spells/SpellHandler.cs
index ee18c7ee93..36bcab2194 100644
--- a/GameServer/spells/SpellHandler.cs
+++ b/GameServer/spells/SpellHandler.cs
@@ -2324,15 +2324,17 @@ public virtual void ApplyEffectOnTarget(GameLiving target)
if (!HasPositiveEffect)
{
- AttackData ad = new AttackData();
- ad.Attacker = Caster;
- ad.Target = target;
- ad.AttackType = AttackData.eAttackType.Spell;
- ad.SpellHandler = this;
- ad.AttackResult = eAttackResult.HitUnstyled;
- ad.IsSpellResisted = false;
- ad.Damage = (int)Spell.Damage;
- ad.DamageType = Spell.DamageType;
+ AttackData ad = new()
+ {
+ Attacker = Caster,
+ Target = target,
+ AttackType = AttackData.eAttackType.Spell,
+ SpellHandler = this,
+ AttackResult = eAttackResult.HitUnstyled,
+ IsSpellResisted = false,
+ Damage = (int) Spell.Damage,
+ DamageType = Spell.DamageType
+ };
m_lastAttackData = ad;
Caster.OnAttackEnemy(ad);
@@ -2340,7 +2342,7 @@ public virtual void ApplyEffectOnTarget(GameLiving target)
// Harmful spells that deal no damage (ie. debuffs) should still trigger OnAttackedByEnemy.
// Exception for DoTs here since the initial landing of the DoT spell reports 0 damage
// and the first tick damage is done by the pulsing effect, which takes care of firing OnAttackedByEnemy.
- if (ad.Damage == 0 && ad.SpellHandler.Spell.SpellType != eSpellType.DamageOverTime)
+ if (ad.Damage == 0 && ad.SpellHandler.Spell.SpellType is not eSpellType.DamageOverTime)
target.OnAttackedByEnemy(ad);
}
}