This commit is contained in:
mark 2006-06-15 04:14:30 +00:00
commit 47711d616e
2644 changed files with 479454 additions and 0 deletions

View file

@ -0,0 +1,157 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
// Ideas
// When you run on animals the panic
// When if ( distance < 8 && Utility.RandomDouble() * Math.Sqrt( (8 - distance) / 6 ) >= incoming.Skills[SkillName.AnimalTaming].Value )
// More your close, the more it can panic
/*
* AnimalHunterAI, AnimalHidingAI, AnimalDomesticAI...
*
*/
namespace Server.Mobiles
{
public class AnimalAI : BaseAI
{
public AnimalAI(BaseCreature m) : base (m)
{
}
public override bool DoActionWander()
{
// Old:
#if false
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 if ( m_Mobile.IsHurt() || m_Mobile.Combatant != null )
{
m_Mobile.DebugSay( "I am hurt or being attacked, I flee" );
Action = ActionType.Flee;
}
else
{
base.DoActionWander();
}
return true;
#endif
// New, only flee @ 10%
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if ( !m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 ) // 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();
}
return true;
}
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.." );
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 )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I cannot find {0}", combatant.Name );
Action = ActionType.Wander;
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 )
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if ( hitPercent < 0.1 )
{
m_Mobile.DebugSay( "I am low on health!" );
Action = ActionType.Flee;
}
}
return true;
}
public override bool DoActionBackoff()
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if ( !m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1 ) // 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;
}
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;
return base.DoActionFlee();
}
}
}

View file

@ -0,0 +1,131 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
using Server.Items;
namespace Server.Mobiles
{
public class ArcherAI : BaseAI
{
public ArcherAI(BaseCreature m) : base (m)
{
}
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 );
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
return base.DoActionWander();
}
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 ( (m_Mobile.LastMoveTime + TimeSpan.FromSeconds( 1.0 )) < DateTime.Now )
{
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);
m_Mobile.Combatant = null;
Action = ActionType.Guard;
return true;
}
}
}
}
// When we have no ammo, we flee
Container pack = m_Mobile.Backpack;
if ( pack == null || 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 )
{
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;
}
}
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

@ -0,0 +1,87 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
namespace Server.Mobiles
{
public class BerserkAI : BaseAI
{
public BerserkAI(BaseCreature m) : base (m)
{
}
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" );
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
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( (int) m_Mobile.GetDistanceToSqrt( m_Mobile.Combatant ) > m_Mobile.RangePerception + 1 )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I have lost " + m_Mobile.Combatant.Name );
Action = ActionType.Guard;
return true;
}
}
}
return true;
}
public override bool DoActionGuard()
{
if ( AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, true, true ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I have detected {0}, attacking", m_Mobile.FocusMob.Name );
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionGuard();
}
return true;
}
}
}

View file

@ -0,0 +1,176 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Spells;
using Server.Spells.First;
using Server.Spells.Second;
using Server.Spells.Fourth;
namespace Server.Mobiles
{
public class HealerAI : BaseAI
{
private static NeedDelegate m_Cure = new NeedDelegate( NeedCure );
private static NeedDelegate m_GHeal = new NeedDelegate( NeedGHeal );
private static NeedDelegate m_LHeal = new NeedDelegate( NeedLHeal );
private static NeedDelegate[] m_ACure = new NeedDelegate[] { m_Cure };
private static NeedDelegate[] m_AGHeal = new NeedDelegate[] { m_GHeal };
private static NeedDelegate[] m_ALHeal = new NeedDelegate[] { m_LHeal };
private static NeedDelegate[] m_All = new NeedDelegate[] { m_Cure, m_GHeal, m_LHeal };
public HealerAI( BaseCreature m ) : base( m )
{
}
public override bool Think()
{
if ( m_Mobile.Deleted )
return false;
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 ( 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 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 );
}
}
}
return true;
}
private delegate bool NeedDelegate( Mobile m );
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 );
}
}
private Mobile Find( params NeedDelegate[] funcs )
{
if ( m_Mobile.Deleted )
return null;
Map map = m_Mobile.Map;
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;
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;
}
break;
}
}
}
return found;
}
return null;
}
private static bool NeedCure( Mobile m )
{
return m.Poisoned;
}
private static bool NeedGHeal( Mobile m )
{
return m.Hits < m.HitsMax - 40;
}
private static bool NeedLHeal( Mobile m )
{
return m.Hits < m.HitsMax - 10;
}
}
}

View file

