Fixes code according to modern code style. Fixes a few expression bugs.

This commit is contained in:
Kamron Batman 2018-09-15 09:58:51 -07:00
parent 89eea25e5f
commit 970fd563b2
3324 changed files with 441118 additions and 433755 deletions

View file

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

View file

@ -1,5 +1,3 @@
// Ideas
// When you run on animals the panic
// When if ( distance < 8 && Utility.RandomDouble() * Math.Sqrt( (8 - distance) / 6 ) >= incoming.Skills[SkillName.AnimalTaming].Value )
@ -7,19 +5,19 @@
/*
* AnimalHunterAI, AnimalHidingAI, AnimalDomesticAI...
*
*/
*/
namespace Server.Mobiles
{
public class AnimalAI : BaseAI
{
public AnimalAI(BaseCreature m) : base (m)
{
}
public class AnimalAI : BaseAI
{
public AnimalAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
// Old:
public override bool DoActionWander()
{
// Old:
#if false
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, true, false, true))
{
@ -39,114 +37,114 @@ namespace Server.Mobiles
return true;
#endif
// New, only flee @ 10%
// New, only flee @ 10%
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
double 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
{
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 );
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 && m_Mobile.CanFlee) // Less than 10% health
{
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
{
base.DoActionWander();
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
return true;
}
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
if ( combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map )
{
m_Mobile.DebugSay( "My combatant is gone.." );
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map)
{
m_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 ) )
{
m_Mobile.Direction = m_Mobile.GetDirectionTo( combatant );
}
else
{
if ( m_Mobile.GetDistanceToSqrt( combatant ) > m_Mobile.RangePerception + 1 )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I cannot find {0}", combatant.Name );
if (WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
{
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
}
else
{
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;
Action = ActionType.Wander;
return true;
}
return true;
}
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I should be closer to {0}", combatant.Name );
}
if (m_Mobile.Debug)
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
}
if ( !m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee )
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (!m_Mobile.Controlled && !m_Mobile.Summoned && m_Mobile.CanFlee)
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if ( hitPercent < 0.1 )
{
m_Mobile.DebugSay( "I am low on health!" );
Action = ActionType.Flee;
}
}
if (hitPercent < 0.1)
{
m_Mobile.DebugSay("I am low on health!");
Action = ActionType.Flee;
}
}
return true;
}
return true;
}
public override bool DoActionBackoff()
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
public override bool DoActionBackoff()
{
double 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) )
{
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;
}
}
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))
{
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 DoActionFlee()
{
AcquireFocusMob(m_Mobile.RangePerception * 2, m_Mobile.FightMode, true, false, true);
public override bool DoActionFlee()
{
AcquireFocusMob(m_Mobile.RangePerception * 2, m_Mobile.FightMode, true, false, true);
if ( m_Mobile.FocusMob == null )
m_Mobile.FocusMob = m_Mobile.Combatant;
if (m_Mobile.FocusMob == null)
m_Mobile.FocusMob = m_Mobile.Combatant;
return base.DoActionFlee();
}
}
return base.DoActionFlee();
}
}
}

View file

@ -2,125 +2,119 @@ using Server.Items;
namespace Server.Mobiles
{
public class ArcherAI : BaseAI
{
public ArcherAI(BaseCreature m) : base (m)
{
}
public class ArcherAI : BaseAI
{
public ArcherAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
m_Mobile.DebugSay( "I have no combatant" );
public override bool DoActionWander()
{
m_Mobile.DebugSay("I have no combatant");
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I have detected {0} and I will attack", m_Mobile.FocusMob.Name );
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
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.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
return base.DoActionWander();
}
return true;
}
return true;
}
public override bool DoActionCombat()
{
if ( m_Mobile.Combatant == null || m_Mobile.Combatant.Deleted || !m_Mobile.Combatant.Alive || m_Mobile.Combatant.IsDeadBondedPet )
{
m_Mobile.DebugSay("My combatant is deleted");
Action = ActionType.Guard;
return true;
}
public override bool DoActionCombat()
{
if (m_Mobile.Combatant == null || m_Mobile.Combatant.Deleted || !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 (WalkMobileRange(m_Mobile.Combatant, 1, true, m_Mobile.RangeFight, m_Mobile.Weapon.MaxRange))
{
// Be sure to face the combatant
m_Mobile.Direction = m_Mobile.GetDirectionTo(m_Mobile.Combatant.Location);
}
else
{
if ( m_Mobile.Combatant != null )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I am still not in range of {0}", m_Mobile.Combatant.Name);
if (Core.TickCount - m_Mobile.LastMoveTime > 1000)
{
if (WalkMobileRange(m_Mobile.Combatant, 1, true, m_Mobile.RangeFight, m_Mobile.Weapon.MaxRange))
{
// Be sure to face the combatant
m_Mobile.Direction = m_Mobile.GetDirectionTo(m_Mobile.Combatant.Location);
}
else
{
if (m_Mobile.Combatant != null)
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("I am still not in range of {0}", 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);
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
Container pack = m_Mobile.Backpack;
// When we have no ammo, we flee
Container pack = m_Mobile.Backpack;
if ( pack?.FindItemByType( typeof( Arrow ) ) == null )
{
Action = ActionType.Flee;
return true;
}
if (pack?.FindItemByType(typeof(Arrow)) == null)
{
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 )
{
bool 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)
{
int 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;
}
}
// At 20% we should check if we must leave
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100 && m_Mobile.CanFlee)
{
bool 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)
{
int iDiff = m_Mobile.Combatant.Hits - m_Mobile.Hits;
return true;
}
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;
}
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 );
if (bFlee) Action = ActionType.Flee;
}
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 {0}, attacking", m_Mobile.FocusMob.Name);
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,82 +1,82 @@
namespace Server.Mobiles
{
public class BerserkAI : BaseAI
{
public BerserkAI(BaseCreature m) : base (m)
{
}
public class BerserkAI : BaseAI
{
public BerserkAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
m_Mobile.DebugSay( "I have No Combatant" );
public override bool DoActionWander()
{
m_Mobile.DebugSay("I have No Combatant");
if ( AcquireFocusMob( m_Mobile.RangePerception, FightMode.Closest, false, true, true) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I have detected " + m_Mobile.FocusMob.Name + " and I will attack" );
if (AcquireFocusMob(m_Mobile.RangePerception, FightMode.Closest, false, true, true))
{
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.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
return true;
}
public override bool DoActionCombat()
{
if ( m_Mobile.Combatant == null || m_Mobile.Combatant.Deleted )
{
m_Mobile.DebugSay("My combatant is deleted");
Action = ActionType.Guard;
return true;
}
public override bool DoActionCombat()
{
if (m_Mobile.Combatant == null || m_Mobile.Combatant.Deleted)
{
m_Mobile.DebugSay("My combatant is deleted");
Action = ActionType.Guard;
return true;
}
if ( WalkMobileRange( m_Mobile.Combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight ) )
{
// Be sure to face the combatant
m_Mobile.Direction = m_Mobile.GetDirectionTo( m_Mobile.Combatant.Location );
}
else
{
if ( m_Mobile.Combatant != null )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay("I am still not in range of " + m_Mobile.Combatant.Name);
if (WalkMobileRange(m_Mobile.Combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
{
// Be sure to face the combatant
m_Mobile.Direction = m_Mobile.GetDirectionTo(m_Mobile.Combatant.Location);
}
else
{
if (m_Mobile.Combatant != null)
{
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 );
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;
}
}
}
Action = ActionType.Guard;
return true;
}
}
}
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 );
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();
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
}
}
return true;
}
}
}

View file

@ -1,172 +1,154 @@
using Server.Targeting;
using Server.Spells.First;
using Server.Spells.Second;
using Server.Spells.Fourth;
using Server.Spells.Second;
using Server.Targeting;
namespace Server.Mobiles
{
public class HealerAI : BaseAI
{
private static NeedDelegate m_Cure = NeedCure;
private static NeedDelegate m_GHeal = NeedGHeal;
private static NeedDelegate m_LHeal = NeedLHeal;
private static NeedDelegate[] m_ACure = { m_Cure };
private static NeedDelegate[] m_AGHeal = { m_GHeal };
private static NeedDelegate[] m_ALHeal = { m_LHeal };
private static NeedDelegate[] m_All = { m_Cure, m_GHeal, m_LHeal };
public class HealerAI : BaseAI
{
private static NeedDelegate m_Cure = NeedCure;
private static NeedDelegate m_GHeal = NeedGHeal;
private static NeedDelegate m_LHeal = NeedLHeal;
private static NeedDelegate[] m_ACure = { m_Cure };
private static NeedDelegate[] m_AGHeal = { m_GHeal };
private static NeedDelegate[] m_ALHeal = { m_LHeal };
private static NeedDelegate[] m_All = { m_Cure, m_GHeal, m_LHeal };
public HealerAI( BaseCreature m ) : base( m )
{
}
public HealerAI(BaseCreature m) : base(m)
{
}
public override bool Think()
{
if ( m_Mobile.Deleted )
return false;
public override bool Think()
{
if (m_Mobile.Deleted)
return false;
Target targ = m_Mobile.Target;
Target targ = m_Mobile.Target;
if ( targ != null )
{
if ( targ is CureSpell.InternalTarget )
{
ProcessTarget( targ, m_ACure );
}
else if ( targ is GreaterHealSpell.InternalTarget )
{
ProcessTarget( targ, m_AGHeal );
}
else if ( targ is HealSpell.InternalTarget )
{
ProcessTarget( targ, m_ALHeal );
}
else
{
targ.Cancel( m_Mobile, TargetCancelType.Canceled );
}
}
else
{
Mobile toHelp = Find( m_All );
if (targ != null)
{
if (targ is CureSpell.InternalTarget)
ProcessTarget(targ, m_ACure);
else if (targ is GreaterHealSpell.InternalTarget)
ProcessTarget(targ, m_AGHeal);
else if (targ is HealSpell.InternalTarget)
ProcessTarget(targ, m_ALHeal);
else
targ.Cancel(m_Mobile, TargetCancelType.Canceled);
}
else
{
Mobile toHelp = Find(m_All);
if ( toHelp != null )
{
if ( NeedCure( toHelp ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "{0} needs a cure", toHelp.Name );
if (toHelp != null)
{
if (NeedCure(toHelp))
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("{0} needs a cure", toHelp.Name);
if ( !(new CureSpell( m_Mobile, null )).Cast() )
new CureSpell( m_Mobile, null ).Cast();
}
else if ( NeedGHeal( toHelp ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "{0} needs a greater heal", toHelp.Name );
if (!new CureSpell(m_Mobile, null).Cast())
new CureSpell(m_Mobile, null).Cast();
}
else if (NeedGHeal(toHelp))
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("{0} needs a greater heal", toHelp.Name);
if ( !(new GreaterHealSpell( m_Mobile, null )).Cast() )
new HealSpell( m_Mobile, null ).Cast();
}
else if ( NeedLHeal( toHelp ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "{0} needs a lesser heal", toHelp.Name );
if (!new GreaterHealSpell(m_Mobile, null).Cast())
new HealSpell(m_Mobile, null).Cast();
}
else if (NeedLHeal(toHelp))
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("{0} needs a lesser heal", toHelp.Name);
new HealSpell( m_Mobile, null ).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 );
}
}
}
new HealSpell(m_Mobile, null).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;
}
return true;
}
private delegate bool NeedDelegate( Mobile m );
private void ProcessTarget(Target targ, NeedDelegate[] func)
{
Mobile toHelp = Find(func);
private void ProcessTarget( Target targ, NeedDelegate[] func )
{
Mobile 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);
}
else
{
targ.Cancel(m_Mobile, TargetCancelType.Canceled);
}
}
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 );
}
}
else
{
targ.Cancel( m_Mobile, TargetCancelType.Canceled );
}
}
private Mobile Find(params NeedDelegate[] funcs)
{
if (m_Mobile.Deleted)
return null;
private Mobile Find( params NeedDelegate[] funcs )
{
if ( m_Mobile.Deleted )
return null;
Map map = m_Mobile.Map;
Map map = m_Mobile.Map;
if (map != null)
{
double prio = 0.0;
Mobile found = null;
if ( map != null )
{
double prio = 0.0;
Mobile found = null;
foreach (Mobile m in m_Mobile.GetMobilesInRange(m_Mobile.RangePerception))
{
if (!m_Mobile.CanSee(m) || !(m is BaseCreature) || ((BaseCreature)m).Team != m_Mobile.Team)
continue;
foreach ( Mobile m in m_Mobile.GetMobilesInRange( m_Mobile.RangePerception ) )
{
if ( !m_Mobile.CanSee( m ) || !(m is BaseCreature) || ((BaseCreature)m).Team != m_Mobile.Team )
continue;
for (int i = 0; i < funcs.Length; ++i)
if (funcs[i](m))
{
double val = -m_Mobile.GetDistanceToSqrt(m);
for ( int i = 0; i < funcs.Length; ++i )
{
if ( funcs[i]( m ) )
{
double val = -m_Mobile.GetDistanceToSqrt( m );
if (found == null || val > prio)
{
prio = val;
found = m;
}
if ( found == null || val > prio )
{
prio = val;
found = m;
}
break;
}
}
break;
}
}
}
return found;
}
return found;
}
return null;
}
return null;
}
private static bool NeedCure(Mobile m)
{
return m.Poisoned;
}
private static bool NeedCure( Mobile m )
{
return m.Poisoned;
}
private static bool NeedGHeal(Mobile m)
{
return m.Hits < m.HitsMax - 40;
}
private static bool NeedGHeal( Mobile m )
{
return m.Hits < m.HitsMax - 40;
}
private static bool NeedLHeal(Mobile m)
{
return m.Hits < m.HitsMax - 10;
}
private static bool NeedLHeal( Mobile m )
{
return m.Hits < m.HitsMax - 10;
}
}
private delegate bool NeedDelegate(Mobile m);
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,3 @@
//
// This is a first simple AI
//
@ -7,174 +5,173 @@
namespace Server.Mobiles
{
public class MeleeAI : BaseAI
{
public MeleeAI(BaseCreature m) : base (m)
{
}
public class MeleeAI : BaseAI
{
public MeleeAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
m_Mobile.DebugSay( "I have no combatant" );
public override bool DoActionWander()
{
m_Mobile.DebugSay("I have no combatant");
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 );
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.DoActionWander();
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
return true;
}
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
if ( combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || combatant.IsDeadBondedPet )
{
m_Mobile.DebugSay( "My combatant is gone, so my guard is up" );
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive ||
combatant.IsDeadBondedPet)
{
m_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 ) )
{
// They are somewhat far away, can we find something else?
if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception))
{
// 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;
}
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;
combatant = m_Mobile.Combatant;
if ( combatant == null )
{
m_Mobile.DebugSay( "My combatant has fled, so I am on guard" );
Action = ActionType.Guard;
if (combatant == null)
{
m_Mobile.DebugSay("My combatant has fled, so I am on guard");
Action = ActionType.Guard;
return true;
}
}
return true;
}
}
/*if ( !m_Mobile.InLOS( combatant ) )
{
if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
m_Mobile.Combatant = combatant = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
}*/
/*if ( !m_Mobile.InLOS( combatant ) )
{
if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
m_Mobile.Combatant = combatant = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
}*/
if ( MoveTo( combatant, true, m_Mobile.RangeFight ) )
{
m_Mobile.Direction = m_Mobile.GetDirectionTo( combatant );
}
else 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 {0}", m_Mobile.FocusMob.Name );
if (MoveTo(combatant, true, m_Mobile.RangeFight))
{
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
}
else 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 {0}", m_Mobile.FocusMob.Name);
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
return true;
}
else 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 );
return true;
}
else 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;
Action = ActionType.Guard;
return true;
}
else
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I should be closer to {0}", combatant.Name );
}
return true;
}
else
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
}
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?
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 = false;
bool flee = false;
if ( m_Mobile.Hits < combatant.Hits )
{
// We are more hurt than them
if (m_Mobile.Hits < combatant.Hits)
{
// We are more hurt than them
int diff = combatant.Hits - m_Mobile.Hits;
int 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
}
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 );
if (flee)
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("I am going to flee from {0}", combatant.Name);
Action = ActionType.Flee;
}
}
}
Action = ActionType.Flee;
}
}
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 {0}, attacking", m_Mobile.FocusMob.Name );
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();
}
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
return true;
}
public override bool DoActionFlee()
{
if ( m_Mobile.Hits > m_Mobile.HitsMax/2 )
{
m_Mobile.DebugSay( "I am stronger now, so I will continue fighting" );
Action = ActionType.Combat;
}
else
{
m_Mobile.FocusMob = m_Mobile.Combatant;
base.DoActionFlee();
}
public override bool DoActionFlee()
{
if (m_Mobile.Hits > m_Mobile.HitsMax / 2)
{
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;
}
}
return true;
}
}
}

