fix: Cleans up AI code (#1084)

This commit is contained in:
Kamron Batman 2022-06-20 19:32:16 -07:00 committed by GitHub
parent da877f59a7
commit 38b45d5e0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 4830 additions and 4632 deletions

View file

@ -411,13 +411,13 @@ namespace Server.Factions
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My move is blocked, so I am going to attack {0}", m_Mobile.FocusMob.Name);
m_Mobile.DebugSay($"My move is blocked, so I am going to attack {m_Mobile.FocusMob.Name}");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
else if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am stuck");
}
@ -815,17 +815,14 @@ namespace Server.Factions
if (type != null && m_Guard.Target == null && UseItemByType(type))
{
if (spell is GreaterHealSpell)
{
if (m_Guard.Hits + 30 > m_Guard.HitsMax && m_Guard.Hits + 10 < m_Guard.HitsMax)
{
spell = new HealSpell(m_Guard);
}
}
else
if (spell is not GreaterHealSpell)
{
spell = null;
}
else if (m_Guard.Hits + 30 > m_Guard.HitsMax && m_Guard.Hits + 10 < m_Guard.HitsMax)
{
spell = new HealSpell(m_Guard);
}
}
}
else if (spell == null && m_Guard.Stam < m_Guard.StamMax / 3 && IsAllowed(GuardAI.Melee))

View file

@ -2,43 +2,42 @@ using System.Collections.Generic;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Targets
namespace Server.Targets;
public class AIControlMobileTarget : Target
{
public class AIControlMobileTarget : Target
private readonly List<BaseAI> m_List;
public AIControlMobileTarget(BaseAI ai, OrderType order) : base(
-1,
false,
order == OrderType.Attack ? TargetFlags.Harmful : TargetFlags.None
)
{
private readonly List<BaseAI> m_List;
m_List = new List<BaseAI>();
Order = order;
public AIControlMobileTarget(BaseAI ai, OrderType order) : base(
-1,
false,
order == OrderType.Attack ? TargetFlags.Harmful : TargetFlags.None
)
AddAI(ai);
}
public OrderType Order { get; }
public void AddAI(BaseAI ai)
{
if (!m_List.Contains(ai))
{
m_List = new List<BaseAI>();
Order = order;
AddAI(ai);
m_List.Add(ai);
}
}
public OrderType Order { get; }
public void AddAI(BaseAI ai)
protected override void OnTarget(Mobile from, object o)
{
if (o is Mobile m)
{
if (!m_List.Contains(ai))
for (var i = 0; i < m_List.Count; ++i)
{
m_List.Add(ai);
}
}
protected override void OnTarget(Mobile from, object o)
{
if (o is Mobile m)
{
for (var i = 0; i < m_List.Count; ++i)
{
m_List[i].EndPickTarget(from, m, Order);
}
m_List[i].EndPickTarget(from, m, Order);
}
}
}
}
}

View file

@ -7,125 +7,140 @@
*
*/
namespace Server.Mobiles
namespace Server.Mobiles;
public class AnimalAI : BaseAI
{
public class AnimalAI : BaseAI
public AnimalAI(BaseCreature m) : base(m)
{
public AnimalAI(BaseCreature m) : base(m)
}
public override bool DoActionWander()
{
// New, only flee @ 10%
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health
{
}
public override bool DoActionWander()
{
// New, only flee @ 10%
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am low on health!");
Action = ActionType.Flee;
}
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
Action = ActionType.Flee;
}
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
base.DoActionWander();
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant is gone..");
}
Action = ActionType.Wander;
return true;
}
public override bool DoActionCombat()
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
m_Mobile.DebugSay("My combatant is gone..");
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I cannot find {combatant.Name}");
}
Action = ActionType.Wander;
return true;
}
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
if (m_Mobile.Debug)
{
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I cannot find {0}", combatant.Name);
}
Action = ActionType.Wander;
return true;
}
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
}
m_Mobile.DebugSay($"I should be closer to {combatant.Name}");
}
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee)
{
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (hitPercent < 0.1)
{
m_Mobile.DebugSay("I am low on health!");
Action = ActionType.Flee;
}
}
return true;
}
public override bool DoActionBackoff()
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee)
{
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health
if (hitPercent <= 0.1)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am low on health!");
}
Action = ActionType.Flee;
}
else
}
return true;
}
public override bool DoActionBackoff()
{
var hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health
{
Action = ActionType.Flee;
}
else if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false, true))
{
if (WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2))
{
if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false, true))
if (m_Mobile.Debug)
{
if (WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2))
{
m_Mobile.DebugSay("Well, here I am safe");
Action = ActionType.Wander;
}
}
else
{
m_Mobile.DebugSay("I have lost my focus, lets relax");
Action = ActionType.Wander;
m_Mobile.DebugSay("Well, here I am safe");
}
Action = ActionType.Wander;
}
}
else
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have lost my focus, lets relax");
}
return true;
Action = ActionType.Wander;
}
public override bool DoActionFlee()
{
AcquireFocusMob(m_Mobile.RangePerception * 2, m_Mobile.FightMode, true, false, true);
return true;
}
m_Mobile.FocusMob ??= m_Mobile.Combatant;
public override bool DoActionFlee()
{
AcquireFocusMob(m_Mobile.RangePerception * 2, m_Mobile.FightMode, true, false, true);
return base.DoActionFlee();
}
m_Mobile.FocusMob ??= m_Mobile.Combatant;
return base.DoActionFlee();
}
}

