fix: Adds guard for monster ability recursion (#2363)
This commit is contained in:
parent
6b6cc10771
commit
55fe688eaf
3 changed files with 37 additions and 20 deletions
|
|
@ -27,7 +27,7 @@ public abstract class AreaEffectMonsterAbility : MonsterAbility
|
|||
|
||||
protected virtual bool CanEffectTarget(BaseCreature source, Mobile defender) =>
|
||||
source != defender && defender.Alive && source.CanBeHarmful(defender)
|
||||
&& (defender.Player || defender is BaseCreature bc && (bc.Team == source.Team || bc.Controlled || bc.Summoned))
|
||||
&& (defender.Player || defender is BaseCreature bc && (bc.Team != source.Team || bc.Controlled || bc.Summoned))
|
||||
&& (!Core.AOS || source.InLOS(defender));
|
||||
|
||||
protected abstract void DoEffectTarget(BaseCreature source, Mobile defender);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles;
|
||||
|
||||
public class DeathExplosion : AreaEffectMonsterAbility
|
||||
{
|
||||
private static HashSet<Mobile> _exploding = new();
|
||||
private static int _chainDepth;
|
||||
|
||||
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.Death;
|
||||
public override MonsterAbilityType AbilityType => MonsterAbilityType.DeathExplosion;
|
||||
|
|
@ -18,22 +17,25 @@ public class DeathExplosion : AreaEffectMonsterAbility
|
|||
|
||||
public override void Trigger(MonsterAbilityTrigger trigger, BaseCreature source, Mobile target)
|
||||
{
|
||||
if (trigger != MonsterAbilityTrigger.Death)
|
||||
if (trigger != MonsterAbilityTrigger.Death || _chainDepth > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_exploding.Add(source);
|
||||
|
||||
source.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head);
|
||||
source.PlaySound(0x307);
|
||||
|
||||
base.Trigger(trigger, source, target);
|
||||
_exploding.Remove(source);
|
||||
_chainDepth++;
|
||||
try
|
||||
{
|
||||
base.Trigger(trigger, source, target);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_chainDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CanEffectTarget(BaseCreature source, Mobile defender) =>
|
||||
!_exploding.Contains(defender) && base.CanEffectTarget(source, defender);
|
||||
|
||||
protected override void DoEffectTarget(BaseCreature source, Mobile defender)
|
||||
{
|
||||
source.DoHarmful(defender);
|
||||
|
|
|
|||
|
|
@ -1130,6 +1130,8 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual MonsterAbility[] GetMonsterAbilities() => null;
|
||||
|
||||
private MonsterAbilityTrigger _activeTriggers;
|
||||
|
||||
public virtual MonsterAbility GetAbility(MonsterAbilityType type)
|
||||
{
|
||||
var abilities = GetMonsterAbilities();
|
||||
|
|
@ -1186,6 +1188,11 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual bool TriggerAbility(MonsterAbilityTrigger trigger, Mobile defender)
|
||||
{
|
||||
if ((_activeTriggers & trigger) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var abilities = GetMonsterAbilities();
|
||||
|
||||
if (abilities == null)
|
||||
|
|
@ -1193,18 +1200,26 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
|
||||
var triggered = false;
|
||||
for (var i = 0; i < abilities.Length; i++)
|
||||
_activeTriggers |= trigger;
|
||||
try
|
||||
{
|
||||
var ability = abilities[i];
|
||||
if (ability.CanTrigger(this, trigger))
|
||||
var triggered = false;
|
||||
for (var i = 0; i < abilities.Length; i++)
|
||||
{
|
||||
ability.Trigger(trigger, this, defender);
|
||||
triggered = true;
|
||||
var ability = abilities[i];
|
||||
if (ability.CanTrigger(this, trigger))
|
||||
{
|
||||
ability.Trigger(trigger, this, defender);
|
||||
triggered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return triggered;
|
||||
return triggered;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_activeTriggers &= ~trigger;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void TriggerAbilityMove(MonsterAbilityTrigger trigger, Mobile defender, Direction d)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue