fix: Standardizes the variables for AI (#2234)

This commit is contained in:
Kamron Batman 2025-07-18 17:50:32 -07:00 • committed by GitHub
parent 416e1be735
commit 8f88de68a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1284 additions and 1287 deletions

View file

@ -234,26 +234,26 @@ namespace Server.Factions
public Mobile FindDispelTarget(bool activeOnly) public Mobile FindDispelTarget(bool activeOnly)
{ {
if (m_Mobile.Deleted || m_Mobile.Int < 95 || CanDispel(m_Mobile) || m_Mobile.AutoDispel) if (Mobile.Deleted || Mobile.Int < 95 || CanDispel(Mobile) || Mobile.AutoDispel)
{ {
return null; return null;
} }
if (activeOnly) if (activeOnly)
{ {
var aggressed = m_Mobile.Aggressed; var aggressed = Mobile.Aggressed;
var aggressors = m_Mobile.Aggressors; var aggressors = Mobile.Aggressors;
Mobile active = null; Mobile active = null;
var activePrio = 0.0; var activePrio = 0.0;
var comb = m_Mobile.Combatant; var comb = Mobile.Combatant;
if (comb?.Deleted == false && comb.Alive && !comb.IsDeadBondedPet && m_Mobile.InRange(comb, 12) && if (comb?.Deleted == false && comb.Alive && !comb.IsDeadBondedPet && Mobile.InRange(comb, 12) &&
CanDispel(comb)) CanDispel(comb))
{ {
active = comb; active = comb;
activePrio = m_Mobile.GetDistanceToSqrt(comb); activePrio = Mobile.GetDistanceToSqrt(comb);
if (activePrio <= 2) if (activePrio <= 2)
{ {
@ -266,9 +266,9 @@ namespace Server.Factions
var info = aggressed[i]; var info = aggressed[i];
var m = info.Defender; var m = info.Defender;
if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, 12) && CanDispel(m)) if (m != comb && m.Combatant == Mobile && Mobile.InRange(m, 12) && CanDispel(m))
{ {
var prio = m_Mobile.GetDistanceToSqrt(m); var prio = Mobile.GetDistanceToSqrt(m);
if (active == null || prio < activePrio) if (active == null || prio < activePrio)
{ {
@ -288,9 +288,9 @@ namespace Server.Factions
var info = aggressors[i]; var info = aggressors[i];
var m = info.Attacker; var m = info.Attacker;
if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, 12) && CanDispel(m)) if (m != comb && m.Combatant == Mobile && Mobile.InRange(m, 12) && CanDispel(m))
{ {
var prio = m_Mobile.GetDistanceToSqrt(m); var prio = Mobile.GetDistanceToSqrt(m);
if (active == null || prio < activePrio) if (active == null || prio < activePrio)
{ {
@ -308,26 +308,26 @@ namespace Server.Factions
return active; return active;
} }
var map = m_Mobile.Map; var map = Mobile.Map;
if (map != null) if (map != null)
{ {
Mobile active = null, inactive = null; Mobile active = null, inactive = null;
double actPrio = 0.0, inactPrio = 0.0; double actPrio = 0.0, inactPrio = 0.0;
var comb = m_Mobile.Combatant; var comb = Mobile.Combatant;
if (comb?.Deleted == false && comb.Alive && !comb.IsDeadBondedPet && CanDispel(comb)) if (comb?.Deleted == false && comb.Alive && !comb.IsDeadBondedPet && CanDispel(comb))
{ {
active = inactive = comb; active = inactive = comb;
actPrio = inactPrio = m_Mobile.GetDistanceToSqrt(comb); actPrio = inactPrio = Mobile.GetDistanceToSqrt(comb);
} }
foreach (var m in m_Mobile.GetMobilesInRange(12)) foreach (var m in Mobile.GetMobilesInRange(12))
{ {
if (m != m_Mobile && CanDispel(m)) if (m != Mobile && CanDispel(m))
{ {
var prio = m_Mobile.GetDistanceToSqrt(m); var prio = Mobile.GetDistanceToSqrt(m);
if (inactive == null || prio < inactPrio) if (inactive == null || prio < inactPrio)
{ {
@ -335,7 +335,7 @@ namespace Server.Factions
inactPrio = prio; inactPrio = prio;
} }
if ((m_Mobile.Combatant == m || m.Combatant == m_Mobile) && (active == null || prio < actPrio)) if ((Mobile.Combatant == m || m.Combatant == Mobile) && (active == null || prio < actPrio))
{ {
active = m; active = m;
actPrio = prio; actPrio = prio;
@ -350,7 +350,7 @@ namespace Server.Factions
} }
public bool CanDispel(Mobile m) => public bool CanDispel(Mobile m) =>
m is BaseCreature creature && creature.Summoned && m_Mobile.CanBeHarmful(creature, false) && m is BaseCreature creature && creature.Summoned && Mobile.CanBeHarmful(creature, false) &&
!creature.IsAnimatedDead; !creature.IsAnimatedDead;
public void RunTo(Mobile m) public void RunTo(Mobile m)
@ -364,14 +364,14 @@ namespace Server.Factions
} }
else else
{*/ {*/
if (!m_Mobile.InRange(m, m_Mobile.RangeFight)) if (!Mobile.InRange(m, Mobile.RangeFight))
{ {
if (!MoveTo(m, true, 1)) if (!MoveTo(m, true, 1))
{ {
OnFailedMove(); OnFailedMove();
} }
} }
else if (m_Mobile.InRange(m, m_Mobile.RangeFight - 1)) else if (Mobile.InRange(m, Mobile.RangeFight - 1))
{ {
RunFrom(m); RunFrom(m);
} }
@ -381,7 +381,7 @@ namespace Server.Factions
public void RunFrom(Mobile m) public void RunFrom(Mobile m)
{ {
Run((m_Mobile.GetDirectionTo(m) - 4) & Direction.Mask); Run((Mobile.GetDirectionTo(m) - 4) & Direction.Mask);
} }
public void OnFailedMove() public void OnFailedMove()
@ -396,33 +396,33 @@ namespace Server.Factions
m_Mobile.DebugSay( "I am stuck, I'm going to try teleporting away" ); m_Mobile.DebugSay( "I am stuck, I'm going to try teleporting away" );
} }
else*/ else*/
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"My move is blocked, so I am going to attack {m_Mobile.FocusMob.Name}"); Mobile.DebugSay($"My move is blocked, so I am going to attack {Mobile.FocusMob.Name}");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else if (m_Mobile.Debug) else if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am stuck"); Mobile.DebugSay("I am stuck");
} }
} }
public void Run(Direction d) public void Run(Direction d)
{ {
if (m_Mobile.Spell?.IsCasting == true || m_Mobile.Paralyzed || m_Mobile.Frozen || if (Mobile.Spell?.IsCasting == true || Mobile.Paralyzed || Mobile.Frozen ||
m_Mobile.DisallowAllMoves) Mobile.DisallowAllMoves)
{ {
return; return;
} }
m_Mobile.Direction = d | Direction.Running; Mobile.Direction = d | Direction.Running;
if (!DoMove(m_Mobile.Direction, true)) if (!DoMove(Mobile.Direction, true))
{ {
OnFailedMove(); OnFailedMove();
} }
@ -430,7 +430,7 @@ namespace Server.Factions
public override bool Think() public override bool Think()
{ {
if (m_Mobile.Deleted) if (Mobile.Deleted)
{ {
return false; return false;
} }
@ -438,32 +438,32 @@ namespace Server.Factions
var combatant = m_Guard.Combatant; var combatant = m_Guard.Combatant;
if (combatant?.Deleted != false || !combatant.Alive || combatant.IsDeadBondedPet || if (combatant?.Deleted != false || !combatant.Alive || combatant.IsDeadBondedPet ||
!m_Mobile.CanSee(combatant) || !m_Mobile.CanBeHarmful(combatant, false) || combatant.Map != m_Mobile.Map) !Mobile.CanSee(combatant) || !Mobile.CanBeHarmful(combatant, false) || combatant.Map != Mobile.Map)
{ {
// Our combatant is deleted, dead, hidden, or we cannot hurt them // Our combatant is deleted, dead, hidden, or we cannot hurt them
// Try to find another combatant // Try to find another combatant
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
m_Mobile.Combatant = combatant = m_Mobile.FocusMob; Mobile.Combatant = combatant = Mobile.FocusMob;
m_Mobile.FocusMob = null; Mobile.FocusMob = null;
} }
else else
{ {
m_Mobile.Combatant = combatant = null; Mobile.Combatant = combatant = null;
} }
} }
if (combatant != null && (!m_Mobile.InLOS(combatant) || !m_Mobile.InRange(combatant, 12))) if (combatant != null && (!Mobile.InLOS(combatant) || !Mobile.InRange(combatant, 12)))
{ {
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
m_Mobile.Combatant = combatant = m_Mobile.FocusMob; Mobile.Combatant = combatant = Mobile.FocusMob;
m_Mobile.FocusMob = null; Mobile.FocusMob = null;
} }
else if (!m_Mobile.InRange(combatant, 36)) else if (!Mobile.InRange(combatant, 36))
{ {
m_Mobile.Combatant = combatant = null; Mobile.Combatant = combatant = null;
} }
} }
@ -544,7 +544,7 @@ namespace Server.Factions
Action = ActionType.Combat; Action = ActionType.Combat;
} }
m_Mobile.SetCurrentSpeedToActive(); Mobile.SetCurrentSpeedToActive();
m_Guard.Warmode = true; m_Guard.Warmode = true;
RunTo(toFollow); RunTo(toFollow);
@ -556,7 +556,7 @@ namespace Server.Factions
Action = ActionType.Wander; Action = ActionType.Wander;
} }
m_Mobile.SetCurrentSpeedToPassive(); Mobile.SetCurrentSpeedToPassive();
m_Guard.Warmode = false; m_Guard.Warmode = false;
WalkRandomInHome(2, 2, 1); WalkRandomInHome(2, 2, 1);
@ -582,9 +582,9 @@ namespace Server.Factions
} }
} }
var spell = m_Mobile.Spell as Spell; var spell = Mobile.Spell as Spell;
if (spell == null && Core.TickCount - m_Mobile.NextSpellTime >= 0) if (spell == null && Core.TickCount - Mobile.NextSpellTime >= 0)
{ {
var toRelease = DateTime.MinValue; var toRelease = DateTime.MinValue;

View file

@ -6,7 +6,7 @@ namespace Server.Targets;
public class AIControlMobileTarget : Target public class AIControlMobileTarget : Target
{ {
private readonly List<BaseAI> m_List; private readonly List<BaseAI> _list;
public AIControlMobileTarget(BaseAI ai, OrderType order) : base( public AIControlMobileTarget(BaseAI ai, OrderType order) : base(
-1, -1,
@ -14,7 +14,7 @@ public class AIControlMobileTarget : Target
order == OrderType.Attack ? TargetFlags.Harmful : TargetFlags.None order == OrderType.Attack ? TargetFlags.Harmful : TargetFlags.None
) )
{ {
m_List = new List<BaseAI>(); _list = new List<BaseAI>();
Order = order; Order = order;
AddAI(ai); AddAI(ai);
@ -24,9 +24,9 @@ public class AIControlMobileTarget : Target
public void AddAI(BaseAI ai) public void AddAI(BaseAI ai)
{ {
if (!m_List.Contains(ai)) if (!_list.Contains(ai))
{ {
m_List.Add(ai); _list.Add(ai);
} }
} }
@ -34,9 +34,9 @@ public class AIControlMobileTarget : Target
{ {
if (o is Mobile m) if (o is Mobile m)
{ {
for (var i = 0; i < m_List.Count; ++i) for (var i = 0; i < _list.Count; ++i)
{ {
m_List[i].EndPickTarget(from, m, Order); _list[i].EndPickTarget(from, m, Order);
} }
} }
} }

View file

@ -19,25 +19,25 @@ public class AnimalAI : BaseAI
{ {
// New, only flee @ 10% // New, only flee @ 10%
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax; var hitPercent = (double)Mobile.Hits / Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health if (!Mobile.Summoned && !Mobile.Controlled && hitPercent < 0.1 && Mobile.CanFlee) // Less than 10% health
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am low on health!"); Mobile.DebugSay("I am low on health!");
} }
Action = ActionType.Flee; Action = ActionType.Flee;
} }
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) else if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
@ -50,52 +50,52 @@ public class AnimalAI : BaseAI
public override bool DoActionCombat() public override bool DoActionCombat()
{ {
var combatant = m_Mobile.Combatant; var combatant = Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || if (combatant == null || combatant.Deleted || combatant.Map != Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet) combatant.IsDeadBondedPet)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant is gone!"); Mobile.DebugSay("My combatant is gone!");
} }
Action = ActionType.Wander; Action = ActionType.Wander;
return true; return true;
} }
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight)) if (!WalkMobileRange(combatant, 1, true, Mobile.RangeFight, Mobile.RangeFight))
{ {
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1) if (Mobile.GetDistanceToSqrt(combatant) > Mobile.RangePerception + 1)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I cannot find {combatant.Name}"); Mobile.DebugSay($"I cannot find {combatant.Name}");
} }
Action = ActionType.Wander; Action = ActionType.Wander;
return true; return true;
} }
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I should be closer to {combatant.Name}"); Mobile.DebugSay($"I should be closer to {combatant.Name}");
} }
} }
else if (Core.TickCount - m_Mobile.LastMoveTime > 400) else if (Core.TickCount - Mobile.LastMoveTime > 400)
{ {
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant); Mobile.Direction = Mobile.GetDirectionTo(combatant);
} }
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee) if (!Mobile.Controlled && !Mobile.Summoned && Mobile.CanFlee)
{ {
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax; var hitPercent = (double)Mobile.Hits / Mobile.HitsMax;
if (hitPercent <= 0.1) if (hitPercent <= 0.1)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am low on health!"); Mobile.DebugSay("I am low on health!");
} }
Action = ActionType.Flee; Action = ActionType.Flee;
@ -103,11 +103,11 @@ public class AnimalAI : BaseAI
} }
} }
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!"); Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
} }
} }
@ -116,19 +116,19 @@ public class AnimalAI : BaseAI
public override bool DoActionBackoff() public override bool DoActionBackoff()
{ {
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax; var hitPercent = (double)Mobile.Hits / Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health if (!Mobile.Summoned && !Mobile.Controlled && hitPercent < 0.1 && Mobile.CanFlee) // Less than 10% health
{ {
Action = ActionType.Flee; Action = ActionType.Flee;
} }
else if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false, true)) else if (AcquireFocusMob(Mobile.RangePerception * 2, FightMode.Closest, true, false, true))
{ {
if (WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2)) if (WalkMobileRange(Mobile.FocusMob, 1, false, Mobile.RangePerception, Mobile.RangePerception * 2))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("Well, here I am safe"); Mobile.DebugSay("Well, here I am safe");
} }
Action = ActionType.Wander; Action = ActionType.Wander;
@ -136,9 +136,9 @@ public class AnimalAI : BaseAI
} }
else else
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I have lost my focus, lets relax"); Mobile.DebugSay("I have lost my focus, lets relax");
} }
Action = ActionType.Wander; Action = ActionType.Wander;
@ -149,9 +149,9 @@ public class AnimalAI : BaseAI
public override bool DoActionFlee() public override bool DoActionFlee()
{ {
AcquireFocusMob(m_Mobile.RangePerception * 2, m_Mobile.FightMode, true, false, true); AcquireFocusMob(Mobile.RangePerception * 2, Mobile.FightMode, true, false, true);
m_Mobile.FocusMob ??= m_Mobile.Combatant; Mobile.FocusMob ??= Mobile.Combatant;
return base.DoActionFlee(); return base.DoActionFlee();
} }