@ -0,0 +1,992 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
using Server.Items;
using Server.Spells;
using Server.Spells.First;
using Server.Spells.Second;
using Server.Spells.Third;
using Server.Spells.Fourth;
using Server.Spells.Fifth;
using Server.Spells.Sixth;
using Server.Spells.Seventh;
using Server.Misc;
using Server.Regions;
using Server.SkillHandlers;
namespace Server.Mobiles
{
public class MageAI : BaseAI
{
private DateTime m_NextCastTime;
private DateTime m_NextHealTime;
public MageAI( BaseCreature m ) : base( m )
{
}
public override bool Think()
{
if ( m_Mobile.Deleted )
return false;
if ( ProcessTarget() )
return true;
else
return base.Think();
}
public virtual bool SmartAI
{
get{ return ( m_Mobile is BaseVendor || m_Mobile is BaseEscortable ); }
}
private const double HealChance = 0.10; // 10% chance to heal at gm magery
private const double TeleportChance = 0.05; // 5% chance to teleport at gm magery
private const double DispelChance = 0.75; // 75% chance to dispel at gm magery
public virtual double ScaleByMagery( double v )
{
return m_Mobile.Skills[SkillName.Magery].Value * v * 0.01;
}
public override bool DoActionWander()
{
if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I am going to attack {0}", m_Mobile.FocusMob.Name );
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
m_NextCastTime = DateTime.Now;
}
else if ( SmartAI && m_Mobile.Mana < m_Mobile.ManaMax )
{
m_Mobile.DebugSay( "I am going to meditate" );
m_Mobile.UseSkill( SkillName.Meditation );
}
else
{
m_Mobile.DebugSay( "I am wandering" );
m_Mobile.Warmode = false;
base.DoActionWander();
if ( !m_Mobile.Controlled )
{
Spell spell = CheckCastHealingSpell();
if ( spell != null )
spell.Cast();
}
}
return true;
}
private Spell CheckCastHealingSpell()
{
// If I'm poisoned, always attempt to cure.
if ( m_Mobile.Poisoned )
return new CureSpell( m_Mobile, null );
// Summoned creatures never heal themselves.
if ( m_Mobile.Summoned )
return null;
if ( m_Mobile.Controlled )
{
if ( DateTime.Now < m_NextHealTime )
return null;
}
if ( !SmartAI )
{
if ( ScaleByMagery( HealChance ) < Utility.RandomDouble() )
return null;
}
else
{
if ( Utility.Random( 0, 4 + (m_Mobile.Hits == 0 ? m_Mobile.HitsMax : (m_Mobile.HitsMax / m_Mobile.Hits)) ) < 3 )
return null;
}
Spell spell = null;
if ( m_Mobile.Hits < (m_Mobile.HitsMax - 50) )
{
spell = new GreaterHealSpell( m_Mobile, null );
if ( spell == null )
spell = new HealSpell( m_Mobile, null );
}
else if ( m_Mobile.Hits < (m_Mobile.HitsMax - 10) )
spell = new HealSpell( m_Mobile, null );
double delay;
if ( m_Mobile.Int >= 500 )
delay = Utility.RandomMinMax( 7, 10 );
else
delay = Math.Sqrt( 600 - m_Mobile.Int );
m_NextHealTime = DateTime.Now + TimeSpan.FromSeconds( delay );
return spell;
}
public void RunTo( Mobile m )
{
if ( !SmartAI )
{
if ( !MoveTo( m, true, m_Mobile.RangeFight ) )
OnFailedMove();
return;
}
if ( m.Paralyzed || m.Frozen )
{
if ( m_Mobile.InRange( m, 1 ) )
RunFrom( m );
else if ( !m_Mobile.InRange( m, m_Mobile.RangeFight > 2 ? m_Mobile.RangeFight : 2 ) && !MoveTo( m, true, 1 ) )
OnFailedMove();
}
else
{
if ( !m_Mobile.InRange( m, m_Mobile.RangeFight ) )
{
if ( !MoveTo( m, true, 1 ) )
OnFailedMove();
}
else if ( m_Mobile.InRange( m, m_Mobile.RangeFight - 1 ) )
{
RunFrom( m );
}
}
}
public void RunFrom( Mobile m )
{
Run( (m_Mobile.GetDirectionTo( m ) - 4) & Direction.Mask );
}
public void OnFailedMove()
{
if ( !m_Mobile.DisallowAllMoves && (SmartAI ? Utility.Random( 4 ) == 0 : ScaleByMagery( TeleportChance ) > Utility.RandomDouble()) )
{
if ( m_Mobile.Target != null )
m_Mobile.Target.Cancel( m_Mobile, TargetCancelType.Canceled );
new TeleportSpell( m_Mobile, null ).Cast();
m_Mobile.DebugSay( "I am stuck, I'm going to try teleporting away" );
}
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;
}
else
{
m_Mobile.DebugSay( "I am stuck" );
}
}
public void Run( Direction d )
{
if ( (m_Mobile.Spell != null && m_Mobile.Spell.IsCasting) || m_Mobile.Paralyzed || m_Mobile.Frozen || m_Mobile.DisallowAllMoves )
return;
m_Mobile.Direction = d | Direction.Running;
if ( !DoMove( m_Mobile.Direction, true ) )
OnFailedMove();
}
public virtual Spell GetRandomDamageSpell()
{
int maxCircle = (int)((m_Mobile.Skills[SkillName.Magery].Value + 20.0) / (100.0 / 7.0));
if ( maxCircle < 1 )
maxCircle = 1;
switch ( Utility.Random( maxCircle*2 ) )
{
case 0: case 1: return new MagicArrowSpell( m_Mobile, null );
case 2: case 3: return new HarmSpell( m_Mobile, null );
case 4: case 5: return new FireballSpell( m_Mobile, null );
case 6: case 7: return new LightningSpell( m_Mobile, null );
case 8: case 9: return new MindBlastSpell( m_Mobile, null );
case 10: return new EnergyBoltSpell( m_Mobile, null );
case 11: return new ExplosionSpell( m_Mobile, null );
default: return new FlameStrikeSpell( m_Mobile, null );
}
}
public virtual Spell GetRandomCurseSpell()
{
if ( Utility.RandomBool() )
{
if ( m_Mobile.Skills[SkillName.Magery].Value >= 40.0 )
return new CurseSpell( m_Mobile, null );
}
switch ( Utility.Random( 3 ) )
{
default:
case 0: return new WeakenSpell( m_Mobile, null );
case 1: return new ClumsySpell( m_Mobile, null );
case 2: return new FeeblemindSpell( m_Mobile, null );
}
}
public virtual Spell GetRandomManaDrainSpell()
{
if ( Utility.RandomBool() )
{
if ( m_Mobile.Skills[SkillName.Magery].Value >= 80.0 )
return new ManaVampireSpell( m_Mobile, null );
}
return new ManaDrainSpell( m_Mobile, null );
}
public virtual Spell DoDispel( Mobile toDispel )
{
if ( !SmartAI )
{
if ( ScaleByMagery( DispelChance ) > Utility.RandomDouble() )
return new DispelSpell( m_Mobile, null );
return ChooseSpell( toDispel );
}
Spell spell = CheckCastHealingSpell();
if ( spell == null )
{
if ( !m_Mobile.DisallowAllMoves && Utility.Random( (int)m_Mobile.GetDistanceToSqrt( toDispel ) ) == 0 )
spell = new TeleportSpell( m_Mobile, null );
else if ( Utility.Random( 3 ) == 0 && !m_Mobile.InRange( toDispel, 3 ) && !toDispel.Paralyzed && !toDispel.Frozen )
spell = new ParalyzeSpell( m_Mobile, null );
else
spell = new DispelSpell( m_Mobile, null );
}
return spell;
}
public virtual Spell ChooseSpell( Mobile c )
{
Spell spell = null;
if ( !SmartAI )
{
spell = CheckCastHealingSpell();
if ( spell != null )
return spell;
switch ( Utility.Random( 16 ) )
{
case 0:
case 1:
case 2: // Poison them
{
m_Mobile.DebugSay( "Attempting to poison" );
if ( !c.Poisoned )
spell = new PoisonSpell( m_Mobile, null );
break;
}
case 3: // Bless ourselves.
{
m_Mobile.DebugSay( "Blessing myself" );
spell = new BlessSpell( m_Mobile, null );
break;
}
case 4:
case 5:
case 6: // Curse them.
{
m_Mobile.DebugSay( "Attempting to curse" );
spell = GetRandomCurseSpell();
break;
}
case 7: // Paralyze them.
{
m_Mobile.DebugSay( "Attempting to paralyze" );
if ( m_Mobile.Skills[SkillName.Magery].Value > 50.0 )
spell = new ParalyzeSpell( m_Mobile, null );
break;
}
case 8: // Drain mana
{
m_Mobile.DebugSay( "Attempting to drain mana" );
spell = GetRandomManaDrainSpell();
break;
}
default: // Damage them.
{
m_Mobile.DebugSay( "Just doing damage" );
spell = GetRandomDamageSpell();
break;
}
}
return spell;
}
spell = CheckCastHealingSpell();
if ( spell != null )
return spell;
switch ( Utility.Random( 3 ) )
{
default:
case 0: // Poison them
{
if ( !c.Poisoned )
spell = new PoisonSpell( m_Mobile, null );
break;
}
case 1: // Deal some damage
{
spell = GetRandomDamageSpell();
break;
}
case 2: // Set up a combo
{
if ( m_Mobile.Mana < 40 && m_Mobile.Mana > 15 )
{
if ( c.Paralyzed && !c.Poisoned )
{
m_Mobile.DebugSay( "I am going to meditate" );
m_Mobile.UseSkill( SkillName.Meditation );
}
else if ( !c.Poisoned )
{
spell = new ParalyzeSpell( m_Mobile, null );
}
}
else if ( m_Mobile.Mana > 60 )
{
if ( Utility.Random( 2 ) == 0 && !c.Paralyzed && !c.Frozen && !c.Poisoned )
{
m_Combo = 0;
spell = new ParalyzeSpell( m_Mobile, null );
}
else
{
m_Combo = 1;
spell = new ExplosionSpell( m_Mobile, null );
}
}
break;
}
}
return spell;
}
protected int m_Combo = -1;
public virtual Spell DoCombo( Mobile c )
{
Spell spell = null;
if ( m_Combo == 0 )
{
spell = new ExplosionSpell( m_Mobile, null );
++m_Combo; // Move to next spell
}
else if ( m_Combo == 1 )
{
spell = new WeakenSpell( m_Mobile, null );
++m_Combo; // Move to next spell
}
else if ( m_Combo == 2 )
{
if ( !c.Poisoned )
spell = new PoisonSpell( m_Mobile, null );
++m_Combo; // Move to next spell
}
if ( m_Combo == 3 && spell == null )
{
switch ( Utility.Random( 3 ) )
{
default:
case 0:
{
if ( c.Int < c.Dex )
spell = new FeeblemindSpell( m_Mobile, null );
else
spell = new ClumsySpell( m_Mobile, null );
++m_Combo; // Move to next spell
break;
}
case 1:
{
spell = new EnergyBoltSpell( m_Mobile, null );
m_Combo = -1; // Reset combo state
break;
}
case 2:
{
spell = new FlameStrikeSpell( m_Mobile, null );
m_Combo = -1; // Reset combo state
break;
}
}
}
else if ( m_Combo == 4 && spell == null )
{
spell = new MindBlastSpell( m_Mobile, null );
m_Combo = -1;
}
return spell;
}
private TimeSpan GetDelay()
{
double del = ScaleByMagery( 3.0 );
double min = 6.0 - (del * 0.75);
double max = 6.0 - (del * 1.25);
return TimeSpan.FromSeconds( min + ((max - min) * Utility.RandomDouble()) );
}
public override bool DoActionCombat()
{
Mobile c = m_Mobile.Combatant;
m_Mobile.Warmode = true;
if ( c == null || c.Deleted || !c.Alive || c.IsDeadBondedPet || !m_Mobile.CanSee( c ) || !m_Mobile.CanBeHarmful( c, false ) || c.Map != m_Mobile.Map )
{
// Our combatant is deleted, dead, hidden, or we cannot hurt them
// Try to find another combatant
if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "Something happened to my combatant, so I am going to fight {0}", m_Mobile.FocusMob.Name );
m_Mobile.Combatant = c = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
else
{
m_Mobile.DebugSay( "Something happened to my combatant, and nothing is around. I am on guard." );
Action = ActionType.Guard;
return true;
}
}
if ( !m_Mobile.InLOS( c ) )
{
m_Mobile.DebugSay( "I can't see my target" );
if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
m_Mobile.DebugSay( "Nobody else is around" );
m_Mobile.Combatant = c = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
}
if ( SmartAI && !m_Mobile.StunReady && m_Mobile.Skills[SkillName.Wrestling].Value >= 80.0 && m_Mobile.Skills[SkillName.Anatomy].Value >= 80.0 )
EventSink.InvokeStunRequest( new StunRequestEventArgs( m_Mobile ) );
if ( !m_Mobile.InRange( c, 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( c, m_Mobile.RangePerception * 3 ) )
{
m_Mobile.Combatant = null;
}
c = m_Mobile.Combatant;
if ( c == null )
{
m_Mobile.DebugSay( "My combatant has fled, so I am on guard" );
Action = ActionType.Guard;
return true;
}
}
if ( !m_Mobile.Controlled && !m_Mobile.Summoned && !m_Mobile.IsParagon )
{
if ( m_Mobile.Hits < m_Mobile.HitsMax * 20/100 )
{
// We are low on health, should we flee?
bool flee = false;
if ( m_Mobile.Hits < c.Hits )
{
// We are more hurt than them
int diff = c.Hits - m_Mobile.Hits;
flee = ( Utility.Random( 0, 100 ) > (10 + diff) ); // (10 + diff)% chance to flee
}
else
{
flee = Utility.Random( 0, 100 ) > 10; // 10% chance to flee
}
if ( flee )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I am going to flee from {0}", c.Name );
Action = ActionType.Flee;
return true;
}
}
}
if ( m_Mobile.Spell == null && DateTime.Now > m_NextCastTime && m_Mobile.InRange( c, 12 ) )
{
// We are ready to cast a spell
Spell spell = null;
Mobile toDispel = FindDispelTarget( true );
if ( m_Mobile.Poisoned ) // Top cast priority is cure
{
m_Mobile.DebugSay( "I am going to cure myself" );
spell = new CureSpell( m_Mobile, null );
}
else if ( toDispel != null ) // Something dispellable is attacking us
{
m_Mobile.DebugSay( "I am going to dispel {0}", toDispel );
spell = DoDispel( toDispel );
}
else if ( SmartAI && m_Combo != -1 ) // We are doing a spell combo
{
spell = DoCombo( c );
}
else if ( SmartAI && (c.Spell is HealSpell || c.Spell is GreaterHealSpell) && !c.Poisoned ) // They have a heal spell out
{
spell = new PoisonSpell( m_Mobile, null );
}
else
{
spell = ChooseSpell( c );
}
// Now we have a spell picked
// Move first before casting
if ( SmartAI && toDispel != null )
{
if ( m_Mobile.InRange( toDispel, 10 ) )
RunFrom( toDispel );
else if ( !m_Mobile.InRange( toDispel, 12 ) )
RunTo( toDispel );
}
else
{
RunTo( c );
}
if ( spell != null )
spell.Cast();
TimeSpan delay;
if ( SmartAI || ( spell is DispelSpell ) )
delay = TimeSpan.FromSeconds( m_Mobile.ActiveSpeed );
else
delay = GetDelay();
m_NextCastTime = DateTime.Now + delay;
}
else if ( m_Mobile.Spell == null || !m_Mobile.Spell.IsCasting )
{
RunTo( c );
}
return true;
}
public override bool DoActionGuard()
{
if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
m_Mobile.DebugSay( "I am going to attack {0}", m_Mobile.FocusMob.Name );
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
if ( !m_Mobile.Controlled )
{
ProcessTarget();
Spell spell = CheckCastHealingSpell();
if ( spell != null )
spell.Cast();
}
base.DoActionGuard();
}
return true;
}
public override bool DoActionFlee()
{
Mobile c = m_Mobile.Combatant;
if ( (m_Mobile.Mana > 20 || m_Mobile.Mana == m_Mobile.ManaMax) && m_Mobile.Hits > (m_Mobile.HitsMax / 2) )
{
m_Mobile.DebugSay( "I am stronger now, my guard is up" );
Action = ActionType.Guard;
}
else if ( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I am scared of {0}", m_Mobile.FocusMob.Name );
RunFrom( m_Mobile.FocusMob );
m_Mobile.FocusMob = null;
if ( m_Mobile.Poisoned && Utility.Random( 0, 5 ) == 0 )
new CureSpell( m_Mobile, null ).Cast();
}
else
{
m_Mobile.DebugSay( "Area seems clear, but my guard is up" );
Action = ActionType.Guard;
m_Mobile.Warmode = true;
}
return true;
}
public Mobile FindDispelTarget( bool activeOnly )
{
if ( m_Mobile.Deleted || m_Mobile.Int < 95 || CanDispel( m_Mobile ) || m_Mobile.AutoDispel )
return null;
if ( activeOnly )
{
List<AggressorInfo> aggressed = m_Mobile.Aggressed;
List<AggressorInfo> aggressors = m_Mobile.Aggressors;
Mobile active = null;
double activePrio = 0.0;
Mobile comb = m_Mobile.Combatant;
if ( comb != null && !comb.Deleted && comb.Alive && !comb.IsDeadBondedPet && m_Mobile.InRange( comb, 12 ) && CanDispel( comb ) )
{
active = comb;
activePrio = m_Mobile.GetDistanceToSqrt( comb );
if ( activePrio <= 2 )
return active;
}
for ( int i = 0; i < aggressed.Count; ++i )
{
AggressorInfo info = aggressed[i];
Mobile m = info.Defender;
if ( m != comb && m.Combatant == m_Mobile && m_Mobile.InRange( m, 12 ) && CanDispel( m ) )
{
double prio = m_Mobile.GetDistanceToSqrt( m );
if ( active == null || prio < activePrio )
{
active = m;
activePrio = prio;
if ( activePrio <= 2 )
return active;
}
}
}
for ( int i = 0; i < aggressors.Count; ++i )
{
AggressorInfo info = aggressors[i];
Mobile m = info.Attacker;
if ( m != comb && m.Combatant == m_Mobile && m_Mobile.InRange( m, 12 ) && CanDispel( m ) )
{
double prio = m_Mobile.GetDistanceToSqrt( m );
if ( active == null || prio < activePrio )
{
active = m;
activePrio = prio;
if ( activePrio <= 2 )
return active;
}
}
}
return active;
}
else
{
Map map = m_Mobile.Map;
if ( map != null )
{
Mobile active = null, inactive = null;
double actPrio = 0.0, inactPrio = 0.0;
Mobile comb = m_Mobile.Combatant;
if ( comb != null && !comb.Deleted && comb.Alive && !comb.IsDeadBondedPet && CanDispel( comb ) )
{
active = inactive = comb;
actPrio = inactPrio = m_Mobile.GetDistanceToSqrt( comb );
}
foreach ( Mobile m in m_Mobile.GetMobilesInRange( 12 ) )
{
if ( m != m_Mobile && CanDispel( m ) )
{
double prio = m_Mobile.GetDistanceToSqrt( m );
if ( !activeOnly && (inactive == null || prio < inactPrio) )
{
inactive = m;
inactPrio = prio;
}
if ( (m_Mobile.Combatant == m || m.Combatant == m_Mobile) && (active == null || prio < actPrio) )
{
active = m;
actPrio = prio;
}
}
}
return active != null ? active : inactive;
}
}
return null;
}
public bool CanDispel( Mobile m )
{
return ( m is BaseCreature && ((BaseCreature)m).Summoned && m_Mobile.CanBeHarmful( m, false ) && !((BaseCreature)m).IsAnimatedDead );
}
private static int[] m_Offsets = new int[]
{
-1, -1,
-1, 0,
-1, 1,
0, -1,
0, 1,
1, -1,
1, 0,
1, 1,
-2, -2,
-2, -1,
-2, 0,
-2, 1,
-2, 2,
-1, -2,
-1, 2,
0, -2,
0, 2,
1, -2,
1, 2,
2, -2,
2, -1,
2, 0,
2, 1,
2, 2
};
private bool ProcessTarget()
{
Target targ = m_Mobile.Target;
if ( targ == null )
return false;
bool isDispel = ( targ is DispelSpell.InternalTarget );
bool isParalyze = ( targ is ParalyzeSpell.InternalTarget );
bool isTeleport = ( targ is TeleportSpell.InternalTarget );
bool teleportAway = false;
Mobile toTarget;
if ( isDispel )
{
toTarget = FindDispelTarget( false );
if ( !SmartAI && toTarget != null )
RunTo( toTarget );
else if ( toTarget != null && m_Mobile.InRange( toTarget, 10 ) )
RunFrom( toTarget );
}
else if ( SmartAI && (isParalyze || isTeleport) )
{
toTarget = FindDispelTarget( true );
if ( toTarget == null )
{
toTarget = m_Mobile.Combatant;
if ( toTarget != null )
RunTo( toTarget );
}
else if ( m_Mobile.InRange( toTarget, 10 ) )
{
RunFrom( toTarget );
teleportAway = true;
}
else
{
teleportAway = true;
}
}
else
{
toTarget = m_Mobile.Combatant;
if ( toTarget != null )
RunTo( toTarget );
}
if ( (targ.Flags & TargetFlags.Harmful) != 0 && toTarget != null )
{
if ( (targ.Range == -1 || m_Mobile.InRange( toTarget, targ.Range )) && m_Mobile.CanSee( toTarget ) && m_Mobile.InLOS( toTarget ) )
{
targ.Invoke( m_Mobile, toTarget );
}
else if ( isDispel )
{
targ.Cancel( m_Mobile, TargetCancelType.Canceled );
}
}
else if ( (targ.Flags & TargetFlags.Beneficial) != 0 )
{
targ.Invoke( m_Mobile, m_Mobile );
}
else if ( isTeleport && toTarget != null )
{
Map map = m_Mobile.Map;
if ( map == null )
{
targ.Cancel( m_Mobile, TargetCancelType.Canceled );
return true;
}
int px, py;
if ( teleportAway )
{
int rx = m_Mobile.X - toTarget.X;
int ry = m_Mobile.Y - toTarget.Y;
double d = m_Mobile.GetDistanceToSqrt( toTarget );
px = toTarget.X + (int)(rx * (10 / d));
py = toTarget.Y + (int)(ry * (10 / d));
}
else
{
px = toTarget.X;
py = toTarget.Y;
}
for ( int i = 0; i < m_Offsets.Length; i += 2 )
{
int x = m_Offsets[i], y = m_Offsets[i + 1];
Point3D p = new Point3D( px + x, py + y, 0 );
LandTarget lt = new LandTarget( p, map );
if ( (targ.Range == -1 || m_Mobile.InRange( p, targ.Range )) && m_Mobile.InLOS( lt ) && map.CanSpawnMobile( px + x, py + y, lt.Z ) && !SpellHelper.CheckMulti( p, map ) )
{
targ.Invoke( m_Mobile, lt );
return true;
}
}
int teleRange = targ.Range;
if ( teleRange < 0 )
teleRange = 12;
for ( int i = 0; i < 10; ++i )
{
Point3D randomPoint = new Point3D( m_Mobile.X - teleRange + Utility.Random( teleRange * 2 + 1 ), m_Mobile.Y - teleRange + Utility.Random( teleRange * 2 + 1 ), 0 );
LandTarget lt = new LandTarget( randomPoint, map );
if ( m_Mobile.InLOS( lt ) && map.CanSpawnMobile( lt.X, lt.Y, lt.Z ) && !SpellHelper.CheckMulti( randomPoint, map ) )
{
targ.Invoke( m_Mobile, new LandTarget( randomPoint, map ) );
return true;
}
}
targ.Cancel( m_Mobile, TargetCancelType.Canceled );
}
else
{
targ.Cancel( m_Mobile, TargetCancelType.Canceled );
}
return true;
}
}
}