View file

@ -1,135 +1,126 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
public class ArcherAI : BaseAI
{
public ArcherAI(BaseCreature m) : base(m)
{
}
namespace Server.Mobiles;
public override bool DoActionWander()
public class ArcherAI : BaseAI
{
public ArcherAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have no combatant");
}
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0} and I will attack", m_Mobile.FocusMob.Name);
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
return base.DoActionWander();
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name} and I will attack");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
return base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
if (m_Mobile.Combatant?.Deleted != false || !m_Mobile.Combatant.Alive ||
m_Mobile.Combatant.IsDeadBondedPet)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant is deleted");
}
Action = ActionType.Guard;
return true;
}
public override bool DoActionCombat()
if (Core.TickCount - m_Mobile.LastMoveTime > 1000)
{
if (m_Mobile.Combatant?.Deleted != false || !m_Mobile.Combatant.Alive ||
m_Mobile.Combatant.IsDeadBondedPet)
{
m_Mobile.DebugSay("My combatant is deleted");
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.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 am still not in range of {0}", m_Mobile.Combatant.Name);
m_Mobile.DebugSay($"I have lost {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 {0}", m_Mobile.Combatant.Name);
}
m_Mobile.Combatant = null;
Action = ActionType.Guard;
return true;
}
m_Mobile.Combatant = null;
Action = ActionType.Guard;
return true;
}
}
}
// When we have no ammo, we flee
var pack = m_Mobile.Backpack;
// When we have no ammo, we flee
var pack = m_Mobile.Backpack;
if (pack?.FindItemByType<Arrow>() == null)
if (pack?.FindItemByType<Arrow>() == null)
{
Action = ActionType.Flee;
return true;
}
// 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)
{
// 10% to flee + the diff of hits
var fleeChance = 10 + Math.Max(0, m_Mobile.Combatant.Hits - m_Mobile.Hits);
if (Utility.Random(0, 100) > fleeChance)
{
Action = ActionType.Flee;
return true;
}
// At 20% we should check if we must leave
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100 && m_Mobile.CanFlee)
{
var bFlee = false;
// if my current hits are more than my opponent, i don't care
if (m_Mobile.Combatant != null && m_Mobile.Hits < m_Mobile.Combatant.Hits)
{
var iDiff = m_Mobile.Combatant.Hits - m_Mobile.Hits;
if (Utility.Random(0, 100) > 10 + iDiff) // 10% to flee + the diff of hits
{
bFlee = true;
}
}
else if (m_Mobile.Combatant != null && m_Mobile.Hits >= m_Mobile.Combatant.Hits)
{
if (Utility.Random(0, 100) > 10) // 10% to flee
{
bFlee = true;
}
}
if (bFlee)
{
Action = ActionType.Flee;
}
}
return true;
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
return true;
}
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,91 +1,97 @@
namespace Server.Mobiles
namespace Server.Mobiles;
public class BerserkAI : BaseAI
{
public class BerserkAI : BaseAI
public BerserkAI(BaseCreature m) : base(m)
{
public BerserkAI(BaseCreature m) : base(m)
}
public override bool DoActionWander()
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have no combatant");
}
public override bool DoActionWander()
if (AcquireFocusMob(m_Mobile.RangePerception, FightMode.Closest, false, true, true))
{
m_Mobile.DebugSay("I have No Combatant");
if (AcquireFocusMob(m_Mobile.RangePerception, FightMode.Closest, false, true, true))
if (m_Mobile.Debug)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name} and I will attack");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name} and I will attack");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
if (m_Mobile.Combatant?.Deleted != false)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant is deleted");
}
Action = ActionType.Guard;
return true;
}
public override bool DoActionCombat()
if (
m_Mobile.Combatant != null &&
!WalkMobileRange(
m_Mobile.Combatant,
1,
true,
m_Mobile.RangeFight,
m_Mobile.RangeFight
)
)
{
if (m_Mobile.Combatant?.Deleted != false)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant is deleted");
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}");
}
Action = ActionType.Guard;
return true;
}
if (
m_Mobile.Combatant != null &&
!WalkMobileRange(
m_Mobile.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}");
}
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}");
}
Action = ActionType.Guard;
return true;
}
}
return true;
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, true, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
return true;
}
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, true, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
}