View file

@ -3,124 +3,124 @@ using Server.Mobiles;
namespace Server
{
public class OppositionGroup
{
private Type[][] m_Types;
public class OppositionGroup
{
private Type[][] m_Types;
public OppositionGroup( Type[][] types )
{
m_Types = types;
}
public OppositionGroup(Type[][] types)
{
m_Types = types;
}
public bool IsEnemy( object from, object target )
{
int fromGroup = IndexOf( from );
int targGroup = IndexOf( target );
public static OppositionGroup TerathansAndOphidians{ get; } = new OppositionGroup(new[]
{
new[]
{
typeof(TerathanAvenger),
typeof(TerathanDrone),
typeof(TerathanMatriarch),
typeof(TerathanWarrior)
},
new[]
{
typeof(OphidianArchmage),
typeof(OphidianKnight),
typeof(OphidianMage),
typeof(OphidianMatriarch),
typeof(OphidianWarrior)
}
});
return ( fromGroup != -1 && targGroup != -1 && fromGroup != targGroup );
}
public static OppositionGroup SavagesAndOrcs{ get; } = new OppositionGroup(new[]
{
new[]
{
typeof(Orc),
typeof(OrcBomber),
typeof(OrcBrute),
typeof(OrcCaptain),
typeof(OrcishLord),
typeof(OrcishMage),
typeof(SpawnedOrcishLord)
},
new[]
{
typeof(Savage),
typeof(SavageRider),
typeof(SavageRidgeback),
typeof(SavageShaman)
}
});
public int IndexOf( object obj )
{
if ( obj == null )
return -1;
public static OppositionGroup FeyAndUndead{ get; } = new OppositionGroup(new[]
{
new[]
{
typeof(Centaur),
typeof(EtherealWarrior),
typeof(Kirin),
typeof(LordOaks),
typeof(Pixie),
typeof(Silvani),
typeof(Unicorn),
typeof(Wisp),
typeof(Treefellow),
typeof(MLDryad),
typeof(Satyr)
},
new[]
{
typeof(AncientLich),
typeof(Bogle),
typeof(LichLord),
typeof(Shade),
typeof(Spectre),
typeof(Wraith),
typeof(BoneKnight),
typeof(Ghoul),
typeof(Mummy),
typeof(SkeletalKnight),
typeof(Skeleton),
typeof(Zombie),
typeof(ShadowKnight),
typeof(DarknightCreeper),
typeof(RevenantLion),
typeof(LadyOfTheSnow),
typeof(RottingCorpse),
typeof(SkeletalDragon),
typeof(Lich)
}
});
Type type = obj.GetType();
public bool IsEnemy(object from, object target)
{
int fromGroup = IndexOf(from);
int targGroup = IndexOf(target);
for ( int i = 0; i < m_Types.Length; ++i )
{
Type[] group = m_Types[i];
return fromGroup != -1 && targGroup != -1 && fromGroup != targGroup;
}
bool contains = false;
public int IndexOf(object obj)
{
if (obj == null)
return -1;
for ( int j = 0; !contains && j < group.Length; ++j )
contains = group[j].IsAssignableFrom( type );
Type type = obj.GetType();
if ( contains )
return i;
}
for (int i = 0; i < m_Types.Length; ++i)
{
Type[] group = m_Types[i];
return -1;
}
bool contains = false;
public static OppositionGroup TerathansAndOphidians { get; } = new OppositionGroup( new[]
{
new[]
{
typeof( TerathanAvenger ),
typeof( TerathanDrone ),
typeof( TerathanMatriarch ),
typeof( TerathanWarrior )
},
new[]
{
typeof( OphidianArchmage ),
typeof( OphidianKnight ),
typeof( OphidianMage ),
typeof( OphidianMatriarch ),
typeof( OphidianWarrior )
}
} );
for (int j = 0; !contains && j < group.Length; ++j)
contains = group[j].IsAssignableFrom(type);
public static OppositionGroup SavagesAndOrcs { get; } = new OppositionGroup( new[]
{
new[]
{
typeof( Orc ),
typeof( OrcBomber ),
typeof( OrcBrute ),
typeof( OrcCaptain ),
typeof( OrcishLord ),
typeof( OrcishMage ),
typeof( SpawnedOrcishLord )
},
new[]
{
typeof( Savage ),
typeof( SavageRider ),
typeof( SavageRidgeback ),
typeof( SavageShaman )
}
} );
if (contains)
return i;
}
public static OppositionGroup FeyAndUndead { get; } = new OppositionGroup( new[]
{
new[]
{
typeof( Centaur ),
typeof( EtherealWarrior ),
typeof( Kirin ),
typeof( LordOaks ),
typeof( Pixie ),
typeof( Silvani ),
typeof( Unicorn ),
typeof( Wisp ),
typeof( Treefellow ),
typeof( MLDryad ),
typeof( Satyr )
},
new[]
{
typeof( AncientLich ),
typeof( Bogle ),
typeof( LichLord ),
typeof( Shade ),
typeof( Spectre ),
typeof( Wraith ),
typeof( BoneKnight ),
typeof( Ghoul ),
typeof( Mummy ),
typeof( SkeletalKnight ),
typeof( Skeleton ),
typeof( Zombie ),
typeof( ShadowKnight ),
typeof( DarknightCreeper ),
typeof( RevenantLion ),
typeof( LadyOfTheSnow ),
typeof( RottingCorpse ),
typeof( SkeletalDragon ),
typeof( Lich )
}
} );
}
return -1;
}
}
}