View file

@ -11,19 +11,19 @@ public class ArcherAI : BaseAI
public override bool DoActionWander() public override bool DoActionWander()
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I have no combatant"); Mobile.DebugSay("I have no combatant");
} }
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name} and I will attack"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name} and I will attack");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
@ -36,62 +36,62 @@ public class ArcherAI : BaseAI
public override bool DoActionCombat() public override bool DoActionCombat()
{ {
var combatant = m_Mobile.Combatant; var combatant = Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || if (combatant == null || combatant.Deleted || combatant.Map != Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet) combatant.IsDeadBondedPet)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant is gone, so my guard is up"); Mobile.DebugSay("My combatant is gone, so my guard is up");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
if (Core.TickCount - m_Mobile.LastMoveTime > 1000 && !WalkMobileRange( if (Core.TickCount - Mobile.LastMoveTime > 1000 && !WalkMobileRange(
combatant, combatant,
1, 1,
true, true,
m_Mobile.RangeFight, Mobile.RangeFight,
m_Mobile.Weapon.MaxRange Mobile.Weapon.MaxRange
)) ))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I am still not in range of {combatant.Name}"); Mobile.DebugSay($"I am still not in range of {combatant.Name}");
} }
if ((int)m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1) if ((int)Mobile.GetDistanceToSqrt(combatant) > Mobile.RangePerception + 1)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have lost {combatant.Name}"); Mobile.DebugSay($"I have lost {combatant.Name}");
} }
m_Mobile.Combatant = null; Mobile.Combatant = null;
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
} }
else if (Core.TickCount - m_Mobile.LastMoveTime > 400) else if (Core.TickCount - Mobile.LastMoveTime > 400)
{ {
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant); Mobile.Direction = Mobile.GetDirectionTo(combatant);
} }
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!"); Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
} }
return true; return true;
} }
// When we have no ammo, we flee // When we have no ammo, we flee
var pack = m_Mobile.Backpack; var pack = Mobile.Backpack;
if (pack?.FindItemByType<Arrow>() == null) if (pack?.FindItemByType<Arrow>() == null)
{ {
@ -100,10 +100,10 @@ public class ArcherAI : BaseAI
} }
// At 20% we should check if we must leave // At 20% we should check if we must leave
if (m_Mobile.Combatant != null && m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100 && m_Mobile.CanFlee) if (Mobile.Combatant != null && Mobile.Hits < Mobile.HitsMax * 20 / 100 && Mobile.CanFlee)
{ {
// 10% to flee + the diff of hits // 10% to flee + the diff of hits
var fleeChance = 10 + Math.Max(0, m_Mobile.Combatant.Hits - m_Mobile.Hits); var fleeChance = 10 + Math.Max(0, Mobile.Combatant.Hits - Mobile.Hits);
if (Utility.Random(0, 100) > fleeChance) if (Utility.Random(0, 100) > fleeChance)
{ {
@ -116,14 +116,14 @@ public class ArcherAI : BaseAI
public override bool DoActionGuard() public override bool DoActionGuard()
{ {
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else

File diff suppressed because it is too large Load diff

View file

@ -8,19 +8,19 @@ public class BerserkAI : BaseAI
public override bool DoActionWander() public override bool DoActionWander()
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I have no combatant"); Mobile.DebugSay("I have no combatant");
} }
if (AcquireFocusMob(m_Mobile.RangePerception, FightMode.Closest, false, true, true)) if (AcquireFocusMob(Mobile.RangePerception, FightMode.Closest, false, true, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name} and I will attack"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name} and I will attack");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
@ -33,48 +33,48 @@ public class BerserkAI : BaseAI
public override bool DoActionCombat() public override bool DoActionCombat()
{ {
var combatant = m_Mobile.Combatant; var combatant = Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || if (combatant == null || combatant.Deleted || combatant.Map != Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet) combatant.IsDeadBondedPet)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant is gone, so my guard is up"); Mobile.DebugSay("My combatant is gone, so my guard is up");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight)) if (!WalkMobileRange(combatant, 1, true, Mobile.RangeFight, Mobile.RangeFight))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I am still not in range of {combatant.Name}"); Mobile.DebugSay($"I am still not in range of {combatant.Name}");
} }
if ((int)m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1) if ((int)Mobile.GetDistanceToSqrt(combatant) > Mobile.RangePerception + 1)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have lost {combatant.Name}"); Mobile.DebugSay($"I have lost {combatant.Name}");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
} }
else if (Core.TickCount - m_Mobile.LastMoveTime > 400) else if (Core.TickCount - Mobile.LastMoveTime > 400)
{ {
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant); Mobile.Direction = Mobile.GetDirectionTo(combatant);
} }
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!"); Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
} }
} }
@ -83,14 +83,14 @@ public class BerserkAI : BaseAI
public override bool DoActionGuard() public override bool DoActionGuard()
{ {
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, true, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, true, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else

View file

@ -9,13 +9,10 @@ namespace Server.Mobiles;
public class HealerAI : BaseAI public class HealerAI : BaseAI
{ {
private static readonly NeedDelegate m_Cure = NeedCure; private static readonly NeedDelegate[] Cure = [NeedCure];
private static readonly NeedDelegate m_GHeal = NeedGHeal; private static readonly NeedDelegate[] GHeal = [NeedGHeal];
private static readonly NeedDelegate m_LHeal = NeedLHeal; private static readonly NeedDelegate[] LHeal = [NeedLHeal];
private static readonly NeedDelegate[] m_ACure = { m_Cure }; private static readonly NeedDelegate[] AllHeal = [NeedCure, NeedGHeal, NeedLHeal];
private static readonly NeedDelegate[] m_AGHeal = { m_GHeal };
private static readonly NeedDelegate[] m_ALHeal = { m_LHeal };
private static readonly NeedDelegate[] m_All = { m_Cure, m_GHeal, m_LHeal };
public HealerAI(BaseCreature m) : base(m) public HealerAI(BaseCreature m) : base(m)
{ {
@ -23,12 +20,12 @@ public class HealerAI : BaseAI
public override bool Think() public override bool Think()
{ {
if (m_Mobile.Deleted) if (Mobile.Deleted)
{ {
return false; return false;
} }
var targ = m_Mobile.Target; var targ = Mobile.Target;
if (targ != null) if (targ != null)
{ {
@ -36,79 +33,79 @@ public class HealerAI : BaseAI
if (spellTarg?.Spell is CureSpell) if (spellTarg?.Spell is CureSpell)
{ {
ProcessTarget(targ, m_ACure); ProcessTarget(targ, Cure);
} }
else if (spellTarg?.Spell is GreaterHealSpell) else if (spellTarg?.Spell is GreaterHealSpell)
{ {
ProcessTarget(targ, m_AGHeal); ProcessTarget(targ, GHeal);
} }
else if (spellTarg?.Spell is HealSpell) else if (spellTarg?.Spell is HealSpell)
{ {
ProcessTarget(targ, m_ALHeal); ProcessTarget(targ, LHeal);
} }
else else
{ {
targ.Cancel(m_Mobile, TargetCancelType.Canceled); targ.Cancel(Mobile, TargetCancelType.Canceled);
} }
return true; return true;
} }
var toHelp = Find(m_All); var toHelp = Find(AllHeal);
if (toHelp != null) if (toHelp != null)
{ {
if (NeedCure(toHelp)) if (NeedCure(toHelp))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{toHelp.Name} needs a cure"); Mobile.DebugSay($"{toHelp.Name} needs a cure");
} }
if (!new CureSpell(m_Mobile).Cast()) if (!new CureSpell(Mobile).Cast())
{ {
new CureSpell(m_Mobile).Cast(); new CureSpell(Mobile).Cast();
} }
} }
else if (NeedGHeal(toHelp)) else if (NeedGHeal(toHelp))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{toHelp.Name} needs a greater heal"); Mobile.DebugSay($"{toHelp.Name} needs a greater heal");
} }
if (!new GreaterHealSpell(m_Mobile).Cast()) if (!new GreaterHealSpell(Mobile).Cast())
{ {
new HealSpell(m_Mobile).Cast(); new HealSpell(Mobile).Cast();
} }
} }
else if (NeedLHeal(toHelp)) else if (NeedLHeal(toHelp))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{toHelp.Name} needs a lesser heal"); Mobile.DebugSay($"{toHelp.Name} needs a lesser heal");
} }
new HealSpell(m_Mobile).Cast(); new HealSpell(Mobile).Cast();
} }
return true; return true;
} }
if (!AcquireFocusMob(m_Mobile.RangePerception, FightMode.Weakest, false, true, false)) if (!AcquireFocusMob(Mobile.RangePerception, FightMode.Weakest, false, true, false))
{ {
WalkRandomInHome(3, 2, 1); WalkRandomInHome(3, 2, 1);
return true; return true;
} }
WalkMobileRange(m_Mobile.FocusMob, 1, false, 4, 7); WalkMobileRange(Mobile.FocusMob, 1, false, 4, 7);
// TODO: Should it be able to do this? // TODO: Should it be able to do this?
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, m_Mobile.Combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, Mobile.Combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I used my abilities on {m_Mobile.Combatant.Name}!"); Mobile.DebugSay($"I used my abilities on {Mobile.Combatant.Name}!");
} }
} }
@ -121,26 +118,26 @@ public class HealerAI : BaseAI
if (toHelp == null) if (toHelp == null)
{ {
targ.Cancel(m_Mobile, TargetCancelType.Canceled); targ.Cancel(Mobile, TargetCancelType.Canceled);
} }
else if (targ.Range != -1 && !m_Mobile.InRange(toHelp, targ.Range)) else if (targ.Range != -1 && !Mobile.InRange(toHelp, targ.Range))
{ {
DoMove(m_Mobile.GetDirectionTo(toHelp) | Direction.Running); DoMove(Mobile.GetDirectionTo(toHelp) | Direction.Running);
} }
else else
{ {
targ.Invoke(m_Mobile, toHelp); targ.Invoke(Mobile, toHelp);
} }
} }
private Mobile Find(params ReadOnlySpan<NeedDelegate> funcs) private Mobile Find(params ReadOnlySpan<NeedDelegate> funcs)
{ {
if (m_Mobile.Deleted) if (Mobile.Deleted)
{ {
return null; return null;
} }
var map = m_Mobile.Map; var map = Mobile.Map;
if (map == null) if (map == null)
{ {
@ -150,9 +147,9 @@ public class HealerAI : BaseAI
var prio = 0.0; var prio = 0.0;
Mobile found = null; Mobile found = null;
foreach (var m in m_Mobile.GetMobilesInRange(m_Mobile.RangePerception)) foreach (var m in Mobile.GetMobilesInRange(Mobile.RangePerception))
{ {
if (!m_Mobile.CanSee(m) || m is not BaseCreature bc || bc.Team != m_Mobile.Team) if (!Mobile.CanSee(m) || m is not BaseCreature bc || bc.Team != Mobile.Team)
{ {
continue; continue;
} }
@ -161,7 +158,7 @@ public class HealerAI : BaseAI
{ {
if (funcs[i](bc)) if (funcs[i](bc))
{ {
var val = -m_Mobile.GetDistanceToSqrt(bc); var val = -Mobile.GetDistanceToSqrt(bc);
if (found == null || val > prio) if (found == null || val > prio)
{ {

File diff suppressed because it is too large Load diff

View file

@ -10,24 +10,24 @@ public class MeleeAI : BaseAI
public override bool DoActionWander() public override bool DoActionWander()
{ {
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am wandering"); Mobile.DebugSay("I am wandering");
} }
m_Mobile.Warmode = false; Mobile.Warmode = false;
base.DoActionWander(); base.DoActionWander();
} }
@ -37,41 +37,41 @@ public class MeleeAI : BaseAI
public override bool DoActionCombat() public override bool DoActionCombat()
{ {
var combatant = m_Mobile.Combatant; var combatant = Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || if (combatant == null || combatant.Deleted || combatant.Map != Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet) combatant.IsDeadBondedPet)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant is gone, so my guard is up"); Mobile.DebugSay("My combatant is gone, so my guard is up");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception)) if (!Mobile.InRange(combatant, Mobile.RangePerception))
{ {
// They are somewhat far away, can we find something else? // They are somewhat far away, can we find something else?
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
m_Mobile.FocusMob = null; Mobile.FocusMob = null;
} }
else if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception * 3)) else if (!Mobile.InRange(combatant, Mobile.RangePerception * 3))
{ {
m_Mobile.Combatant = null; Mobile.Combatant = null;
} }
combatant = m_Mobile.Combatant; combatant = Mobile.Combatant;
if (combatant == null) if (combatant == null)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant has fled, so I am on guard"); Mobile.DebugSay("My combatant has fled, so I am on guard");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
@ -79,58 +79,58 @@ public class MeleeAI : BaseAI
} }
} }
if (!MoveTo(combatant, true, m_Mobile.RangeFight)) if (!MoveTo(combatant, true, Mobile.RangeFight))
{ {
if (m_Mobile.InRange(combatant, 1)) if (Mobile.InRange(combatant, 1))
{ {
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant); Mobile.Direction = Mobile.GetDirectionTo(combatant);
} }
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"My move is blocked, so I am going to attack {m_Mobile.FocusMob!.Name}"); Mobile.DebugSay($"My move is blocked, so I am going to attack {Mobile.FocusMob!.Name}");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
return true; return true;
} }
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1) if (Mobile.GetDistanceToSqrt(combatant) > Mobile.RangePerception + 1)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I cannot find {combatant.Name}, so my guard is up"); Mobile.DebugSay($"I cannot find {combatant.Name}, so my guard is up");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I cannot find {combatant.Name}, so my guard is up"); Mobile.DebugSay($"I cannot find {combatant.Name}, so my guard is up");
} }
} }
else if (Core.TickCount - m_Mobile.LastMoveTime > 400) else if (Core.TickCount - Mobile.LastMoveTime > 400)
{ {
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant); Mobile.Direction = Mobile.GetDirectionTo(combatant);
} }
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee) if (!Mobile.Controlled && !Mobile.Summoned && Mobile.CanFlee)
{ {
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100) if (Mobile.Hits < Mobile.HitsMax * 20 / 100)
{ {
// We are low on health, should we flee? // We are low on health, should we flee?
var fleeChance = 10 + Math.Max(0, combatant.Hits - m_Mobile.Hits); // (10 + diff)% chance to flee; var fleeChance = 10 + Math.Max(0, combatant.Hits - Mobile.Hits); // (10 + diff)% chance to flee;
if (Utility.Random(0, 100) < fleeChance) if (Utility.Random(0, 100) < fleeChance)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I am going to flee from {combatant.Name}"); Mobile.DebugSay($"I am going to flee from {combatant.Name}");
} }
Action = ActionType.Flee; Action = ActionType.Flee;
@ -139,11 +139,11 @@ public class MeleeAI : BaseAI
} }
} }
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I used my abilities!"); Mobile.DebugSay("I used my abilities!");
} }
} }
@ -152,14 +152,14 @@ public class MeleeAI : BaseAI
public override bool DoActionGuard() public override bool DoActionGuard()
{ {
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
@ -172,20 +172,20 @@ public class MeleeAI : BaseAI
public override bool DoActionFlee() public override bool DoActionFlee()
{ {
if (m_Mobile.Hits > m_Mobile.HitsMax / 2) if (Mobile.Hits > Mobile.HitsMax / 2)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am stronger now, so I will continue fighting"); Mobile.DebugSay("I am stronger now, so I will continue fighting");
} }
m_Mobile.PlaySound(m_Mobile.GetAttackSound()); Mobile.PlaySound(Mobile.GetAttackSound());
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; Mobile.CurrentSpeed = Mobile.ActiveSpeed;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
{ {
m_Mobile.FocusMob = m_Mobile.Combatant; Mobile.FocusMob = Mobile.Combatant;
base.DoActionFlee(); base.DoActionFlee();
} }

View file

@ -5,9 +5,9 @@ namespace Server
{ {
public class OppositionGroup public class OppositionGroup
{ {
private readonly Type[][] m_Types; private readonly Type[][] _types;
public OppositionGroup(Type[][] types) => m_Types = types; public OppositionGroup(Type[][] types) => _types = types;
public static OppositionGroup TerathansAndOphidians { get; } = new( public static OppositionGroup TerathansAndOphidians { get; } = new(
new[] new[]
@ -112,9 +112,9 @@ namespace Server
var type = obj.GetType(); var type = obj.GetType();
for (var i = 0; i < m_Types.Length; ++i) for (var i = 0; i < _types.Length; ++i)
{ {
var group = m_Types[i]; var group = _types[i];
var contains = false; var contains = false;

View file

@ -8,20 +8,20 @@ public class PredatorAI : BaseAI
public override bool DoActionWander() public override bool DoActionWander()
{ {
if (m_Mobile.Combatant != null) if (Mobile.Combatant != null)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am hurt or being attacked, I kill him"); Mobile.DebugSay("I am hurt or being attacked, I kill him");
} }
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, true, false, true)) else if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, true, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("There is something near, I go away"); Mobile.DebugSay("There is something near, I go away");
} }
Action = ActionType.Backoff; Action = ActionType.Backoff;
@ -36,44 +36,44 @@ public class PredatorAI : BaseAI
public override bool DoActionCombat() public override bool DoActionCombat()
{ {
var combatant = m_Mobile.Combatant; var combatant = Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || if (combatant == null || combatant.Deleted || combatant.Map != Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet) combatant.IsDeadBondedPet)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant is gone, so my guard is up"); Mobile.DebugSay("My combatant is gone, so my guard is up");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight)) if (!WalkMobileRange(combatant, 1, true, Mobile.RangeFight, Mobile.RangeFight))
{ {
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1) if (Mobile.GetDistanceToSqrt(combatant) > Mobile.RangePerception + 1)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I cannot find {combatant.Name}"); Mobile.DebugSay($"I cannot find {combatant.Name}");
} }
Action = ActionType.Wander; Action = ActionType.Wander;
return true; return true;
} }
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I should be closer to {combatant.Name}"); Mobile.DebugSay($"I should be closer to {combatant.Name}");
} }
} }
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!"); Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
} }
} }
@ -82,17 +82,17 @@ public class PredatorAI : BaseAI
public override bool DoActionBackoff() public override bool DoActionBackoff()
{ {
if (m_Mobile.IsHurt() || m_Mobile.Combatant != null) if (Mobile.IsHurt() || Mobile.Combatant != null)
{ {
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false, true)) else if (AcquireFocusMob(Mobile.RangePerception * 2, FightMode.Closest, true, false, true))
{ {
if (WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2)) if (WalkMobileRange(Mobile.FocusMob, 1, false, Mobile.RangePerception, Mobile.RangePerception * 2))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("Well, here I am safe"); Mobile.DebugSay("Well, here I am safe");
} }
Action = ActionType.Wander; Action = ActionType.Wander;
@ -100,9 +100,9 @@ public class PredatorAI : BaseAI
} }
else else
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I have lost my focus, lets relax"); Mobile.DebugSay("I have lost my focus, lets relax");
} }
Action = ActionType.Wander; Action = ActionType.Wander;