View file

@ -4,179 +4,168 @@ using Server.Spells.Fourth;
using Server.Spells.Second;
using Server.Targeting;
namespace Server.Mobiles
namespace Server.Mobiles;
public class HealerAI : BaseAI
{
public class HealerAI : BaseAI
private static readonly NeedDelegate m_Cure = NeedCure;
private static readonly NeedDelegate m_GHeal = NeedGHeal;
private static readonly NeedDelegate m_LHeal = NeedLHeal;
private static readonly NeedDelegate[] m_ACure = { m_Cure };
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)
{
private static readonly NeedDelegate m_Cure = NeedCure;
private static readonly NeedDelegate m_GHeal = NeedGHeal;
private static readonly NeedDelegate m_LHeal = NeedLHeal;
private static readonly NeedDelegate[] m_ACure = { m_Cure };
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 override bool Think()
{
if (m_Mobile.Deleted)
{
return false;
}
public override bool Think()
var targ = m_Mobile.Target;
if (targ != null)
{
if (m_Mobile.Deleted)
var spellTarg = targ as ISpellTarget;
if (spellTarg?.Spell is CureSpell)
{
return false;
ProcessTarget(targ, m_ACure);
}
var targ = m_Mobile.Target;
if (targ != null)
else if (spellTarg?.Spell is GreaterHealSpell)
{
var spellTarg = targ as ISpellTarget;
if (spellTarg?.Spell is CureSpell)
{
ProcessTarget(targ, m_ACure);
}
else if (spellTarg?.Spell is GreaterHealSpell)
{
ProcessTarget(targ, m_AGHeal);
}
else if (spellTarg?.Spell is HealSpell)
{
ProcessTarget(targ, m_ALHeal);
}
else
{
targ.Cancel(m_Mobile, TargetCancelType.Canceled);
}
ProcessTarget(targ, m_AGHeal);
}
else
else if (spellTarg?.Spell is HealSpell)
{
var toHelp = Find(m_All);
if (toHelp != null)
{
if (NeedCure(toHelp))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} needs a cure", toHelp.Name);
}
if (!new CureSpell(m_Mobile).Cast())
{
new CureSpell(m_Mobile).Cast();
}
}
else if (NeedGHeal(toHelp))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} needs a greater heal", toHelp.Name);
}
if (!new GreaterHealSpell(m_Mobile).Cast())
{
new HealSpell(m_Mobile).Cast();
}
}
else if (NeedLHeal(toHelp))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} needs a lesser heal", toHelp.Name);
}
new HealSpell(m_Mobile).Cast();
}
}
else
{
if (AcquireFocusMob(m_Mobile.RangePerception, FightMode.Weakest, false, true, false))
{
WalkMobileRange(m_Mobile.FocusMob, 1, false, 4, 7);
}
else
{
WalkRandomInHome(3, 2, 1);
}
}
}
return true;
}
private void ProcessTarget(Target targ, NeedDelegate[] func)
{
var toHelp = Find(func);
if (toHelp != null)
{
if (targ.Range != -1 && !m_Mobile.InRange(toHelp, targ.Range))
{
DoMove(m_Mobile.GetDirectionTo(toHelp) | Direction.Running);
}
else
{
targ.Invoke(m_Mobile, toHelp);
}
ProcessTarget(targ, m_ALHeal);
}
else
{
targ.Cancel(m_Mobile, TargetCancelType.Canceled);
}
}
private Mobile Find(params NeedDelegate[] funcs)
else
{
if (m_Mobile.Deleted)
var toHelp = Find(m_All);
if (toHelp != null)
{
return null;
}
var map = m_Mobile.Map;
if (map != null)
{
var prio = 0.0;
Mobile found = null;
foreach (var m in m_Mobile.GetMobilesInRange(m_Mobile.RangePerception))
if (NeedCure(toHelp))
{
if (!m_Mobile.CanSee(m) || !(m is BaseCreature) || ((BaseCreature)m).Team != m_Mobile.Team)
if (m_Mobile.Debug)
{
continue;
m_Mobile.DebugSay($"{toHelp.Name} needs a cure");
}
for (var i = 0; i < funcs.Length; ++i)
if (!new CureSpell(m_Mobile).Cast())
{
if (funcs[i](m))
{
var val = -m_Mobile.GetDistanceToSqrt(m);
if (found == null || val > prio)
{
prio = val;
found = m;
}
break;
}
new CureSpell(m_Mobile).Cast();
}
}
else if (NeedGHeal(toHelp))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{toHelp.Name} needs a greater heal");
}
return found;
if (!new GreaterHealSpell(m_Mobile).Cast())
{
new HealSpell(m_Mobile).Cast();
}
}
else if (NeedLHeal(toHelp))
{
m_Mobile.DebugSay("{toHelp.Name} needs a lesser heal");
new HealSpell(m_Mobile).Cast();
}
}
else if (AcquireFocusMob(m_Mobile.RangePerception, FightMode.Weakest, false, true, false))
{
WalkMobileRange(m_Mobile.FocusMob, 1, false, 4, 7);
}
else
{
WalkRandomInHome(3, 2, 1);
}
}
return true;
}
private void ProcessTarget(Target targ, NeedDelegate[] func)
{
var toHelp = Find(func);
if (toHelp == null)
{
targ.Cancel(m_Mobile, TargetCancelType.Canceled);
}
else if (targ.Range != -1 && !m_Mobile.InRange(toHelp, targ.Range))
{
DoMove(m_Mobile.GetDirectionTo(toHelp) | Direction.Running);
}
else
{
targ.Invoke(m_Mobile, toHelp);
}
}
private Mobile Find(params NeedDelegate[] funcs)
{
if (m_Mobile.Deleted)
{
return null;
}
private static bool NeedCure(Mobile m) => m.Poisoned;
var map = m_Mobile.Map;
private static bool NeedGHeal(Mobile m) => m.Hits < m.HitsMax - 40;
if (map == null)
{
return null;
}
private static bool NeedLHeal(Mobile m) => m.Hits < m.HitsMax - 10;
var prio = 0.0;
Mobile found = null;
private delegate bool NeedDelegate(Mobile m);
foreach (var m in m_Mobile.GetMobilesInRange(m_Mobile.RangePerception))
{
if (!m_Mobile.CanSee(m) || !(m is BaseCreature) || ((BaseCreature)m).Team != m_Mobile.Team)
{
continue;
}
for (var i = 0; i < funcs.Length; ++i)
{
if (funcs[i](m))
{
var val = -m_Mobile.GetDistanceToSqrt(m);
if (found == null || val > prio)
{
prio = val;
found = m;
}
break;
}
}
}
return found;
}
}
private static bool NeedCure(Mobile m) => m.Poisoned;
private static bool NeedGHeal(Mobile m) => m.Hits < m.HitsMax - 40;
private static bool NeedLHeal(Mobile m) => m.Hits < m.HitsMax - 10;
private delegate bool NeedDelegate(Mobile m);
}