View file

@ -0,0 +1,183 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
//
// This is a first simple AI
//
//
namespace Server.Mobiles
{
public class MeleeAI : BaseAI
{
public MeleeAI(BaseCreature m) : base (m)
{
}
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 );
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else
{
base.DoActionWander();
}
return true;
}
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" );
Action = ActionType.Guard;
return true;
}
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;
}
combatant = m_Mobile.Combatant;
if ( combatant == null )
{
m_Mobile.DebugSay( "My combatant has fled, so I am on guard" );
Action = ActionType.Guard;
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 ( 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;
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;
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.IsParagon )
{
if ( m_Mobile.Hits < m_Mobile.HitsMax * 20/100 )
{
// We are low on health, should we flee?
bool flee = false;
if ( m_Mobile.Hits < combatant.Hits )
{
// We are more hurt than them
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
}
if ( flee )
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "I am going to flee from {0}", combatant.Name );
Action = ActionType.Flee;
}
}
}
return true;
}
public override bool DoActionGuard()
{
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;
}
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

@ -0,0 +1,100 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
/*
* 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 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;
}
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 ( 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;
}
else
{
m_Mobile.DebugSay( "I should be closer to {0}", combatant.Name );
}
}
return true;
}
public override bool DoActionBackoff()
{
if ( m_Mobile.IsHurt() || m_Mobile.Combatant != null )
{
Action = ActionType.Combat;
}
else
{
if (AcquireFocusMob(m_Mobile.RangePerception * 2, FightMode.Closest, true, false , true))
{
if ( WalkMobileRange(m_Mobile.FocusMob, 1, false, m_Mobile.RangePerception, m_Mobile.RangePerception * 2) )
{
m_Mobile.DebugSay( "Well, here I am safe" );
Action = ActionType.Wander;
}
}
else
{
m_Mobile.DebugSay( "I have lost my focus, lets relax" );
Action = ActionType.Wander;
}
}
return true;
}
}
}

View file

@ -0,0 +1,194 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Items;
//
// This is a first simple AI
//
//
namespace Server.Mobiles
{
public class ThiefAI : BaseAI
{
public ThiefAI(BaseCreature m) : base (m)
{
}
private Item m_toDisarm;
public override bool DoActionWander()
{
m_Mobile.DebugSay( "I have no combatant" );
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.DoActionWander();
}
return true;
}
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.Guard;
return true;
}
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 = combatant.FindItemOnLayer( Layer.TwoHanded );
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 ( !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.IsChildOf( combatant.Backpack ) && m_Mobile.NextSkillTime <= DateTime.Now && (m_toDisarm.LootType != LootType.Blessed && m_toDisarm.LootType != LootType.Newbied) )
{
m_Mobile.DebugSay( "Trying to steal from combatant." );
m_Mobile.UseSkill( SkillName.Stealing );
if ( m_Mobile.Target != null )
m_Mobile.Target.Invoke( m_Mobile, m_toDisarm );
}
else if ( m_toDisarm == null && m_Mobile.NextSkillTime <= DateTime.Now )
{
Container cpack = combatant.Backpack;
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 );
if ( m_Mobile.Target != null )
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 );
if ( m_Mobile.Target != null )
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 );
if ( m_Mobile.Target != null )
m_Mobile.Target.Invoke( m_Mobile, stealc );
}
Item steald = cpack.FindItemByType( typeof ( MandrakeRoot ) );
if ( steald != null )
{
m_Mobile.DebugSay( "Trying to steal from combatant." );
m_Mobile.UseSkill( SkillName.Stealing );
if ( m_Mobile.Target != null )
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 );
Action = ActionType.Flee;
}
}
}
}
else
{
m_Mobile.DebugSay( "I should be closer to {0}", combatant.Name );
}
if ( m_Mobile.Hits < m_Mobile.HitsMax * 20/100 && !m_Mobile.IsParagon )
{
// We are low on health, should we flee?
bool flee = false;
if ( m_Mobile.Hits < combatant.Hits )
{
// We are more hurt than them
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
}
if ( flee )
{
m_Mobile.DebugSay( "I am going to flee from {0}", combatant.Name );
Action = ActionType.Flee;
}
}
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

@ -0,0 +1,149 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
//
// This is a first simple AI
//
//
namespace Server.Mobiles
{
public class VendorAI : BaseAI
{
public VendorAI(BaseCreature m) : base (m)
{
}
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 );
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.Interact;
}
else
{
m_Mobile.Warmode = false;
base.DoActionWander();
}
}
return true;
}
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 );
m_Mobile.Say( Utility.RandomList( 1005305, 501603 ) );
Action = ActionType.Flee;
return true;
}
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 );
m_Mobile.Direction = m_Mobile.GetDirectionTo( customer );
}
else
{
if ( m_Mobile.Debug )
m_Mobile.DebugSay( "{0} is gone", customer.Name );
m_Mobile.FocusMob = null;
Action = ActionType.Wander;
}
}
return true;
}
public override bool DoActionGuard()
{
m_Mobile.FocusMob = m_Mobile.Combatant;
return base.DoActionGuard();
}
public override bool HandlesOnSpeech( Mobile from )
{
if ( from.InRange( m_Mobile, 4 ) )
return true;
return base.HandlesOnSpeech( from );
}
// Temporary
public override void OnSpeech( SpeechEventArgs e )
{
base.OnSpeech( e );
Mobile from = e.Mobile;
if ( m_Mobile is BaseVendor && from.InRange( m_Mobile, Core.AOS ? 1 : 4 ) && !e.Handled )
{
if ( e.HasKeyword( 0x14D ) ) // *vendor sell*
{
e.Handled = true;
((BaseVendor)m_Mobile).VendorSell( from );
m_Mobile.FocusMob = from;
}
else if ( e.HasKeyword( 0x3C ) )
{
e.Handled = true;
((BaseVendor)m_Mobile).VendorBuy( from );
m_Mobile.FocusMob = from;
}
else if ( WasNamed( e.Speech ) )
{
e.Handled = true;
if ( e.HasKeyword( 0x177 ) ) // *sell*
((BaseVendor)m_Mobile).VendorSell( from );
else if ( e.HasKeyword( 0x171 ) ) // *buy*
((BaseVendor)m_Mobile).VendorBuy( from );
m_Mobile.FocusMob = from;
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,152 @@
using System;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
namespace Server.Mobiles
{
/// <summary>
/// This is a test creature
/// You can set its value in game
/// It die after 5 minutes, so your test server stay clean
/// Create a macro to help your creation "[add Dummy 1 15 7 -1 0.5 2"
///
/// A iTeam of negative will set a faction at random
///
/// Say Kill if you want them to die
///
/// </summary>
public class Dummy : BaseCreature
{
public Timer m_Timer;
[Constructable]
public Dummy(AIType iAI, FightMode iFightMode, int iRangePerception, int iRangeFight, double dActiveSpeed, double dPassiveSpeed) : base(iAI, iFightMode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed)
{
this.Body = 400 + Utility.Random(2);
this.Hue = Utility.RandomSkinHue();
this.Skills[SkillName.DetectHidden].Base = 100;
this.Skills[SkillName.MagicResist].Base = 120;
Team = Utility.Random(3);
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
Utility.AssignRandomHair( this, iHue );
LeatherGloves glv = new LeatherGloves();
glv.Hue = iHue;
glv.LootType = LootType.Newbied;
AddItem(glv);
Container pack = new Backpack();
pack.Movable = false;
AddItem( pack );
m_Timer = new AutokillTimer(this);
m_Timer.Start();
}
public Dummy( Serial serial ) : base( serial )
{
m_Timer = new AutokillTimer(this);
m_Timer.Start();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override bool HandlesOnSpeech( Mobile from )
{
if ( from.AccessLevel >= AccessLevel.GameMaster )
return true;
return base.HandlesOnSpeech( from );
}
public override void OnSpeech( SpeechEventArgs e )
{
base.OnSpeech( e );
if (e.Mobile.AccessLevel >= AccessLevel.GameMaster)
{
if (e.Speech == "kill")
{
m_Timer.Stop();
m_Timer.Delay = TimeSpan.FromSeconds( Utility.Random(1, 5) );
m_Timer.Start();
}
}
}
public override void OnTeamChange()
{
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
Item item = FindItemOnLayer( Layer.OuterTorso );
if ( item != null )
item.Hue = jHue;
item = FindItemOnLayer( Layer.Helm );
if ( item != null )
item.Hue = iHue;
item = FindItemOnLayer( Layer.Gloves );
if ( item != null )
item.Hue = iHue;
item = FindItemOnLayer( Layer.Shoes );
if ( item != null )
item.Hue = iHue;
HairHue = iHue;
item = FindItemOnLayer( Layer.MiddleTorso );
if ( item != null )
item.Hue = iHue;
item = FindItemOnLayer( Layer.OuterLegs );
if ( item != null )
item.Hue = iHue;
}
private class AutokillTimer : Timer
{
private Dummy m_Owner;
public AutokillTimer( Dummy owner ) : base( TimeSpan.FromMinutes(5.0) )
{
m_Owner = owner;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
m_Owner.Kill();
Stop();
}
}
}
}

View file

@ -0,0 +1,814 @@
using System;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
namespace Server.Mobiles
{
/// <summary>
/// This is a test creature
/// You can set its value in game
/// It die after 5 minutes, so your test server stay clean
/// Create a macro to help your creation "[add Dummy 1 15 7 -1 0.5 2"
///
/// A iTeam of negative will set a faction at random
///
/// Say Kill if you want them to die
///
/// </summary>
public class DummyMace : Dummy
{
[Constructable]
public DummyMace() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Macer
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 125, 125, 90 );
this.Skills[SkillName.Macing].Base = 120;
this.Skills[SkillName.Anatomy].Base = 120;
this.Skills[SkillName.Healing].Base = 120;
this.Skills[SkillName.Tactics].Base = 120;
// Name
this.Name = "Macer";
// Equip
WarHammer war = new WarHammer();
war.Movable = true;
war.Crafter = this;
war.Quality = WeaponQuality.Regular;
AddItem( war );
Boots bts = new Boots();
bts.Hue = iHue;
AddItem( bts );
ChainChest cht = new ChainChest();
cht.Movable = false;
cht.LootType = LootType.Newbied;
cht.Crafter = this;
cht.Quality = ArmorQuality.Regular;
AddItem( cht );
ChainLegs chl = new ChainLegs();
chl.Movable = false;
chl.LootType = LootType.Newbied;
chl.Crafter = this;
chl.Quality = ArmorQuality.Regular;
AddItem( chl );
PlateArms pla = new PlateArms();
pla.Movable = false;
pla.LootType = LootType.Newbied;
pla.Crafter = this;
pla.Quality = ArmorQuality.Regular;
AddItem( pla );
Bandage band = new Bandage( 50 );
AddToBackpack( band );
}
public DummyMace( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummyFence : Dummy
{
[Constructable]
public DummyFence() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Fencer
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 125, 125, 90 );
this.Skills[SkillName.Fencing].Base = 120;
this.Skills[SkillName.Anatomy].Base = 120;
this.Skills[SkillName.Healing].Base = 120;
this.Skills[SkillName.Tactics].Base = 120;
// Name
this.Name = "Fencer";
// Equip
Spear ssp = new Spear();
ssp.Movable = true;
ssp.Crafter = this;
ssp.Quality = WeaponQuality.Regular;
AddItem( ssp );
Boots snd = new Boots();
snd.Hue = iHue;
snd.LootType = LootType.Newbied;
AddItem( snd );
ChainChest cht = new ChainChest();
cht.Movable = false;
cht.LootType = LootType.Newbied;
cht.Crafter = this;
cht.Quality = ArmorQuality.Regular;
AddItem( cht );
ChainLegs chl = new ChainLegs();
chl.Movable = false;
chl.LootType = LootType.Newbied;
chl.Crafter = this;
chl.Quality = ArmorQuality.Regular;
AddItem( chl );
PlateArms pla = new PlateArms();
pla.Movable = false;
pla.LootType = LootType.Newbied;
pla.Crafter = this;
pla.Quality = ArmorQuality.Regular;
AddItem( pla );
Bandage band = new Bandage( 50 );
AddToBackpack( band );
}
public DummyFence( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummySword : Dummy
{
[Constructable]
public DummySword() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Swordsman
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 125, 125, 90 );
this.Skills[SkillName.Swords].Base = 120;
this.Skills[SkillName.Anatomy].Base = 120;
this.Skills[SkillName.Healing].Base = 120;
this.Skills[SkillName.Tactics].Base = 120;
this.Skills[SkillName.Parry].Base = 120;
// Name
this.Name = "Swordsman";
// Equip
Katana kat = new Katana();
kat.Crafter = this;
kat.Movable = true;
kat.Quality = WeaponQuality.Regular;
AddItem( kat );
Boots bts = new Boots();
bts.Hue = iHue;
AddItem( bts );
ChainChest cht = new ChainChest();
cht.Movable = false;
cht.LootType = LootType.Newbied;
cht.Crafter = this;
cht.Quality = ArmorQuality.Regular;
AddItem( cht );
ChainLegs chl = new ChainLegs();
chl.Movable = false;
chl.LootType = LootType.Newbied;
chl.Crafter = this;
chl.Quality = ArmorQuality.Regular;
AddItem( chl );
PlateArms pla = new PlateArms();
pla.Movable = false;
pla.LootType = LootType.Newbied;
pla.Crafter = this;
pla.Quality = ArmorQuality.Regular;
AddItem( pla );
Bandage band = new Bandage( 50 );
AddToBackpack( band );
}
public DummySword( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummyNox : Dummy
{
[Constructable]
public DummyNox() : base(AIType.AI_Mage, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Nox or Pure Mage
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 90, 90, 125 );
this.Skills[SkillName.Magery].Base = 120;
this.Skills[SkillName.EvalInt].Base = 120;
this.Skills[SkillName.Inscribe].Base = 100;
this.Skills[SkillName.Wrestling].Base = 120;
this.Skills[SkillName.Meditation].Base = 120;
this.Skills[SkillName.Poisoning].Base = 100;
// Name
this.Name = "Nox Mage";
// Equip
Spellbook book = new Spellbook();
book.Movable = false;
book.LootType = LootType.Newbied;
book.Content =0xFFFFFFFFFFFFFFFF;
AddItem( book );
Kilt kilt = new Kilt();
kilt.Hue = jHue;
AddItem( kilt );
Sandals snd = new Sandals();
snd.Hue = iHue;
snd.LootType = LootType.Newbied;
AddItem( snd );
SkullCap skc = new SkullCap();
skc.Hue = iHue;
AddItem( skc );
// Spells
AddSpellAttack( typeof(Spells.First.MagicArrowSpell) );
AddSpellAttack( typeof(Spells.First.WeakenSpell) );
AddSpellAttack( typeof(Spells.Third.FireballSpell) );
AddSpellDefense( typeof(Spells.Third.WallOfStoneSpell) );
AddSpellDefense( typeof(Spells.First.HealSpell) );
}
public DummyNox( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummyStun : Dummy
{
[Constructable]
public DummyStun() : base(AIType.AI_Mage, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Stun Mage
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 90, 90, 125 );
this.Skills[SkillName.Magery].Base = 100;
this.Skills[SkillName.EvalInt].Base = 120;
this.Skills[SkillName.Anatomy].Base = 80;
this.Skills[SkillName.Wrestling].Base = 80;
this.Skills[SkillName.Meditation].Base = 100;
this.Skills[SkillName.Poisoning].Base = 100;
// Name
this.Name = "Stun Mage";
// Equip
Spellbook book = new Spellbook();
book.Movable = false;
book.LootType = LootType.Newbied;
book.Content =0xFFFFFFFFFFFFFFFF;
AddItem( book );
LeatherArms lea = new LeatherArms();
lea.Movable = false;
lea.LootType = LootType.Newbied;
lea.Crafter = this;
lea.Quality = ArmorQuality.Regular;
AddItem( lea );
LeatherChest lec = new LeatherChest();
lec.Movable = false;
lec.LootType = LootType.Newbied;
lec.Crafter = this;
lec.Quality = ArmorQuality.Regular;
AddItem( lec );
LeatherGorget leg = new LeatherGorget();
leg.Movable = false;
leg.LootType = LootType.Newbied;
leg.Crafter = this;
leg.Quality = ArmorQuality.Regular;
AddItem( leg );
LeatherLegs lel = new LeatherLegs();
lel.Movable = false;
lel.LootType = LootType.Newbied;
lel.Crafter = this;
lel.Quality = ArmorQuality.Regular;
AddItem( lel );
Boots bts = new Boots();
bts.Hue = iHue;
AddItem( bts );
Cap cap = new Cap();
cap.Hue = iHue;
AddItem( cap );
// Spells
AddSpellAttack( typeof(Spells.First.MagicArrowSpell) );
AddSpellAttack( typeof(Spells.First.WeakenSpell) );
AddSpellAttack( typeof(Spells.Third.FireballSpell) );
AddSpellDefense( typeof(Spells.Third.WallOfStoneSpell) );
AddSpellDefense( typeof(Spells.First.HealSpell) );
}
public DummyStun( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummySuper : Dummy
{
[Constructable]
public DummySuper() : base(AIType.AI_Mage, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Super Mage
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 125, 125, 125 );
this.Skills[SkillName.Magery].Base = 120;
this.Skills[SkillName.EvalInt].Base = 120;
this.Skills[SkillName.Anatomy].Base = 120;
this.Skills[SkillName.Wrestling].Base = 120;
this.Skills[SkillName.Meditation].Base = 120;
this.Skills[SkillName.Poisoning].Base = 100;
this.Skills[SkillName.Inscribe].Base = 100;
// Name
this.Name = "Super Mage";
// Equip
Spellbook book = new Spellbook();
book.Movable = false;
book.LootType = LootType.Newbied;
book.Content =0xFFFFFFFFFFFFFFFF;
AddItem( book );
LeatherArms lea = new LeatherArms();
lea.Movable = false;
lea.LootType = LootType.Newbied;
lea.Crafter = this;
lea.Quality = ArmorQuality.Regular;
AddItem( lea );
LeatherChest lec = new LeatherChest();
lec.Movable = false;
lec.LootType = LootType.Newbied;
lec.Crafter = this;
lec.Quality = ArmorQuality.Regular;
AddItem( lec );
LeatherGorget leg = new LeatherGorget();
leg.Movable = false;
leg.LootType = LootType.Newbied;
leg.Crafter = this;
leg.Quality = ArmorQuality.Regular;
AddItem( leg );
LeatherLegs lel = new LeatherLegs();
lel.Movable = false;
lel.LootType = LootType.Newbied;
lel.Crafter = this;
lel.Quality = ArmorQuality.Regular;
AddItem( lel );
Sandals snd = new Sandals();
snd.Hue = iHue;
snd.LootType = LootType.Newbied;
AddItem( snd );
JesterHat jhat = new JesterHat();
jhat.Hue = iHue;
AddItem( jhat );
Doublet dblt = new Doublet();
dblt.Hue = iHue;
AddItem( dblt );
// Spells
AddSpellAttack( typeof(Spells.First.MagicArrowSpell) );
AddSpellAttack( typeof(Spells.First.WeakenSpell) );
AddSpellAttack( typeof(Spells.Third.FireballSpell) );
AddSpellDefense( typeof(Spells.Third.WallOfStoneSpell) );
AddSpellDefense( typeof(Spells.First.HealSpell) );
}
public DummySuper( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummyHealer : Dummy
{
[Constructable]
public DummyHealer() : base(AIType.AI_Healer, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Healer Mage
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 125, 125, 125 );
this.Skills[SkillName.Magery].Base = 120;
this.Skills[SkillName.EvalInt].Base = 120;
this.Skills[SkillName.Anatomy].Base = 120;
this.Skills[SkillName.Wrestling].Base = 120;
this.Skills[SkillName.Meditation].Base = 120;
this.Skills[SkillName.Healing].Base = 100;
// Name
this.Name = "Healer";
// Equip
Spellbook book = new Spellbook();
book.Movable = false;
book.LootType = LootType.Newbied;
book.Content =0xFFFFFFFFFFFFFFFF;
AddItem( book );
LeatherArms lea = new LeatherArms();
lea.Movable = false;
lea.LootType = LootType.Newbied;
lea.Crafter = this;
lea.Quality = ArmorQuality.Regular;
AddItem( lea );
LeatherChest lec = new LeatherChest();
lec.Movable = false;
lec.LootType = LootType.Newbied;
lec.Crafter = this;
lec.Quality = ArmorQuality.Regular;
AddItem( lec );
LeatherGorget leg = new LeatherGorget();
leg.Movable = false;
leg.LootType = LootType.Newbied;
leg.Crafter = this;
leg.Quality = ArmorQuality.Regular;
AddItem( leg );
LeatherLegs lel = new LeatherLegs();
lel.Movable = false;
lel.LootType = LootType.Newbied;
lel.Crafter = this;
lel.Quality = ArmorQuality.Regular;
AddItem( lel );
Sandals snd = new Sandals();
snd.Hue = iHue;
snd.LootType = LootType.Newbied;
AddItem( snd );
Cap cap = new Cap();
cap.Hue = iHue;
AddItem( cap );
Robe robe = new Robe();
robe.Hue = iHue;
AddItem( robe );
}
public DummyHealer( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummyAssassin : Dummy
{
[Constructable]
public DummyAssassin() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Hybrid Assassin
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 105, 105, 105 );
this.Skills[SkillName.Magery].Base = 120;
this.Skills[SkillName.EvalInt].Base = 120;
this.Skills[SkillName.Swords].Base = 120;
this.Skills[SkillName.Tactics].Base = 120;
this.Skills[SkillName.Meditation].Base = 120;
this.Skills[SkillName.Poisoning].Base = 100;
// Name
this.Name = "Hybrid Assassin";
// Equip
Spellbook book = new Spellbook();
book.Movable = false;
book.LootType = LootType.Newbied;
book.Content =0xFFFFFFFFFFFFFFFF;
AddToBackpack( book );
Katana kat = new Katana();
kat.Movable = false;
kat.LootType = LootType.Newbied;
kat.Crafter = this;
kat.Poison = Poison.Deadly;
kat.PoisonCharges = 12;
kat.Quality = WeaponQuality.Regular;
AddToBackpack( kat );
LeatherArms lea = new LeatherArms();
lea.Movable = false;
lea.LootType = LootType.Newbied;
lea.Crafter = this;
lea.Quality = ArmorQuality.Regular;
AddItem( lea );
LeatherChest lec = new LeatherChest();
lec.Movable = false;
lec.LootType = LootType.Newbied;
lec.Crafter = this;
lec.Quality = ArmorQuality.Regular;
AddItem( lec );
LeatherGorget leg = new LeatherGorget();
leg.Movable = false;
leg.LootType = LootType.Newbied;
leg.Crafter = this;
leg.Quality = ArmorQuality.Regular;
AddItem( leg );
LeatherLegs lel = new LeatherLegs();
lel.Movable = false;
lel.LootType = LootType.Newbied;
lel.Crafter = this;
lel.Quality = ArmorQuality.Regular;
AddItem( lel );
Sandals snd = new Sandals();
snd.Hue = iHue;
snd.LootType = LootType.Newbied;
AddItem( snd );
Cap cap = new Cap();
cap.Hue = iHue;
AddItem( cap );
Robe robe = new Robe();
robe.Hue = iHue;
AddItem( robe );
DeadlyPoisonPotion pota = new DeadlyPoisonPotion();
pota.LootType = LootType.Newbied;
AddToBackpack( pota );
DeadlyPoisonPotion potb = new DeadlyPoisonPotion();
potb.LootType = LootType.Newbied;
AddToBackpack( potb );
DeadlyPoisonPotion potc = new DeadlyPoisonPotion();
potc.LootType = LootType.Newbied;
AddToBackpack( potc );
DeadlyPoisonPotion potd = new DeadlyPoisonPotion();
potd.LootType = LootType.Newbied;
AddToBackpack( potd );
Bandage band = new Bandage( 50 );
AddToBackpack( band );
}
public DummyAssassin( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DummyTheif : Dummy
{
[Constructable]
public DummyTheif() : base(AIType.AI_Thief, FightMode.Closest, 15, 1, 0.2, 0.6)
{
// A Dummy Hybrid Theif
int iHue = 20 + Team * 40;
int jHue = 25 + Team * 40;
// Skills and Stats
this.InitStats( 105, 105, 105 );
this.Skills[SkillName.Healing].Base = 120;
this.Skills[SkillName.Anatomy].Base = 120;
this.Skills[SkillName.Stealing].Base = 120;
this.Skills[SkillName.ArmsLore].Base = 100;
this.Skills[SkillName.Meditation].Base = 120;
this.Skills[SkillName.Wrestling].Base = 120;
// Name
this.Name = "Hybrid Theif";
// Equip
Spellbook book = new Spellbook();
book.Movable = false;
book.LootType = LootType.Newbied;
book.Content =0xFFFFFFFFFFFFFFFF;
AddItem( book );
LeatherArms lea = new LeatherArms();
lea.Movable = false;
lea.LootType = LootType.Newbied;
lea.Crafter = this;
lea.Quality = ArmorQuality.Regular;
AddItem( lea );
LeatherChest lec = new LeatherChest();
lec.Movable = false;
lec.LootType = LootType.Newbied;
lec.Crafter = this;
lec.Quality = ArmorQuality.Regular;
AddItem( lec );
LeatherGorget leg = new LeatherGorget();
leg.Movable = false;
leg.LootType = LootType.Newbied;
leg.Crafter = this;
leg.Quality = ArmorQuality.Regular;
AddItem( leg );
LeatherLegs lel = new LeatherLegs();
lel.Movable = false;
lel.LootType = LootType.Newbied;
lel.Crafter = this;
lel.Quality = ArmorQuality.Regular;
AddItem( lel );
Sandals snd = new Sandals();
snd.Hue = iHue;
snd.LootType = LootType.Newbied;
AddItem( snd );
Cap cap = new Cap();
cap.Hue = iHue;
AddItem( cap );
Robe robe = new Robe();
robe.Hue = iHue;
AddItem( robe );
Bandage band = new Bandage( 50 );
AddToBackpack( band );
}
public DummyTheif( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,140 @@
using System;
using Server;
using Server.Mobiles;
namespace Server
{
public class OppositionGroup
{
private Type[][] m_Types;
public OppositionGroup( Type[][] types )
{
m_Types = types;
}
public bool IsEnemy( object from, object target )
{
int fromGroup = IndexOf( from );
int targGroup = IndexOf( target );
return ( fromGroup != -1 && targGroup != -1 && fromGroup != targGroup );
}
public int IndexOf( object obj )
{
if ( obj == null )
return -1;
Type type = obj.GetType();
for ( int i = 0; i < m_Types.Length; ++i )
{
Type[] group = m_Types[i];
bool contains = false;
for ( int j = 0; !contains && j < group.Length; ++j )
contains = ( type == group[j] );
if ( contains )
return i;
}
return -1;
}
private static OppositionGroup m_TerathansAndOphidians = new OppositionGroup( new Type[][]
{
new Type[]
{
typeof( TerathanAvenger ),
typeof( TerathanDrone ),
typeof( TerathanMatriarch ),
typeof( TerathanWarrior )
},
new Type[]
{
typeof( OphidianArchmage ),
typeof( OphidianKnight ),
typeof( OphidianMage ),
typeof( OphidianMatriarch ),
typeof( OphidianWarrior )
}
} );
public static OppositionGroup TerathansAndOphidians
{
get{ return m_TerathansAndOphidians; }
}
private static OppositionGroup m_SavagesAndOrcs = new OppositionGroup( new Type[][]
{
new Type[]
{
typeof( Orc ),
typeof( OrcBomber ),
typeof( OrcBrute ),
typeof( OrcCaptain ),
typeof( OrcishLord ),
typeof( OrcishMage ),
typeof( SpawnedOrcishLord )
},
new Type[]
{
typeof( Savage ),
typeof( SavageRider ),
typeof( SavageRidgeback ),
typeof( SavageShaman )
}
} );
public static OppositionGroup SavagesAndOrcs
{
get{ return m_SavagesAndOrcs; }
}
private static OppositionGroup m_FeyAndUndead = new OppositionGroup( new Type[][]
{
new Type[]
{
typeof( Centaur ),
typeof( EtherealWarrior ),
typeof( Kirin ),
typeof( LordOaks ),
typeof( Pixie ),
typeof( Silvani ),
typeof( Unicorn ),
typeof( Wisp ),
typeof( Treefellow )
},
new Type[]
{
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 )
}
} );
public static OppositionGroup FeyAndUndead
{
get{ return m_FeyAndUndead; }
}
}
}

View file

@ -0,0 +1,182 @@
using System;
using Server;
using Server.Items;
namespace Server.Mobiles
{
public class Paragon
{
public static double ChestChance = .10; // Chance that a paragon will carry a paragon chest
public static Map[] Maps = new Map[] // Maps that paragons will spawn on
{
Map.Ilshenar
};
public static Type[] Artifacts = new Type[]
{
typeof( GoldBricks ), typeof( PhillipsWoodenSteed ),
typeof( AlchemistsBauble ), typeof( ArcticDeathDealer ),
typeof( BlazeOfDeath ), typeof( BowOfTheJukaKing ),
typeof( BurglarsBandana ), typeof( CavortingClub ),
typeof( EnchantedTitanLegBone ), typeof( GwennosHarp ),
typeof( IolosLute ), typeof( LunaLance ),
typeof( NightsKiss ), typeof( NoxRangersHeavyCrossbow ),
typeof( OrcishVisage ), typeof( PolarBearMask ),
typeof( ShieldOfInvulnerability ), typeof( StaffOfPower ),
typeof( VioletCourage ), typeof( HeartOfTheLion ),
typeof( WrathOfTheDryad ), typeof( PixieSwatter ),
typeof( GlovesOfThePugilist )
};
public static int Hue = 0x501; // Paragon hue
// Buffs
public static double HitsBuff = 5.0;
public static double StrBuff = 1.05;
public static double IntBuff = 1.20;
public static double DexBuff = 1.20;
public static double SkillsBuff = 1.20;
public static double SpeedBuff = 1.20;
public static double FameBuff = 1.40;
public static double KarmaBuff = 1.40;
public static int DamageBuff = 5;
public static void Convert( BaseCreature bc )
{
if ( bc.IsParagon )
return;
bc.Hue = Hue;
if ( bc.HitsMaxSeed >= 0 )
bc.HitsMaxSeed = (int)( bc.HitsMaxSeed * HitsBuff );
bc.RawStr = (int)( bc.RawStr * StrBuff );
bc.RawInt = (int)( bc.RawInt * IntBuff );
bc.RawDex = (int)( bc.RawDex * DexBuff );
bc.Hits = bc.HitsMax;
bc.Mana = bc.ManaMax;
bc.Stam = bc.StamMax;
for( int i = 0; i < bc.Skills.Length; i++ )
{
Skill skill = (Skill)bc.Skills[i];
if ( skill.Base > 0.0 )
skill.Base *= SkillsBuff;
}
bc.PassiveSpeed /= SpeedBuff;
bc.ActiveSpeed /= SpeedBuff;
bc.DamageMin += DamageBuff;
bc.DamageMax += DamageBuff;
if ( bc.Fame > 0 )
bc.Fame = (int)( bc.Fame * FameBuff );
if ( bc.Fame > 32000 )
bc.Fame = 32000;
// TODO: Mana regeneration rate = Sqrt( buffedFame ) / 4
if ( bc.Karma != 0 )
{
bc.Karma = (int)( bc.Karma * KarmaBuff );
if( Math.Abs( bc.Karma ) > 32000 )
bc.Karma = 32000 * Math.Sign( bc.Karma );
}
}
public static void UnConvert( BaseCreature bc )
{
if ( !bc.IsParagon )
return;
bc.Hue = 0;
if ( bc.HitsMaxSeed >= 0 )
bc.HitsMaxSeed = (int)( bc.HitsMaxSeed / HitsBuff );
bc.RawStr = (int)( bc.RawStr / StrBuff );
bc.RawInt = (int)( bc.RawInt / IntBuff );
bc.RawDex = (int)( bc.RawDex / DexBuff );
bc.Hits = bc.HitsMax;
bc.Mana = bc.ManaMax;
bc.Stam = bc.StamMax;
for( int i = 0; i < bc.Skills.Length; i++ )
{
Skill skill = (Skill)bc.Skills[i];
if ( skill.Base > 0.0 )
skill.Base /= SkillsBuff;
}
bc.PassiveSpeed *= SpeedBuff;
bc.ActiveSpeed *= SpeedBuff;
bc.DamageMin -= DamageBuff;
bc.DamageMax -= DamageBuff;
if ( bc.Fame > 0 )
bc.Fame = (int)( bc.Fame / FameBuff );
if ( bc.Karma != 0 )
bc.Karma = (int)( bc.Karma / KarmaBuff );
}
public static bool CheckConvert( BaseCreature bc )
{
return CheckConvert( bc, bc.Location, bc.Map );
}
public static bool CheckConvert( BaseCreature bc, Point3D location, Map m )
{
if ( !Core.AOS )
return false;
if ( Array.IndexOf( Maps, m ) == -1 )
return false;
if ( bc is BaseChampion || bc is Harrower || bc is BaseVendor || bc is BaseEscortable || bc is Clone )
return false;
int fame = bc.Fame;
if ( fame > 32000 )
fame = 32000;
double chance = 1 / Math.Round( 20.0 - ( fame / 3200 ));
return ( chance > Utility.RandomDouble() );
}
public static bool CheckArtifactChance( Mobile m, BaseCreature bc )
{
if ( !Core.AOS )
return false;
double fame = (double)bc.Fame;
if ( fame > 32000 )
fame = 32000;
double chance = 1 / ( Math.Max( 10, 100 * ( 0.83 - Math.Round( Math.Log( Math.Round( fame / 6000, 3 ) + 0.001, 10 ), 3 ) ) ) * ( 100 - Math.Sqrt( m.Luck ) ) / 100.0 );
return chance > Utility.RandomDouble();
}
public static void GiveArtifactTo( Mobile m )
{
Item item = (Item)Activator.CreateInstance( Artifacts[Utility.Random(Artifacts.Length)] );
if ( m.AddToBackpack( item ) )
m.SendMessage( "As a reward for slaying the mighty paragon, an artifact has been placed in your backpack." );
else
m.SendMessage( "As your backpack is full, your reward for destroying the legendary paragon has been placed at your feet." );
}
}
}

View file

@ -0,0 +1,213 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Factions;
namespace Server
{
public class SpeedInfo
{
// Should we use the new method of speeds?
private static bool Enabled = true;
private double m_ActiveSpeed;
private double m_PassiveSpeed;
private Type[] m_Types;
public double ActiveSpeed
{
get{ return m_ActiveSpeed; }
set{ m_ActiveSpeed = value; }
}
public double PassiveSpeed
{
get{ return m_PassiveSpeed; }
set{ m_PassiveSpeed = value; }
}
public Type[] Types
{
get{ return m_Types; }
set{ m_Types = value; }
}
public SpeedInfo( double activeSpeed, double passiveSpeed, Type[] types )
{
m_ActiveSpeed = activeSpeed;
m_PassiveSpeed = passiveSpeed;
m_Types = types;
}
public static bool Contains( object obj )
{
if ( !Enabled )
return false;
if ( m_Table == null )
LoadTable();
SpeedInfo sp = (SpeedInfo)m_Table[obj.GetType()];
return ( sp != null );
}
public static bool GetSpeeds( object obj, ref double activeSpeed, ref double passiveSpeed )
{
if ( !Enabled )
return false;
if ( m_Table == null )
LoadTable();
SpeedInfo sp = (SpeedInfo)m_Table[obj.GetType()];
if ( sp == null )
return false;
activeSpeed = sp.ActiveSpeed;
passiveSpeed = sp.PassiveSpeed;
return true;
}
private static void LoadTable()
{
m_Table = new Hashtable();
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;
}
}
private static Hashtable m_Table;
private static SpeedInfo[] m_Speeds = new SpeedInfo[]
{
/* Slow */
new SpeedInfo( 0.3, 0.6, new Type[]
{
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 Type[]
{
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 )
} ),
/* Very Fast */
new SpeedInfo( 0.175, 0.350, new Type[]
{
typeof( Barracoon ), typeof( Mephitis ), typeof( Neira ),
typeof( Rikktor ), typeof( Semidar ), typeof( EnergyVortex ),
typeof( Beetle ), 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( EliteNinja )
} ),
/* Medium */
new SpeedInfo( 0.25, 0.5, new Type[]
{
typeof( ToxicElemental ), 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( RuneBeetle ), typeof( Gaman ), typeof( Crane )
} )
};
}
}