View file

@ -1,95 +1,92 @@
/*
* PredatorAI, its an animal that can attack
* Dont flee but dont attack if not hurt or attacked
*
*/
*/
namespace Server.Mobiles
{
public class PredatorAI : BaseAI
{
public PredatorAI(BaseCreature m) : base (m)
{
}
public class PredatorAI : BaseAI
{
public PredatorAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
if ( m_Mobile.Combatant != null )
{
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();
}
public override bool DoActionWander()
{
if (m_Mobile.Combatant != null)
{
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();
}
return true;
}
return true;
}
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
if ( combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map )
{
m_Mobile.DebugSay( "My combatant is gone, so my guard is up" );
Action = ActionType.Wander;
return true;
}
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map)
{
m_Mobile.DebugSay("My combatant is gone, so my guard is up");
Action = ActionType.Wander;
return true;
}
if ( WalkMobileRange( combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight ) )
{
m_Mobile.Direction = m_Mobile.GetDirectionTo( combatant );
}
else
{
if ( m_Mobile.GetDistanceToSqrt( combatant ) > m_Mobile.RangePerception + 1 )
{
m_Mobile.DebugSay( "I cannot find {0}", combatant.Name );
if (WalkMobileRange(combatant, 1, true, m_Mobile.RangeFight, m_Mobile.RangeFight))
{
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant);
}
else
{
if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
m_Mobile.DebugSay("I cannot find {0}", combatant.Name);
Action = ActionType.Wander;
return true;
}
Action = ActionType.Wander;
return true;
}
m_Mobile.DebugSay( "I should be closer to {0}", combatant.Name );
}
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
}
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) )
{
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;
}
}
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;
}
}
}