File diff suppressed because it is too large Load diff

View file

@ -1,175 +1,176 @@
namespace Server.Mobiles
{
public class MeleeAI : BaseAI
{
public MeleeAI(BaseCreature m) : base(m)
{
}
using System;
public override bool DoActionWander()
namespace Server.Mobiles;
public class MeleeAI : BaseAI
{
public MeleeAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have no combatant");
}
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
}
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet)
{
if (m_Mobile.Debug)
{
base.DoActionWander();
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
}
Action = ActionType.Guard;
return true;
}
public override bool DoActionCombat()
if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception))
{
var combatant = m_Mobile.Combatant;
// They are somewhat far away, can we find something else?
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet)
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
m_Mobile.Combatant = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
else if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception * 3))
{
m_Mobile.Combatant = null;
}
combatant = m_Mobile.Combatant;
if (combatant == null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant has fled, so I am on guard");
}
Action = ActionType.Guard;
return true;
}
}
if (!MoveTo(combatant, true, m_Mobile.RangeFight))
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"My move is blocked, so I am going to attack {m_Mobile.FocusMob!.Name}");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
return true;
}
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I cannot find {combatant.Name}, so my guard is up");
}
Action = ActionType.Guard;
return true;
}
if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception))
if (m_Mobile.Debug)
{
// They are somewhat far away, can we find something else?
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
m_Mobile.Combatant = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
else if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception * 3))
{
m_Mobile.Combatant = null;
}
combatant = m_Mobile.Combatant;
if (combatant == null)
{
m_Mobile.DebugSay("My combatant has fled, so I am on guard");
Action = ActionType.Guard;
return true;
}
m_Mobile.DebugSay($"I cannot find {combatant.Name}, so my guard is up");
}
}
if (!MoveTo(combatant, true, m_Mobile.RangeFight))
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee)
{
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100)
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
// We are low on health, should we flee?
var fleeChance = 10 + Math.Max(0, combatant.Hits - m_Mobile.Hits); // (10 + diff)% chance to flee;
if (Utility.Random(0, 100) < fleeChance)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My move is blocked, so I am going to attack {0}", m_Mobile.FocusMob?.Name ?? "null");
m_Mobile.DebugSay($"I am going to flee from {combatant.Name}");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
return true;
}
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I cannot find {0}, so my guard is up", combatant.Name);
}
Action = ActionType.Guard;
return true;
}
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
Action = ActionType.Flee;
}
}
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee)
{
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100)
{
// We are low on health, should we flee?
bool flee;
if (m_Mobile.Hits < combatant.Hits)
{
// We are more hurt than them
var diff = combatant.Hits - m_Mobile.Hits;
flee = Utility.Random(0, 100) < 10 + diff; // (10 + diff)% chance to flee
}
else
{
flee = Utility.Random(0, 100) < 10; // 10% chance to flee
}
if (flee)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am going to flee from {0}", combatant.Name);
}
Action = ActionType.Flee;
}
}
}
return true;
}
public override bool DoActionGuard()
return true;
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
if (m_Mobile.Debug)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
return true;
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
public override bool DoActionFlee()
return true;
}
public override bool DoActionFlee()
{
if (m_Mobile.Hits > m_Mobile.HitsMax / 2)
{
if (m_Mobile.Hits > m_Mobile.HitsMax / 2)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am stronger now, so I will continue fighting");
Action = ActionType.Combat;
}
else
{
m_Mobile.FocusMob = m_Mobile.Combatant;
base.DoActionFlee();
}
return true;
Action = ActionType.Combat;
}
else
{
m_Mobile.FocusMob = m_Mobile.Combatant;
base.DoActionFlee();
}
return true;
}
}
}

View file

@ -1,82 +1,104 @@
namespace Server.Mobiles
{
public class PredatorAI : BaseAI
{
public PredatorAI(BaseCreature m) : base(m)
{
}
namespace Server.Mobiles;
public override bool DoActionWander()
public class PredatorAI : BaseAI
{
public PredatorAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
if (m_Mobile.Combatant != null)
{
if (m_Mobile.Combatant != null)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am hurt or being attacked, I kill him");
Action = ActionType.Combat;
}
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, true, false, true))
{
m_Mobile.DebugSay("There is something near, I go away");
Action = ActionType.Backoff;
}
else
{
base.DoActionWander();
}
Action = ActionType.Combat;
}
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, true, false, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("There is something near, I go away");
}
Action = ActionType.Backoff;
}
else
{
base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
}
Action = ActionType.Wander;
return true;
}
public override bool DoActionCombat()
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I cannot find {combatant.Name}");
}
Action = ActionType.Wander;
return true;
}
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
if (m_Mobile.Debug)
{
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
m_Mobile.DebugSay("I cannot find {0}", combatant.Name);
Action = ActionType.Wander;
return true;
}
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
m_Mobile.DebugSay($"I should be closer to {combatant.Name}");
}
return true;
}
public override bool DoActionBackoff()
{
if (m_Mobile.IsHurt() || m_Mobile.Combatant != null)
{
Action = ActionType.Combat;
}
else
{
if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false, true))
{
if (WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2))
{
m_Mobile.DebugSay("Well, here I am safe");
Action = ActionType.Wander;
}
}
else
{
m_Mobile.DebugSay("I have lost my focus, lets relax");
Action = ActionType.Wander;
}
}
return true;
}
return true;
}
}
public override bool DoActionBackoff()
{
if (m_Mobile.IsHurt() || m_Mobile.Combatant != null)
{
Action = ActionType.Combat;
}
else if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false, true))
{
if (WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("Well, here I am safe");
}
Action = ActionType.Wander;
}
}
else
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have lost my focus, lets relax");
}
Action = ActionType.Wander;
}
return true;
}
}

