Fixes code according to modern code style. Fixes a few expression bugs.
This commit is contained in:
parent
89eea25e5f
commit
970fd563b2
3324 changed files with 441118 additions and 433755 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue