Skip to content

Commit

Permalink
fix: Magic NPCs now use spell range (#1870)
Browse files Browse the repository at this point in the history
### Summary
- Drastically streamlines the spell targeting by collapsing the target classes into a single `SpellTarget<T>` class.
- Moves TargetRange to the spell itself so it can be used by MageAI.
- Changes range check in MageAI to use TargetRange. This should fix target acquisition bugs
  • Loading branch information
kamronbatman authored Aug 8, 2024
1 parent 91e37fb commit 9b7fea2
Show file tree
Hide file tree
Showing 85 changed files with 255 additions and 313 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ public override bool Think()
{
targ.Invoke(m_Guard, toHarm);
}
else if ((targ as ISpellTarget)?.Spell is DispelSpell)
else if ((targ as ISpellTarget<Mobile>)?.Spell is DispelSpell)
{
targ.Cancel(m_Guard, TargetCancelType.Canceled);
}
Expand Down
2 changes: 1 addition & 1 deletion Projects/UOContent/Mobiles/AI/HealerAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override bool Think()

if (targ != null)
{
var spellTarg = targ as ISpellTarget;
var spellTarg = targ as ISpellTarget<Mobile>;

if (spellTarg?.Spell is CureSpell)
{
Expand Down
30 changes: 18 additions & 12 deletions Projects/UOContent/Mobiles/AI/MageAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ public override bool DoActionCombat()
m_Mobile.DebugSay("I used my abilities!");
}
}
else if (m_Mobile.Spell == null && Core.TickCount - m_NextCastTime >= 0 && m_Mobile.InRange(c, Core.ML ? 10 : 12))
else if (m_Mobile.Spell == null && Core.TickCount - m_NextCastTime >= 0)
{
// We are ready to cast a spell
Spell spell;
Expand Down Expand Up @@ -816,24 +816,30 @@ public override bool DoActionCombat()
};

// Now we have a spell picked
// Move first before casting
var range = (spell as IRangedSpell)?.TargetRange ?? m_Mobile.RangePerception;

// Move first before casting
if (!SmartAI || toDispel == null)
{
RunTo(c);
}
else if (m_Mobile.InRange(toDispel, 10))
else if (m_Mobile.InRange(toDispel, Math.Min(10, range)))
{
RunFrom(toDispel);
}
else if (!m_Mobile.InRange(toDispel, Core.ML ? 10 : 12))
else if (!m_Mobile.InRange(toDispel, range))
{
RunTo(toDispel);
}

spell?.Cast();
// After running, make sure we are still in range
if (spell == null || m_Mobile.InRange(c, range))
{
spell?.Cast();

m_NextCastTime = Core.TickCount + (int)GetDelay(spell).TotalMilliseconds;
// Even if we don't have a spell, delay the next potential cast
m_NextCastTime = Core.TickCount + (int)GetDelay(spell).TotalMilliseconds;
}
}
else if (m_Mobile.Spell?.IsCasting != true)
{
Expand All @@ -857,7 +863,7 @@ public override bool DoActionGuard()
{
var map = m_Mobile.Map;

if (map == null || !m_Mobile.InRange(m_LastTargetLoc, Core.ML ? 10 : 12))
if (map == null || !m_Mobile.InRange(m_LastTargetLoc, m_Mobile.RangePerception))
{
m_LastTarget = null;
}
Expand Down Expand Up @@ -967,7 +973,7 @@ public Mobile FindDispelTarget(bool activeOnly)
var comb = m_Mobile.Combatant;

if (comb?.Deleted == false && comb.Alive && !comb.IsDeadBondedPet &&
m_Mobile.InRange(comb, Core.ML ? 10 : 12) && CanDispel(comb))
m_Mobile.InRange(comb, m_Mobile.RangePerception) && CanDispel(comb))
{
active = comb;
activePrio = m_Mobile.GetDistanceToSqrt(comb);
Expand All @@ -983,7 +989,7 @@ public Mobile FindDispelTarget(bool activeOnly)
var info = aggressed[i];
var m = info.Defender;

if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, Core.ML ? 10 : 12) && CanDispel(m))
if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, m_Mobile.RangePerception) && CanDispel(m))
{
var prio = m_Mobile.GetDistanceToSqrt(m);

Expand All @@ -1005,7 +1011,7 @@ public Mobile FindDispelTarget(bool activeOnly)
var info = aggressors[i];
var m = info.Attacker;

if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, Core.ML ? 10 : 12) && CanDispel(m))
if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, m_Mobile.RangePerception) && CanDispel(m))
{
var prio = m_Mobile.GetDistanceToSqrt(m);

Expand Down Expand Up @@ -1040,7 +1046,7 @@ public Mobile FindDispelTarget(bool activeOnly)
actPrio = inactPrio = m_Mobile.GetDistanceToSqrt(comb);
}