View file

@ -1,179 +1,214 @@
using System;
using Server.Items;
namespace Server.Mobiles
namespace Server.Mobiles;
public class ThiefAI : BaseAI
{
public class ThiefAI : BaseAI
private Item m_toDisarm;
public ThiefAI(BaseCreature m) : base(m)
{
private Item m_toDisarm;
}
public ThiefAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
public override bool DoActionWander()
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have no combatant");
}
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
{
if (m_Mobile.Debug)
{
base.DoActionWander();
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
}
Action = ActionType.Guard;
return true;
}
public override bool DoActionCombat()
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
{
var combatant = m_Mobile.Combatant;
if (combatant?.Deleted != false || combatant.Map != m_Mobile.Map)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
Action = ActionType.Guard;
return true;
m_Mobile.DebugSay($"I should be closer to {combatant.Name}");
}
}
else
{
if (m_toDisarm?.IsChildOf(m_Mobile.Backpack) != false)
{
m_toDisarm = combatant.FindItemOnLayer(Layer.OneHanded) ?? combatant.FindItemOnLayer(Layer.TwoHanded);
}
if (!WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
if (!Core.AOS && !m_Mobile.DisarmReady && m_Mobile.Skills.Wrestling.Value >= 80.0 &&
m_Mobile.Skills.ArmsLore.Value >= 80.0 && m_toDisarm != null)
{
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
EventSink.InvokeDisarmRequest(m_Mobile);
}
else
if (m_toDisarm?.IsChildOf(combatant.Backpack) == true &&
Core.TickCount - m_Mobile.NextSkillTime >= 0 && m_toDisarm.LootType != LootType.Blessed &&
m_toDisarm.LootType != LootType.Newbied)
{
if (m_toDisarm?.IsChildOf(m_Mobile.Backpack) != false)
{
m_toDisarm = combatant.FindItemOnLayer(Layer.OneHanded) ?? combatant.FindItemOnLayer(Layer.TwoHanded);
}
if (!Core.AOS && !m_Mobile.DisarmReady && m_Mobile.Skills.Wrestling.Value >= 80.0 &&
m_Mobile.Skills.ArmsLore.Value >= 80.0 && m_toDisarm != null)
{
EventSink.InvokeDisarmRequest(m_Mobile);
}
if (m_toDisarm?.IsChildOf(combatant.Backpack) == true &&
Core.TickCount - m_Mobile.NextSkillTime >= 0 && m_toDisarm.LootType != LootType.Blessed &&
m_toDisarm.LootType != LootType.Newbied)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("Trying to steal from combatant.");
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, m_toDisarm);
}
else if (m_toDisarm == null && Core.TickCount - m_Mobile.NextSkillTime >= 0)
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, m_toDisarm);
}
else if (m_toDisarm == null && Core.TickCount - m_Mobile.NextSkillTime >= 0)
{
var cpack = combatant.Backpack;
if (cpack != null)
{
var cpack = combatant.Backpack;
if (cpack != null)
Item steala = cpack.FindItemByType<Bandage>();
if (steala != null)
{
Item steala = cpack.FindItemByType<Bandage>();
if (steala != null)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("Trying to steal from combatant.");
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, steala);
}
Item stealb = cpack.FindItemByType<Nightshade>();
if (stealb != null)
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, steala);
}
Item stealb = cpack.FindItemByType<Nightshade>();
if (stealb != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("Trying to steal from combatant.");
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, stealb);
}
Item stealc = cpack.FindItemByType<BlackPearl>();
if (stealc != null)
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, stealb);
}
Item stealc = cpack.FindItemByType<BlackPearl>();
if (stealc != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("Trying to steal from combatant.");
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, stealc);
}
Item steald = cpack.FindItemByType<MandrakeRoot>();
if (steald != null)
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, stealc);
}
Item steald = cpack.FindItemByType<MandrakeRoot>();
if (steald != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("Trying to steal from combatant.");
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, steald);
}
else if (steala == null && stealb == null && stealc == null)
{
m_Mobile.DebugSay("I am going to flee from {0}", combatant.Name);
Action = ActionType.Flee;
m_Mobile.UseSkill(SkillName.Stealing);
m_Mobile.Target?.Invoke(m_Mobile, steald);
}
else if (steala == null && stealb == null && stealc == null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I am going to flee from {combatant.Name}");
}
Action = ActionType.Flee;
}
}
}
}
if (m_Mobile.Hits >= m_Mobile.HitsMax * 20 / 100 || !m_Mobile.CanFlee)
{
return true;
}
// We are low on health, should we flee?
bool flee;
if (m_Mobile.Hits < combatant.Hits)
{
// We are more hurt than them
var diff = combatant.Hits - m_Mobile.Hits;
flee = Utility.Random(0, 100) > 10 + diff; // (10 + diff)% chance to flee
}
else
{
flee = Utility.Random(0, 100) > 10; // 10% chance to flee
}
if (flee)
{
m_Mobile.DebugSay("I am going to flee from {0}", combatant.Name);
Action = ActionType.Flee;
}
if (m_Mobile.Hits >= m_Mobile.HitsMax * 20 / 100 || !m_Mobile.CanFlee)
{
return true;
}
public override bool DoActionGuard()
// We are low on health, should we flee?
// (10 + diff)% chance to flee
var fleeChance = 10 + Math.Max(0, combatant.Hits - m_Mobile.Hits);
if (Utility.Random(0, 100) > fleeChance)
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
m_Mobile.DebugSay($"I am going to flee from {combatant.Name}");
}
return true;
Action = ActionType.Flee;
}
public override bool DoActionFlee()
return true;
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Hits > m_Mobile.HitsMax / 2)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"I have detected {m_Mobile.FocusMob.Name}, attacking");
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
public override bool DoActionFlee()
{
if (m_Mobile.Hits > m_Mobile.HitsMax / 2)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am stronger now, so I will continue fighting");
Action = ActionType.Combat;
}
else
{
m_Mobile.FocusMob = m_Mobile.Combatant;
base.DoActionFlee();
}
return true;
Action = ActionType.Combat;
}
else
{
m_Mobile.FocusMob = m_Mobile.Combatant;
base.DoActionFlee();
}
return true;
}
}
}