View file

@ -5,7 +5,7 @@ namespace Server.Mobiles;
public class ThiefAI : BaseAI public class ThiefAI : BaseAI
{ {
private Item m_toDisarm; private Item _toDisarm;
public ThiefAI(BaseCreature m) : base(m) public ThiefAI(BaseCreature m) : base(m)
{ {
@ -13,19 +13,19 @@ public class ThiefAI : BaseAI
public override bool DoActionWander() public override bool DoActionWander()
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I have no combatant"); Mobile.DebugSay("I have no combatant");
} }
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
@ -38,57 +38,57 @@ public class ThiefAI : BaseAI
public override bool DoActionCombat() public override bool DoActionCombat()
{ {
var combatant = m_Mobile.Combatant; var combatant = Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || if (combatant == null || combatant.Deleted || combatant.Map != Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet) combatant.IsDeadBondedPet)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My combatant is gone, so my guard is up"); Mobile.DebugSay("My combatant is gone, so my guard is up");
} }
Action = ActionType.Guard; Action = ActionType.Guard;
return true; return true;
} }
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight)) if (!WalkMobileRange(combatant, 1, true, Mobile.RangeFight, Mobile.RangeFight))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I should be closer to {combatant.Name}"); Mobile.DebugSay($"I should be closer to {combatant.Name}");
} }
} }
else else
{ {
if (m_toDisarm?.IsChildOf(m_Mobile.Backpack) != false) if (_toDisarm?.IsChildOf(Mobile.Backpack) != false)
{ {
m_toDisarm = combatant.FindItemOnLayer(Layer.OneHanded) ?? combatant.FindItemOnLayer(Layer.TwoHanded); _toDisarm = combatant.FindItemOnLayer(Layer.OneHanded) ?? combatant.FindItemOnLayer(Layer.TwoHanded);
} }
if (!Core.AOS && !m_Mobile.DisarmReady && m_Mobile.Skills.Wrestling.Value >= 80.0 && if (!Core.AOS && !Mobile.DisarmReady && Mobile.Skills.Wrestling.Value >= 80.0 &&
m_Mobile.Skills.ArmsLore.Value >= 80.0 && m_toDisarm != null) Mobile.Skills.ArmsLore.Value >= 80.0 && _toDisarm != null)
{ {
Fists.DisarmRequest(m_Mobile); Fists.DisarmRequest(Mobile);
} }
if (m_toDisarm?.IsChildOf(combatant.Backpack) == true && if (_toDisarm?.IsChildOf(combatant.Backpack) == true &&
Core.TickCount - m_Mobile.NextSkillTime >= 0 && m_toDisarm.LootType != LootType.Blessed && Core.TickCount - Mobile.NextSkillTime >= 0 && _toDisarm.LootType != LootType.Blessed &&
m_toDisarm.LootType != LootType.Newbied) _toDisarm.LootType != LootType.Newbied)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("Trying to steal from combatant."); Mobile.DebugSay("Trying to steal from combatant.");
} }
m_Mobile.UseSkill(SkillName.Stealing); Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, m_toDisarm); Mobile.Target?.Invoke(Mobile, _toDisarm);
} }
else if (m_toDisarm == null && Core.TickCount - m_Mobile.NextSkillTime >= 0) else if (_toDisarm == null && Core.TickCount - Mobile.NextSkillTime >= 0)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"Trying to steal from {combatant.Name}."); Mobile.DebugSay($"Trying to steal from {combatant.Name}.");
} }
bool didSteal = TryStealFrom<Bandage>(combatant); bool didSteal = TryStealFrom<Bandage>(combatant);
@ -98,9 +98,9 @@ public class ThiefAI : BaseAI
if (!didSteal) if (!didSteal)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I am going to flee from {combatant.Name}"); Mobile.DebugSay($"I am going to flee from {combatant.Name}");
} }
Action = ActionType.Flee; Action = ActionType.Flee;
@ -111,15 +111,15 @@ public class ThiefAI : BaseAI
// We are low on health, should we flee? // We are low on health, should we flee?
// (10 + diff)% chance to flee // (10 + diff)% chance to flee
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100 && m_Mobile.CanFlee) if (Mobile.Hits < Mobile.HitsMax * 20 / 100 && Mobile.CanFlee)
{ {
var fleeChance = 10 + Math.Max(0, combatant.Hits - m_Mobile.Hits); var fleeChance = 10 + Math.Max(0, combatant.Hits - Mobile.Hits);
if (Utility.Random(0, 100) > fleeChance) if (Utility.Random(0, 100) > fleeChance)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I am going to flee from {combatant.Name}"); Mobile.DebugSay($"I am going to flee from {combatant.Name}");
} }
Action = ActionType.Flee; Action = ActionType.Flee;
@ -128,11 +128,11 @@ public class ThiefAI : BaseAI
return true; return true;
} }
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, m_Mobile.Combatant)) if (Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, Mobile.Combatant))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I used my abilities on {m_Mobile.Combatant.Name}!"); Mobile.DebugSay($"I used my abilities on {Mobile.Combatant.Name}!");
} }
} }
return true; return true;
@ -143,8 +143,8 @@ public class ThiefAI : BaseAI
Item steal = combatant.Backpack?.FindItemByType<T>(); Item steal = combatant.Backpack?.FindItemByType<T>();
if (steal != null) if (steal != null)
{ {
m_Mobile.UseSkill(SkillName.Stealing); Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, steal); Mobile.Target?.Invoke(Mobile, steal);
return true; return true;
} }
@ -153,14 +153,14 @@ public class ThiefAI : BaseAI
public override bool DoActionGuard() public override bool DoActionGuard()
{ {
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) if (AcquireFocusMob(Mobile.RangePerception, Mobile.FightMode, false, false, true))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking"); Mobile.DebugSay($"I have detected {Mobile.FocusMob.Name}, attacking");
} }
m_Mobile.Combatant = m_Mobile.FocusMob; Mobile.Combatant = Mobile.FocusMob;
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
@ -173,18 +173,18 @@ public class ThiefAI : BaseAI
public override bool DoActionFlee() public override bool DoActionFlee()
{ {
if (m_Mobile.Hits > m_Mobile.HitsMax / 2) if (Mobile.Hits > Mobile.HitsMax / 2)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I am stronger now, so I will continue fighting"); Mobile.DebugSay("I am stronger now, so I will continue fighting");
} }
Action = ActionType.Combat; Action = ActionType.Combat;
} }
else else
{ {
m_Mobile.FocusMob = m_Mobile.Combatant; Mobile.FocusMob = Mobile.Combatant;
base.DoActionFlee(); base.DoActionFlee();
} }