foreach (var m in m_Mobile.GetMobilesInRange(Core.ML ? 10 : 12))
foreach (var m in m_Mobile.GetMobilesInRange(m_Mobile.RangePerception))
{
if (m != m_Mobile && CanDispel(m))
{
Expand Down Expand Up @@ -1079,7 +1085,7 @@ private bool ProcessTarget()
return false;
}

var spellTarg = targ as ISpellTarget;
var spellTarg = targ as ISpellTarget<Mobile>;

var isReveal = spellTarg?.Spell is RevealSpell;
var isDispel = spellTarg?.Spell is DispelSpell;
Expand Down
13 changes: 1 addition & 12 deletions Projects/UOContent/Mobiles/BaseCreature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ public enum TeachResult
public const int MaxOwners = 5;

public const int DefaultRangePerception = 16;
public const int OldRangePerception = 10;

private const double ChanceToRummage = 0.5; // 50%

Expand Down Expand Up @@ -350,15 +349,10 @@ public enum TeachResult
public BaseCreature(
AIType ai,
FightMode mode = FightMode.Closest,
int iRangePerception = 10,
int iRangePerception = DefaultRangePerception,
int iRangeFight = 1
)
{
if (iRangePerception == OldRangePerception)
{
iRangePerception = DefaultRangePerception;
}

m_Loyalty = MaxLoyalty; // Wonderfully Happy

m_CurrentAI = ai;
Expand Down Expand Up @@ -1980,11 +1974,6 @@ public override void Deserialize(IGenericReader reader)
_passiveSpeed = reader.ReadDouble();
_currentSpeed = reader.ReadDouble();

if (RangePerception == OldRangePerception)
{
RangePerception = DefaultRangePerception;
}

m_Home.X = reader.ReadInt();
m_Home.Y = reader.ReadInt();
m_Home.Z = reader.ReadInt();
Expand Down
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Chivalry/CleanseByFire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Server.Spells.Chivalry
{
public class CleanseByFireSpell : PaladinSpell, ISpellTargetingMobile
public class CleanseByFireSpell : PaladinSpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Cleanse By Fire",
Expand Down Expand Up @@ -113,7 +113,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Beneficial);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Chivalry/CloseWounds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Server.Spells.Chivalry
{
public class CloseWoundsSpell : PaladinSpell, ISpellTargetingMobile
public class CloseWoundsSpell : PaladinSpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Close Wounds",
Expand Down Expand Up @@ -93,7 +93,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Beneficial);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Chivalry/RemoveCurse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Server.Spells.Chivalry
{
public class RemoveCurseSpell : PaladinSpell, ISpellTargetingMobile
public class RemoveCurseSpell : PaladinSpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Remove Curse",
Expand Down Expand Up @@ -139,7 +139,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Beneficial);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Eighth/EnergyVortex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Server.Spells.Eighth
{
public class EnergyVortexSpell : MagerySpell, ISpellTargetingPoint3D
public class EnergyVortexSpell : MagerySpell, ITargetingSpell<IPoint3D>
{
private static readonly SpellInfo _info = new(
"Energy Vortex",
Expand Down Expand Up @@ -60,7 +60,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetPoint3D(this, retryOnLOS: true);
Caster.Target = new SpellTarget<IPoint3D>(this, retryOnLos: true);
}
}
}
6 changes: 4 additions & 2 deletions Projects/UOContent/Spells/Eighth/Resurrection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Server.Spells.Eighth
{
public class ResurrectionSpell : MagerySpell, ISpellTargetingMobile
public class ResurrectionSpell : MagerySpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Resurrection",
Expand All @@ -22,6 +22,8 @@ public ResurrectionSpell(Mobile caster, Item scroll = null) : base(caster, scrol

public override SpellCircle Circle => SpellCircle.Eighth;

public int TargetRange => 1;

public void Target(Mobile m)
{
if (m == Caster)
Expand Down Expand Up @@ -79,7 +81,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial, 1);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Beneficial);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Fifth/BladeSpirits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Server.Spells.Fifth
{
public class BladeSpiritsSpell : MagerySpell, ISpellTargetingPoint3D
public class BladeSpiritsSpell : MagerySpell, ITargetingSpell<IPoint3D>
{
private static readonly SpellInfo _info = new(
"Blade Spirits",
Expand Down Expand Up @@ -78,7 +78,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetPoint3D(this, retryOnLOS: true);
Caster.Target = new SpellTarget<IPoint3D>(this, retryOnLos: true);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Fifth/DispelField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Server.Spells.Fifth
{
public class DispelFieldSpell : MagerySpell, ISpellTargetingItem
public class DispelFieldSpell : MagerySpell, ITargetingSpell<Item>
{
private static readonly SpellInfo _info = new(
"Dispel Field",
Expand Down Expand Up @@ -51,7 +51,7 @@ public void Target(Item item)

public override void OnCast()
{
Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Item>(this);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Fifth/MindBlast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Server.Spells.Fifth
{
public class MindBlastSpell : MagerySpell, ISpellTargetingMobile
public class MindBlastSpell : MagerySpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Mind Blast",
Expand Down Expand Up @@ -110,7 +110,7 @@ public void Target(Mobile m)

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Harmful);
}

private void AosDelay_Callback(Mobile caster, Mobile target, Mobile defender, int damage)
Expand Down
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Fifth/Paralyze.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Server.Spells.Fifth
{
public class ParalyzeSpell : MagerySpell, ISpellTargetingMobile
public class ParalyzeSpell : MagerySpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Paralyze",
Expand Down Expand Up @@ -82,7 +82,7 @@ public void Target(Mobile m)

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Harmful);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/Fifth/PoisonField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Server.Spells.Fifth;

public class PoisonFieldSpell : MagerySpell, ISpellTargetingPoint3D
public class PoisonFieldSpell : MagerySpell, ITargetingSpell<IPoint3D>
{
private static readonly SpellInfo _info = new(
"Poison Field",
Expand Down Expand Up @@ -57,7 +57,7 @@ public void Target(IPoint3D p)

public override void OnCast()
{
Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<IPoint3D>(this);
}
}

Expand Down
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/First/Clumsy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Server.Spells.First
{
public class ClumsySpell : MagerySpell, ISpellTargetingMobile
public class ClumsySpell : MagerySpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Clumsy",
Expand Down Expand Up @@ -47,7 +47,7 @@ public void Target(Mobile m)

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Harmful);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/First/Feeblemind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Server.Spells.First
{
public class FeeblemindSpell : MagerySpell, ISpellTargetingMobile
public class FeeblemindSpell : MagerySpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Feeblemind",
Expand Down Expand Up @@ -49,7 +49,7 @@ public void Target(Mobile m)

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Harmful);
}
}
}
4 changes: 2 additions & 2 deletions Projects/UOContent/Spells/First/Heal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Server.Spells.First
{
public class HealSpell : MagerySpell, ISpellTargetingMobile
public class HealSpell : MagerySpell, ITargetingSpell<Mobile>
{
private static readonly SpellInfo _info = new(
"Heal",
Expand Down Expand Up @@ -84,7 +84,7 @@ public override bool CheckCast()

public override void OnCast()
{
Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial, Core.ML ? 10 : 12);
Caster.Target = new SpellTarget<Mobile>(this, TargetFlags.Beneficial);
}
}
}
Loading

0 comments on commit 9b7fea2

Please sign in to comment.