View file

@ -1,157 +1,158 @@
namespace Server.Mobiles
{
public class VendorAI : BaseAI
{
public VendorAI(BaseCreature m) : base(m)
{
}
namespace Server.Mobiles;
public override bool DoActionWander()
public class VendorAI : BaseAI
{
public VendorAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I'm fine");
}
if (m_Mobile.Combatant != null)
if (m_Mobile.Combatant != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"{m_Mobile.Combatant.Name} is attacking me");
}
m_Mobile.Say(Utility.RandomBool() ? 1005305 : 501603);
Action = ActionType.Flee;
}
else
{
if (m_Mobile.FocusMob != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} is attacking me", m_Mobile.Combatant.Name);
m_Mobile.DebugSay($"{m_Mobile.FocusMob.Name} has talked to me");
}
m_Mobile.Say(Utility.RandomList(1005305, 501603));
Action = ActionType.Flee;
Action = ActionType.Interact;
}
else
{
if (m_Mobile.FocusMob != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} has talked to me", m_Mobile.FocusMob.Name);
}
m_Mobile.Warmode = false;
Action = ActionType.Interact;
}
else
{
m_Mobile.Warmode = false;
base.DoActionWander();
}
base.DoActionWander();
}
}
return true;
}
public override bool DoActionInteract()
{
var customer = m_Mobile.FocusMob;
if (m_Mobile.Combatant != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"{m_Mobile.Combatant.Name} is attacking me");
}
m_Mobile.Say(Utility.RandomList(1005305, 501603));
Action = ActionType.Flee;
return true;
}
public override bool DoActionInteract()
if (customer?.Deleted != false || customer.Map != m_Mobile.Map)
{
var customer = m_Mobile.FocusMob;
if (m_Mobile.Combatant != null)
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} is attacking me", m_Mobile.Combatant.Name);
}
m_Mobile.Say(Utility.RandomList(1005305, 501603));
Action = ActionType.Flee;
return true;
}
if (customer?.Deleted != false || customer.Map != m_Mobile.Map)
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("My customer have disapeared");
m_Mobile.FocusMob = null;
Action = ActionType.Wander;
}
else
m_Mobile.FocusMob = null;
Action = ActionType.Wander;
}
else if (customer.InRange(m_Mobile, m_Mobile.RangeFight))
{
if (m_Mobile.Debug)
{
if (customer.InRange(m_Mobile, m_Mobile.RangeFight))
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("I am with {0}", customer.Name);
}
m_Mobile.Direction = m_Mobile.GetDirectionTo(customer);
}
else
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay("{0} is gone", customer.Name);
}
m_Mobile.FocusMob = null;
Action = ActionType.Wander;
}
m_Mobile.DebugSay($"I am with {customer.Name}");
}
m_Mobile.Direction = m_Mobile.GetDirectionTo(customer);
}
else
{
if (m_Mobile.Debug)
{
m_Mobile.DebugSay($"{customer.Name} is gone");
}
m_Mobile.FocusMob = null;
Action = ActionType.Wander;
}
return true;
}
public override bool DoActionGuard()
{
m_Mobile.FocusMob = m_Mobile.Combatant;
return base.DoActionGuard();
}
public override bool HandlesOnSpeech(Mobile from)
{
if (from.InRange(m_Mobile, 4))
{
return true;
}
public override bool DoActionGuard()
{
m_Mobile.FocusMob = m_Mobile.Combatant;
return base.DoActionGuard();
}
return base.HandlesOnSpeech(from);
}
public override bool HandlesOnSpeech(Mobile from)
// Temporary
public override void OnSpeech(SpeechEventArgs e)
{
base.OnSpeech(e);
var from = e.Mobile;
if (m_Mobile is BaseVendor vendor && from.InRange(m_Mobile, Core.AOS ? 1 : 4) && !e.Handled)
{
if (from.InRange(m_Mobile, 4))
if (e.HasKeyword(0x14D)) // *vendor sell*
{
return true;
e.Handled = true;
vendor.VendorSell(from);
vendor.FocusMob = from;
}
return base.HandlesOnSpeech(from);
}
// Temporary
public override void OnSpeech(SpeechEventArgs e)
{
base.OnSpeech(e);
var from = e.Mobile;
if (m_Mobile is BaseVendor vendor && from.InRange(m_Mobile, Core.AOS ? 1 : 4) && !e.Handled)
else if (e.HasKeyword(0x3C)) // *vendor buy*
{
if (e.HasKeyword(0x14D)) // *vendor sell*
e.Handled = true;
vendor.VendorBuy(from);
vendor.FocusMob = from;
}
else if (WasNamed(e.Speech))
{
if (e.HasKeyword(0x177)) // *sell*
{
e.Handled = true;
vendor.VendorSell(from);
vendor.FocusMob = from;
}
else if (e.HasKeyword(0x3C)) // *vendor buy*
else if (e.HasKeyword(0x171)) // *buy*
{
e.Handled = true;
vendor.VendorBuy(from);
vendor.FocusMob = from;
}
else if (WasNamed(e.Speech))
{
if (e.HasKeyword(0x177)) // *sell*
{
e.Handled = true;
vendor.VendorSell(from);
}
else if (e.HasKeyword(0x171)) // *buy*
{
e.Handled = true;
vendor.VendorBuy(from);
}
vendor.FocusMob = from;
}
vendor.FocusMob = from;
}
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.ConPVP;
@ -2271,20 +2272,11 @@ namespace Server.Mobiles
base.OnAfterDelete();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DebugSay(string text)
{
if (Debug)
{
PublicOverheadMessage(MessageType.Regular, 41, false, text);
}
}
public void DebugSay(string format, params object[] args)
{
if (Debug)
{
PublicOverheadMessage(MessageType.Regular, 41, false, string.Format(format, args));
}
// Moved the debug check to implementation layer so we can avoid string formatting when we do not need it
PublicOverheadMessage(MessageType.Regular, 41, false, text);
}
/*