View file

@ -0,0 +1,45 @@
using System;
using Server;
using Server.Targeting;
using Server.Mobiles;
using System.Collections;
namespace Server.Targets
{
public class AIControlMobileTarget : Target
{
private ArrayList m_List;
private OrderType m_Order;
public OrderType Order
{
get
{
return m_Order;
}
}
public AIControlMobileTarget( BaseAI ai, OrderType order ) : base( -1, false, ( order == OrderType.Attack ? TargetFlags.Harmful : TargetFlags.None ) )
{
m_List = new ArrayList();
m_Order = order;
AddAI( 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 )
{
for ( int i = 0; i < m_List.Count; ++i )
((BaseAI)m_List[i]).EndPickTarget( from, (Mobile)o, m_Order );
}
}
}
}

View file

@ -0,0 +1,32 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
/*
* NPC could use a team objets..
*
* -List of members
* -List of ennemy teams
* -List of ally team
* -Team could be set automaticaly at mobile creation by the region system
* -Team could be the owner of a common timer instead of one by creature
*
*
*
*/
namespace Server.Mobiles
{
public class Team
{
//private ArrayList m_arAlly;
//private ArrayList m_arFoe;
//private ArrayList m_arMember;
public static void Initialize()
{
}
}
}

View file

@ -0,0 +1,29 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
/*
* NPC could use a faction objets..
*
* -List of members
* -List of ennemy factions
* -List of neutral factions
* -List of ally faction
* -Team could be set automaticaly at mobile creation by the region system
* -Team could be the owner of a common timer instead of one by creature
*
*
*
*/
namespace Server.Mobiles
{
public class TeamRegistry
{
//private ArrayList m_arTeam;
public static void Initialize()
{
}
}
}