View file

@ -1,206 +1,210 @@
using System;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Factions;
using Server.Mobiles;
namespace Server
{
public class SpeedInfo
{
// Should we use the new method of speeds?
private static bool Enabled = true;
public class SpeedInfo
{
// Should we use the new method of speeds?
private static bool Enabled = true;
public double ActiveSpeed { get; set; }
private static Dictionary<Type, SpeedInfo> m_Table;
public double PassiveSpeed { get; set; }
private static SpeedInfo[] m_Speeds =
{
/* Slow */
new SpeedInfo(0.3, 0.6, new[]
{
typeof(AntLion), typeof(ArcticOgreLord), typeof(BogThing),
typeof(Bogle), typeof(BoneKnight), typeof(EarthElemental),
typeof(Ettin), typeof(FrostOoze), typeof(FrostTroll),
typeof(GazerLarva), typeof(Ghoul), typeof(Golem),
typeof(HeadlessOne), typeof(Jwilson), typeof(Mummy),
typeof(Ogre), typeof(OgreLord), typeof(PlagueBeast),
typeof(Quagmire), typeof(Rat), typeof(RottingCorpse),
typeof(SewerRat), typeof(Skeleton), typeof(Slime),
typeof(Zombie), typeof(Walrus), typeof(RestlessSoul),
typeof(CrystalElemental), typeof(DarknightCreeper), typeof(MoundOfMaggots),
typeof(Juggernaut), typeof(Yamandon), typeof(Serado)
}),
/* Fast */
new SpeedInfo(0.2, 0.4, new[]
{
typeof(LordOaks), typeof(Silvani), typeof(AirElemental),
typeof(AncientWyrm), typeof(Balron), typeof(BladeSpirits),
typeof(DreadSpider), typeof(Efreet), typeof(EtherealWarrior),
typeof(Lich), typeof(Nightmare), typeof(OphidianArchmage),
typeof(OphidianMage), typeof(OphidianWarrior), typeof(OphidianMatriarch),
typeof(OphidianKnight), typeof(PoisonElemental), typeof(Revenant),
typeof(SandVortex), typeof(SavageRider), typeof(SavageShaman),
typeof(SnowElemental), typeof(WhiteWyrm), typeof(Wisp),
typeof(DemonKnight), typeof(GiantBlackWidow), typeof(SummonedAirElemental),
typeof(LesserHiryu), typeof(Hiryu), typeof(LadyOfTheSnow),
typeof(RaiJu), typeof(Ronin), typeof(RuneBeetle),
typeof(Changeling),
public Type[] Types { get; set; }
#region ML named mobs - before Paragon speedboost
public SpeedInfo( double activeSpeed, double passiveSpeed, Type[] types )
{
ActiveSpeed = activeSpeed;
PassiveSpeed = passiveSpeed;
Types = types;
}
typeof(LadyJennifyr), typeof(LadyMarai), typeof(MasterJonath),
typeof(MasterMikael), typeof(MasterTheophilus), typeof(RedDeath),
typeof(SirPatrick), typeof(Miasma), typeof(Rend),
typeof(Grobu), typeof(Gnaw), typeof(Guile),
typeof(Irk), typeof(Spite), typeof(LadyLissith),
typeof(LadySabrix), typeof(Malefic), typeof(Silk),
typeof(Virulent)
// TODO: Where to put Lurg, Putrefier, Swoop and Pyre? They seem slower.
public static bool Contains( object obj )
{
if ( !Enabled )
return false;
#endregion
}),
/* Very Fast */
new SpeedInfo(0.175, 0.350, new[]
{
typeof(Barracoon), typeof(Mephitis), typeof(Neira),
typeof(Rikktor), typeof(Semidar), typeof(EnergyVortex),
typeof(EliteNinja), typeof(Pixie), typeof(SilverSerpent),
typeof(VorpalBunny), typeof(FleshRenderer), typeof(KhaldunRevenant),
typeof(FactionDragoon), typeof(FactionKnight), typeof(FactionPaladin),
typeof(FactionHenchman), typeof(FactionMercenary), typeof(FactionNecromancer),
typeof(FactionSorceress), typeof(FactionWizard), typeof(FactionBerserker),
typeof(FactionPaladin), typeof(Leviathan), typeof(FireBeetle),
typeof(FanDancer), typeof(FactionDeathKnight)
}),
/* Medium */
new SpeedInfo(0.25, 0.5, new[]
{
typeof(AcidElemental), typeof(AgapiteElemental), typeof(Alligator),
typeof(AncientLich), typeof(Betrayer), typeof(Bird),
typeof(BlackBear), typeof(BlackSolenInfiltratorQueen), typeof(BlackSolenInfiltratorWarrior),
typeof(BlackSolenQueen), typeof(BlackSolenWarrior), typeof(BlackSolenWorker),
typeof(BloodElemental), typeof(Boar), typeof(Bogling),
typeof(BoneMagi), typeof(Brigand), typeof(BronzeElemental),
typeof(BrownBear), typeof(Bull), typeof(BullFrog),
typeof(Cat), typeof(Centaur), typeof(ChaosDaemon),
typeof(Chicken), typeof(GolemController), typeof(CopperElemental),
typeof(CopperElemental), typeof(Cougar), typeof(Cow),
typeof(Cyclops), typeof(Daemon), typeof(DeepSeaSerpent),
typeof(DesertOstard), typeof(DireWolf), typeof(Dog),
typeof(Dolphin), typeof(Dragon), typeof(Drake),
typeof(DullCopperElemental), typeof(Eagle), typeof(ElderGazer),
typeof(EvilMage), typeof(EvilMageLord), typeof(Executioner),
typeof(Savage), typeof(FireElemental), typeof(FireGargoyle),
typeof(FireSteed), typeof(ForestOstard), typeof(FrenziedOstard),
typeof(FrostSpider), typeof(Gargoyle), typeof(Gazer),
typeof(IceSerpent), typeof(GiantRat), typeof(GiantSerpent),
typeof(GiantSpider), typeof(GiantToad), typeof(Goat),
typeof(GoldenElemental), typeof(Gorilla), typeof(GreatHart),
typeof(GreyWolf), typeof(GrizzlyBear), typeof(Guardian),
typeof(Harpy), typeof(Harrower), typeof(HellHound),
typeof(Hind), typeof(HordeMinion), typeof(Horse),
typeof(Horse), typeof(IceElemental), typeof(IceFiend),
typeof(IceSnake), typeof(Imp), typeof(JackRabbit),
typeof(Kirin), typeof(Kraken), typeof(PredatorHellCat),
typeof(LavaLizard), typeof(LavaSerpent), typeof(LavaSnake),
typeof(Lizardman), typeof(Llama), typeof(Mongbat),
typeof(StrongMongbat), typeof(MountainGoat), typeof(Orc),
typeof(OrcBomber), typeof(OrcBrute), typeof(OrcCaptain),
typeof(OrcishLord), typeof(OrcishMage), typeof(PackHorse),
typeof(PackLlama), typeof(Panther), typeof(Pig),
typeof(PlagueSpawn), typeof(PolarBear), typeof(Rabbit),
typeof(Ratman), typeof(RatmanArcher), typeof(RatmanMage),
typeof(RedSolenInfiltratorQueen), typeof(RedSolenInfiltratorWarrior), typeof(RedSolenQueen),
typeof(RedSolenWarrior), typeof(RedSolenWorker), typeof(RidableLlama),
typeof(Ridgeback), typeof(Scorpion), typeof(SeaSerpent),
typeof(SerpentineDragon), typeof(Shade), typeof(ShadowIronElemental),
typeof(ShadowWisp), typeof(ShadowWyrm), typeof(Sheep),
typeof(SilverSteed), typeof(SkeletalDragon), typeof(SkeletalMage),
typeof(SkeletalMount), typeof(HellCat), typeof(Snake),
typeof(SnowLeopard), typeof(SpectralArmour), typeof(Spectre),
typeof(StoneGargoyle), typeof(StoneHarpy), typeof(SwampDragon),
typeof(ScaledSwampDragon), typeof(SwampTentacle), typeof(TerathanAvenger),
typeof(TerathanDrone), typeof(TerathanMatriarch), typeof(TerathanWarrior),
typeof(TimberWolf), typeof(Titan), typeof(Troll),
typeof(Unicorn), typeof(ValoriteElemental), typeof(VeriteElemental),
typeof(CoMWarHorse), typeof(MinaxWarHorse), typeof(SLWarHorse),
typeof(TBWarHorse), typeof(WaterElemental), typeof(WhippingVine),
typeof(WhiteWolf), typeof(Wraith), typeof(Wyvern),
typeof(KhaldunZealot), typeof(KhaldunSummoner), typeof(SavageRidgeback),
typeof(LichLord), typeof(SkeletalKnight), typeof(SummonedDaemon),
typeof(SummonedEarthElemental), typeof(SummonedWaterElemental), typeof(SummonedFireElemental),
typeof(MeerWarrior), typeof(MeerEternal), typeof(MeerMage),
typeof(MeerCaptain), typeof(JukaLord), typeof(JukaMage),
typeof(JukaWarrior), typeof(AbysmalHorror), typeof(BoneDemon),
typeof(Devourer), typeof(FleshGolem), typeof(Gibberling),
typeof(GoreFiend), typeof(Impaler), typeof(PatchworkSkeleton),
typeof(Ravager), typeof(ShadowKnight), typeof(SkitteringHopper),
typeof(Treefellow), typeof(VampireBat), typeof(WailingBanshee),
typeof(WandererOfTheVoid), typeof(Cursed), typeof(GrimmochDrummel),
typeof(LysanderGathenwale), typeof(MorgBergen), typeof(ShadowFiend),
typeof(SpectralArmour), typeof(TavaraSewel), typeof(ArcaneDaemon),
typeof(Doppleganger), typeof(EnslavedGargoyle), typeof(ExodusMinion),
typeof(ExodusOverseer), typeof(GargoyleDestroyer), typeof(GargoyleEnforcer),
typeof(Moloch), typeof(BakeKitsune), typeof(DeathwatchBeetleHatchling),
typeof(Kappa), typeof(KazeKemono), typeof(DeathwatchBeetle),
typeof(TsukiWolf), typeof(YomotsuElder), typeof(YomotsuPriest),
typeof(YomotsuWarrior), typeof(RevenantLion), typeof(Oni),
typeof(Gaman), typeof(Crane), typeof(Beetle)
})
};
if ( m_Table == null )
LoadTable();
public SpeedInfo(double activeSpeed, double passiveSpeed, Type[] types)
{
ActiveSpeed = activeSpeed;
PassiveSpeed = passiveSpeed;
Types = types;
}
m_Table.TryGetValue( obj.GetType(), out SpeedInfo sp );
public double ActiveSpeed{ get; set; }
return ( sp != null );
}
public double PassiveSpeed{ get; set; }
public static bool GetSpeeds( object obj, ref double activeSpeed, ref double passiveSpeed )
{
if ( !Enabled )
return false;
public Type[] Types{ get; set; }
if ( m_Table == null )
LoadTable();
public static bool Contains(object obj)
{
if (!Enabled)
return false;
m_Table.TryGetValue( obj.GetType(), out SpeedInfo sp );
if (m_Table == null)
LoadTable();
if ( sp == null )
return false;
m_Table.TryGetValue(obj.GetType(), out SpeedInfo sp);
activeSpeed = sp.ActiveSpeed;
passiveSpeed = sp.PassiveSpeed;
return sp != null;
}
return true;
}
public static bool GetSpeeds(object obj, ref double activeSpeed, ref double passiveSpeed)
{
if (!Enabled)
return false;
private static void LoadTable()
{
m_Table = new Dictionary<Type, SpeedInfo>();
if (m_Table == null)
LoadTable();
for ( int i = 0; i < m_Speeds.Length; ++i )
{
SpeedInfo info = m_Speeds[i];
Type[] types = info.Types;
m_Table.TryGetValue(obj.GetType(), out SpeedInfo sp);
for ( int j = 0; j < types.Length; ++j )
m_Table[types[j]] = info;
}
}
if (sp == null)
return false;
private static Dictionary<Type, SpeedInfo> m_Table;
activeSpeed = sp.ActiveSpeed;
passiveSpeed = sp.PassiveSpeed;
private static SpeedInfo[] m_Speeds = {
/* Slow */
new SpeedInfo( 0.3, 0.6, new[]
{
typeof( AntLion ), typeof( ArcticOgreLord ), typeof( BogThing ),
typeof( Bogle ), typeof( BoneKnight ), typeof( EarthElemental ),
typeof( Ettin ), typeof( FrostOoze ), typeof( FrostTroll ),
typeof( GazerLarva ), typeof( Ghoul ), typeof( Golem ),
typeof( HeadlessOne ), typeof( Jwilson ), typeof( Mummy ),
typeof( Ogre ), typeof( OgreLord ), typeof( PlagueBeast ),
typeof( Quagmire ), typeof( Rat ), typeof( RottingCorpse ),
typeof( SewerRat ), typeof( Skeleton ), typeof( Slime ),
typeof( Zombie ), typeof( Walrus ), typeof( RestlessSoul ),
typeof( CrystalElemental ), typeof( DarknightCreeper ), typeof( MoundOfMaggots ),
typeof( Juggernaut ), typeof( Yamandon ), typeof( Serado )
} ),
/* Fast */
new SpeedInfo( 0.2, 0.4, new[]
{
typeof( LordOaks ), typeof( Silvani ), typeof( AirElemental ),
typeof( AncientWyrm ), typeof( Balron ), typeof( BladeSpirits ),
typeof( DreadSpider ), typeof( Efreet ), typeof( EtherealWarrior ),
typeof( Lich ), typeof( Nightmare ), typeof( OphidianArchmage ),
typeof( OphidianMage ), typeof( OphidianWarrior ), typeof( OphidianMatriarch ),
typeof( OphidianKnight ), typeof( PoisonElemental ), typeof( Revenant ),
typeof( SandVortex ), typeof( SavageRider ), typeof( SavageShaman ),
typeof( SnowElemental ), typeof( WhiteWyrm ), typeof( Wisp ),
typeof( DemonKnight ), typeof( GiantBlackWidow ), typeof( SummonedAirElemental ),
typeof( LesserHiryu ), typeof( Hiryu ), typeof( LadyOfTheSnow ),
typeof( RaiJu ), typeof( Ronin ), typeof( RuneBeetle ),
typeof( Changeling ),
#region ML named mobs - before Paragon speedboost
typeof( LadyJennifyr ), typeof( LadyMarai ), typeof( MasterJonath ),
typeof( MasterMikael ), typeof( MasterTheophilus ), typeof( RedDeath ),
typeof( SirPatrick ), typeof( Miasma ), typeof( Rend ),
typeof( Grobu ), typeof( Gnaw ), typeof( Guile ),
typeof( Irk ), typeof( Spite ), typeof( LadyLissith ),
typeof( LadySabrix ), typeof( Malefic ), typeof( Silk ),
typeof( Virulent )
// TODO: Where to put Lurg, Putrefier, Swoop and Pyre? They seem slower.
#endregion
} ),
/* Very Fast */
new SpeedInfo( 0.175, 0.350, new[]
{
typeof( Barracoon ), typeof( Mephitis ), typeof( Neira ),
typeof( Rikktor ), typeof( Semidar ), typeof( EnergyVortex ),
typeof( EliteNinja ), typeof( Pixie ), typeof( SilverSerpent ),
typeof( VorpalBunny ), typeof( FleshRenderer ), typeof( KhaldunRevenant ),
typeof( FactionDragoon ), typeof( FactionKnight ), typeof( FactionPaladin ),
typeof( FactionHenchman ), typeof( FactionMercenary ), typeof( FactionNecromancer ),
typeof( FactionSorceress ), typeof( FactionWizard ), typeof( FactionBerserker ),
typeof( FactionPaladin ), typeof( Leviathan ), typeof( FireBeetle ),
typeof( FanDancer ), typeof( FactionDeathKnight )
} ),
/* Medium */
new SpeedInfo( 0.25, 0.5, new[]
{
typeof( AcidElemental ), typeof( AgapiteElemental ), typeof( Alligator ),
typeof( AncientLich ), typeof( Betrayer ), typeof( Bird ),
typeof( BlackBear ), typeof( BlackSolenInfiltratorQueen ), typeof( BlackSolenInfiltratorWarrior ),
typeof( BlackSolenQueen ), typeof( BlackSolenWarrior ), typeof( BlackSolenWorker ),
typeof( BloodElemental ), typeof( Boar ), typeof( Bogling ),
typeof( BoneMagi ), typeof( Brigand ), typeof( BronzeElemental ),
typeof( BrownBear ), typeof( Bull ), typeof( BullFrog ),
typeof( Cat ), typeof( Centaur ), typeof( ChaosDaemon ),
typeof( Chicken ), typeof( GolemController ), typeof( CopperElemental ),
typeof( CopperElemental ), typeof( Cougar ), typeof( Cow ),
typeof( Cyclops ), typeof( Daemon ), typeof( DeepSeaSerpent ),
typeof( DesertOstard ), typeof( DireWolf ), typeof( Dog ),
typeof( Dolphin ), typeof( Dragon ), typeof( Drake ),
typeof( DullCopperElemental ), typeof( Eagle ), typeof( ElderGazer ),
typeof( EvilMage ), typeof( EvilMageLord ), typeof( Executioner ),
typeof( Savage ), typeof( FireElemental ), typeof( FireGargoyle ),
typeof( FireSteed ), typeof( ForestOstard ), typeof( FrenziedOstard ),
typeof( FrostSpider ), typeof( Gargoyle ), typeof( Gazer ),
typeof( IceSerpent ), typeof( GiantRat ), typeof( GiantSerpent ),
typeof( GiantSpider ), typeof( GiantToad ), typeof( Goat ),
typeof( GoldenElemental ), typeof( Gorilla ), typeof( GreatHart ),
typeof( GreyWolf ), typeof( GrizzlyBear ), typeof( Guardian ),
typeof( Harpy ), typeof( Harrower ), typeof( HellHound ),
typeof( Hind ), typeof( HordeMinion ), typeof( Horse ),
typeof( Horse ), typeof( IceElemental ), typeof( IceFiend ),
typeof( IceSnake ), typeof( Imp ), typeof( JackRabbit ),
typeof( Kirin ), typeof( Kraken ), typeof( PredatorHellCat ),
typeof( LavaLizard ), typeof( LavaSerpent ), typeof( LavaSnake ),
typeof( Lizardman ), typeof( Llama ), typeof( Mongbat ),
typeof( StrongMongbat ), typeof( MountainGoat ), typeof( Orc ),
typeof( OrcBomber ), typeof( OrcBrute ), typeof( OrcCaptain ),
typeof( OrcishLord ), typeof( OrcishMage ), typeof( PackHorse ),
typeof( PackLlama ), typeof( Panther ), typeof( Pig ),
typeof( PlagueSpawn ), typeof( PolarBear ), typeof( Rabbit ),
typeof( Ratman ), typeof( RatmanArcher ), typeof( RatmanMage ),
typeof( RedSolenInfiltratorQueen ), typeof( RedSolenInfiltratorWarrior ), typeof( RedSolenQueen ),
typeof( RedSolenWarrior ), typeof( RedSolenWorker ), typeof( RidableLlama ),
typeof( Ridgeback ), typeof( Scorpion ), typeof( SeaSerpent ),
typeof( SerpentineDragon ), typeof( Shade ), typeof( ShadowIronElemental ),
typeof( ShadowWisp ), typeof( ShadowWyrm ), typeof( Sheep ),
typeof( SilverSteed ), typeof( SkeletalDragon ), typeof( SkeletalMage ),
typeof( SkeletalMount ), typeof( HellCat ), typeof( Snake ),
typeof( SnowLeopard ), typeof( SpectralArmour ), typeof( Spectre ),
typeof( StoneGargoyle ), typeof( StoneHarpy ), typeof( SwampDragon ),
typeof( ScaledSwampDragon ), typeof( SwampTentacle ), typeof( TerathanAvenger ),
typeof( TerathanDrone ), typeof( TerathanMatriarch ), typeof( TerathanWarrior ),
typeof( TimberWolf ), typeof( Titan ), typeof( Troll ),
typeof( Unicorn ), typeof( ValoriteElemental ), typeof( VeriteElemental ),
typeof( CoMWarHorse ), typeof( MinaxWarHorse ), typeof( SLWarHorse ),
typeof( TBWarHorse ), typeof( WaterElemental ), typeof( WhippingVine ),
typeof( WhiteWolf ), typeof( Wraith ), typeof( Wyvern ),
typeof( KhaldunZealot ), typeof( KhaldunSummoner ), typeof( SavageRidgeback ),
typeof( LichLord ), typeof( SkeletalKnight ), typeof( SummonedDaemon ),
typeof( SummonedEarthElemental ), typeof( SummonedWaterElemental ), typeof( SummonedFireElemental ),
typeof( MeerWarrior ), typeof( MeerEternal ), typeof( MeerMage ),
typeof( MeerCaptain ), typeof( JukaLord ), typeof( JukaMage ),
typeof( JukaWarrior ), typeof( AbysmalHorror ), typeof( BoneDemon ),
typeof( Devourer ), typeof( FleshGolem ), typeof( Gibberling ),
typeof( GoreFiend ), typeof( Impaler ), typeof( PatchworkSkeleton ),
typeof( Ravager ), typeof( ShadowKnight ), typeof( SkitteringHopper ),
typeof( Treefellow ), typeof( VampireBat ), typeof( WailingBanshee ),
typeof( WandererOfTheVoid ), typeof( Cursed ), typeof( GrimmochDrummel ),
typeof( LysanderGathenwale ), typeof( MorgBergen ), typeof( ShadowFiend ),
typeof( SpectralArmour ), typeof( TavaraSewel ), typeof( ArcaneDaemon ),
typeof( Doppleganger ), typeof( EnslavedGargoyle ), typeof( ExodusMinion ),
typeof( ExodusOverseer ), typeof( GargoyleDestroyer ), typeof( GargoyleEnforcer ),
typeof( Moloch ), typeof( BakeKitsune ), typeof( DeathwatchBeetleHatchling ),
typeof( Kappa ), typeof( KazeKemono ), typeof( DeathwatchBeetle ),
typeof( TsukiWolf ), typeof( YomotsuElder ), typeof( YomotsuPriest ),
typeof( YomotsuWarrior ), typeof( RevenantLion ), typeof( Oni ),
typeof( Gaman ), typeof( Crane ), typeof( Beetle )
} )
};
}
}
return true;
}
private static void LoadTable()
{
m_Table = new Dictionary<Type, SpeedInfo>();
for (int i = 0; i < m_Speeds.Length; ++i)
{
SpeedInfo info = m_Speeds[i];
Type[] types = info.Types;
for (int j = 0; j < types.Length; ++j)
m_Table[types[j]] = info;
}
}
}
}

View file

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

View file

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