View file

@ -15,35 +15,35 @@ public class VendorAI : BaseAI
public override bool DoActionWander() public override bool DoActionWander()
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("I'm fine"); Mobile.DebugSay("I'm fine");
} }
if (m_Mobile.Combatant != null) if (Mobile.Combatant != null)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{m_Mobile.Combatant.Name} is attacking me"); Mobile.DebugSay($"{Mobile.Combatant.Name} is attacking me");
} }
m_Mobile.Say(GetRandomGuardMessage()); Mobile.Say(GetRandomGuardMessage());
Action = ActionType.Flee; Action = ActionType.Flee;
} }
else else
{ {
if (m_Mobile.FocusMob != null) if (Mobile.FocusMob != null)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{m_Mobile.FocusMob.Name} has talked to me"); Mobile.DebugSay($"{Mobile.FocusMob.Name} has talked to me");
} }
Action = ActionType.Interact; Action = ActionType.Interact;
} }
else else
{ {
m_Mobile.Warmode = false; Mobile.Warmode = false;
base.DoActionWander(); base.DoActionWander();
} }
@ -54,50 +54,50 @@ public class VendorAI : BaseAI
public override bool DoActionInteract() public override bool DoActionInteract()
{ {
var customer = m_Mobile.FocusMob; var customer = Mobile.FocusMob;
if (m_Mobile.Combatant != null) if (Mobile.Combatant != null)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{m_Mobile.Combatant.Name} is attacking me"); Mobile.DebugSay($"{Mobile.Combatant.Name} is attacking me");
} }
m_Mobile.Say(GetRandomGuardMessage()); Mobile.Say(GetRandomGuardMessage());
Action = ActionType.Flee; Action = ActionType.Flee;
return true; return true;
} }
if (customer?.Deleted != false || customer.Map != m_Mobile.Map) if (customer?.Deleted != false || customer.Map != Mobile.Map)
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay("My customer have disapeared"); Mobile.DebugSay("My customer have disapeared");
} }
m_Mobile.FocusMob = null; Mobile.FocusMob = null;
Action = ActionType.Wander; Action = ActionType.Wander;
} }
else if (customer.InRange(m_Mobile, m_Mobile.RangeFight)) else if (customer.InRange(Mobile, Mobile.RangeFight))
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"I am with {customer.Name}"); Mobile.DebugSay($"I am with {customer.Name}");
} }
m_Mobile.Direction = m_Mobile.GetDirectionTo(customer); Mobile.Direction = Mobile.GetDirectionTo(customer);
} }
else else
{ {
if (m_Mobile.Debug) if (Mobile.Debug)
{ {
m_Mobile.DebugSay($"{customer.Name} is gone"); Mobile.DebugSay($"{customer.Name} is gone");
} }
m_Mobile.FocusMob = null; Mobile.FocusMob = null;
Action = ActionType.Wander; Action = ActionType.Wander;
} }
@ -106,13 +106,13 @@ public class VendorAI : BaseAI
public override bool DoActionGuard() public override bool DoActionGuard()
{ {
m_Mobile.FocusMob = m_Mobile.Combatant; Mobile.FocusMob = Mobile.Combatant;
return base.DoActionGuard(); return base.DoActionGuard();
} }
public override bool HandlesOnSpeech(Mobile from) public override bool HandlesOnSpeech(Mobile from)
{ {
if (from.InRange(m_Mobile, 4)) if (from.InRange(Mobile, 4))
{ {
return true; return true;
} }
@ -127,7 +127,7 @@ public class VendorAI : BaseAI
var from = e.Mobile; var from = e.Mobile;
if (m_Mobile is BaseVendor vendor && from.InRange(m_Mobile, Core.AOS ? 1 : 4) && !e.Handled) if (Mobile is BaseVendor vendor && from.InRange(Mobile, Core.AOS ? 1 : 4) && !e.Handled)
{ {
if (e.HasKeyword(0x14D)) // *vendor sell* if (e.HasKeyword(0x14D)) // *vendor sell*
{ {

View file

@ -2258,7 +2258,7 @@ namespace Server.Mobiles
public void ChangeAIType(AIType newAI) public void ChangeAIType(AIType newAI)
{ {
AIObject?.m_Timer.Stop(); AIObject?._timer.Stop();
if (ForcedAI != null) if (ForcedAI != null)
{ {
@ -2381,7 +2381,7 @@ namespace Server.Mobiles
{ {
if (AIObject != null) if (AIObject != null)
{ {
AIObject.m_Timer?.Stop(); AIObject._timer?.Stop();
AIObject = null; AIObject = null;
} }

View file

@ -234,11 +234,11 @@ namespace Server.Mobiles
public override bool Think() public override bool Think()
{ {
// Clones only follow their owners // Clones only follow their owners
var master = m_Mobile.SummonMaster; var master = Mobile.SummonMaster;
if (master?.Map == m_Mobile.Map && master?.InRange(m_Mobile, m_Mobile.RangePerception) == true) if (master?.Map == Mobile.Map && master?.InRange(Mobile, Mobile.RangePerception) == true)
{ {
var iCurrDist = (int)m_Mobile.GetDistanceToSqrt(master); var iCurrDist = (int)Mobile.GetDistanceToSqrt(master);
var bRun = iCurrDist > 5; var bRun = iCurrDist > 5;
WalkMobileRange(master, 2, bRun, 0, 1); WalkMobileRange(master, 2, bRun, 0, 1);