fix: Fixes crash with combatant and mobs facing each other (#1644)
### Summary - Fixes crash bugs with combatant checks in AI - Fixes mobs not facing each other while in combat. (Old RunUO bug) - Fixes predators not actually going into guard when their combatant dies. - Adds missing checks for combatant in various AI. Note: Much easier to understand changes if whitespace is off - https://github.com/modernuo/ModernUO/pull/1644/files?diff=split&w=1
This commit is contained in:
parent
1e73802d1e
commit
d4282367ba
8 changed files with 89 additions and 87 deletions
|
|
@ -52,11 +52,12 @@ public class AnimalAI : BaseAI
|
|||
{
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("My combatant is gone..");
|
||||
m_Mobile.DebugSay("My combatant is gone!");
|
||||
}
|
||||
|
||||
Action = ActionType.Wander;
|
||||
|
|
@ -98,6 +99,7 @@ public class AnimalAI : BaseAI
|
|||
}
|
||||
}
|
||||
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
|
|
|
|||
|
|
@ -36,55 +36,53 @@ public class ArcherAI : BaseAI
|
|||
|
||||
public override bool DoActionCombat()
|
||||
{
|
||||
if (m_Mobile.Combatant?.Deleted != false || !m_Mobile.Combatant.Alive ||
|
||||
m_Mobile.Combatant.IsDeadBondedPet)
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("My combatant is deleted");
|
||||
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
|
||||
}
|
||||
|
||||
Action = ActionType.Guard;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Core.TickCount - m_Mobile.LastMoveTime > 1000)
|
||||
{
|
||||
if (
|
||||
m_Mobile.Combatant != null &&
|
||||
!WalkMobileRange(
|
||||
m_Mobile.Combatant,
|
||||
1,
|
||||
true,
|
||||
m_Mobile.RangeFight,
|
||||
m_Mobile.Weapon.MaxRange
|
||||
)
|
||||
)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I am still not in range of {m_Mobile.Combatant.Name}");
|
||||
}
|
||||
|
||||
if ((int)m_Mobile.GetDistanceToSqrt(m_Mobile.Combatant) > m_Mobile.RangePerception + 1)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I have lost {m_Mobile.Combatant.Name}");
|
||||
}
|
||||
|
||||
m_Mobile.Combatant = null;
|
||||
Action = ActionType.Guard;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, m_Mobile.Combatant))
|
||||
if (Core.TickCount - m_Mobile.LastMoveTime > 1000 &&
|
||||
!WalkMobileRange(
|
||||
m_Mobile.Combatant,
|
||||
1,
|
||||
true,
|
||||
m_Mobile.RangeFight,
|
||||
m_Mobile.Weapon.MaxRange
|
||||
))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I used my abilities on {m_Mobile.Combatant.Name}!");
|
||||
m_Mobile.DebugSay($"I am still not in range of {combatant.Name}");
|
||||
}
|
||||
|
||||
if ((int)m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I have lost {combatant.Name}");
|
||||
}
|
||||
|
||||
m_Mobile.Combatant = null;
|
||||
Action = ActionType.Guard;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -998,20 +998,26 @@ public abstract class BaseAI
|
|||
return true;
|
||||
}
|
||||
|
||||
var c = m_Mobile.Combatant;
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (c?.Deleted != false || c.Map != m_Mobile.Map || !c.Alive || c.IsDeadBondedPet)
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("My combatant is gone!");
|
||||
}
|
||||
|
||||
Action = ActionType.Wander;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(c);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, c))
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I used my abilities on {c.Name}!");
|
||||
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1949,31 +1955,28 @@ public abstract class BaseAI
|
|||
m_Mobile.Combatant = null;
|
||||
m_Mobile.Warmode = false;
|
||||
}
|
||||
else if (m_Mobile.BardTarget?.Deleted != false || m_Mobile.BardTarget.Map != m_Mobile.Map ||
|
||||
m_Mobile.GetDistanceToSqrt(m_Mobile.BardTarget) > m_Mobile.RangePerception)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("I have lost my provoke target");
|
||||
}
|
||||
|
||||
m_Mobile.BardProvoked = false;
|
||||
m_Mobile.BardMaster = null;
|
||||
m_Mobile.BardTarget = null;
|
||||
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.Warmode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Mobile.BardTarget?.Deleted != false || m_Mobile.BardTarget.Map != m_Mobile.Map ||
|
||||
m_Mobile.GetDistanceToSqrt(m_Mobile.BardTarget) > m_Mobile.RangePerception)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("I have lost my provoke target");
|
||||
}
|
||||
m_Mobile.Combatant = m_Mobile.BardTarget;
|
||||
m_Action = ActionType.Combat;
|
||||
|
||||
m_Mobile.BardProvoked = false;
|
||||
m_Mobile.BardMaster = null;
|
||||
m_Mobile.BardTarget = null;
|
||||
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.Warmode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.Combatant = m_Mobile.BardTarget;
|
||||
m_Action = ActionType.Combat;
|
||||
|
||||
m_Mobile.OnThink();
|
||||
Think();
|
||||
}
|
||||
m_Mobile.OnThink();
|
||||
Think();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -33,38 +33,32 @@ public class BerserkAI : BaseAI
|
|||
|
||||
public override bool DoActionCombat()
|
||||
{
|
||||
if (m_Mobile.Combatant?.Deleted != false)
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("My combatant is deleted");
|
||||
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
|
||||
}
|
||||
|
||||
Action = ActionType.Guard;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
m_Mobile.Combatant != null &&
|
||||
!WalkMobileRange(
|
||||
m_Mobile.Combatant,
|
||||
1,
|
||||
true,
|
||||
m_Mobile.RangeFight,
|
||||
m_Mobile.RangeFight
|
||||
)
|
||||
)
|
||||
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I am still not in range of {m_Mobile.Combatant.Name}");
|
||||
m_Mobile.DebugSay($"I am still not in range of {combatant.Name}");
|
||||
}
|
||||
|
||||
if ((int)m_Mobile.GetDistanceToSqrt(m_Mobile.Combatant) > m_Mobile.RangePerception + 1)
|
||||
if ((int)m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I have lost {m_Mobile.Combatant.Name}");
|
||||
m_Mobile.DebugSay($"I have lost {combatant.Name}");
|
||||
}
|
||||
|
||||
Action = ActionType.Guard;
|
||||
|
|
@ -72,11 +66,12 @@ public class BerserkAI : BaseAI
|
|||
}
|
||||
}
|
||||
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, m_Mobile.Combatant))
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay($"I used my abilities on {m_Mobile.Combatant.Name}!");
|
||||
m_Mobile.DebugSay($"I used my abilities on {combatant.Name}!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -780,6 +780,7 @@ public class MageAI : BaseAI
|
|||
}
|
||||
}
|
||||
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(c);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, c))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class MeleeAI : BaseAI
|
|||
{
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
|
|
@ -128,6 +128,7 @@ public class MeleeAI : BaseAI
|
|||
}
|
||||
}
|
||||
|
||||
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
|
||||
if (m_Mobile.TriggerAbility(MonsterAbilityTrigger.CombatAction, combatant))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
|
|
|
|||
|
|
@ -38,14 +38,15 @@ public class PredatorAI : BaseAI
|
|||
{
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
|
||||
}
|
||||
|
||||
Action = ActionType.Wander;
|
||||
Action = ActionType.Guard;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ public class ThiefAI : BaseAI
|
|||
{
|
||||
var combatant = m_Mobile.Combatant;
|
||||
|
||||
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
|
||||
combatant.IsDeadBondedPet)
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue