RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[RunUO 2.0 RC1] BaseSpecialCreature

lillibeth

Wanderer
ok and sorry :)

this is the code

Code:
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Spells;

namespace Server.Mobiles
    {
    public abstract class BaseSpecialCreature : BaseCreature
        {
        public virtual bool DoesTeleporting { get { return false; } }
        public virtual double TeleportingChance { get { return 0.625; } }

        public virtual bool DoesNoxStriking { get { return false; } }
        public virtual double NoxStrikingChance { get { return 0.250; } }

        public virtual bool DoesLifeDraining { get { return false; } }
        public virtual double LifeDrainingChance
            {
            get
                {
                if( Hits < ( HitsMax / Utility.RandomMinMax( 1, 3 ) ) )
                    return 0.125;

                return 0.0;
                }
            }

        public virtual bool DoesTripleBolting { get { return false; } }
        public virtual double TripleBoltingChance { get { return 0.250; } }

        public virtual bool DoesMultiFirebreathing { get { return false; } }
        public virtual double MultiFirebreathingChance { get { return 1.000; } }
        public virtual int BreathDamagePercent { get { return 100; } }
        public virtual int BreathMaxTargets { get { return 5; } }
        public virtual int BreathMaxRange { get { return 5; } }
        public override bool HasBreath { get { return DoesMultiFirebreathing; } }

        public virtual bool DoesEarthquaking { get { return false; } }
        public virtual double EarthquakingChance { get { return 0.250; } }

        public virtual bool DoesSummoning { get { return false; } }
        public virtual double SummoningChance { get { return 0.150; } }
        public virtual double SummoningLowChance { get { return 0.050; } }
        public virtual Type SummoningType { get { return null; } }
        public virtual TimeSpan SummoningDuration { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual TimeSpan SummoningDelay { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual int SummoningSound { get { return -1; } }
        public virtual int SummoningMin { get { return 1; } }
        public virtual int SummoningMax { get { return 1; } }

        public override void OnGotMeleeAttack( Mobile attacker )
            {
            base.OnGotMeleeAttack( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesNoxStriking && NoxStrikingChance >= Utility.RandomDouble() )
                NoxStrike( target );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        public override void OnGaveMeleeAttack( Mobile defender )
            {
            base.OnGaveMeleeAttack( defender );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesEarthquaking && EarthquakingChance >= Utility.RandomDouble() )
                Earthquake();
            }

        public override void OnDamagedBySpell( Mobile attacker )
            {
            base.OnDamagedBySpell( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        #region Summoning

        private DateTime m_NextSummonTime = DateTime.Now;

        public virtual int SummonMinions( Mobile victim )
            {
            int minions = 0;

            if( Map == null || Map == Map.Internal || Map != victim.Map || SummoningType == null )
                return minions;

            if( m_NextSummonTime >= DateTime.Now && Utility.RandomDouble() > SummoningLowChance )
                return minions;

            #region Cantidad de Summons
            int min = SummoningMin;
            int max = SummoningMax;

            if( min > max )
                {
                int aux = min;
                max = min;
                min = max;
                }

            int amount = min;

            if( min != max )
                amount = Utility.RandomMinMax( min, max );

            if( amount < 1 )
                amount = 1;
            #endregion

            for( int m = 0; m < amount; m++ )
                {
                BaseCreature minion;

                try { minion = (BaseCreature)Activator.CreateInstance( SummoningType ); }
                catch { continue; }

                int offset = Utility.Random( 8 ) * 2;
                Point3D selectedOffset = victim.Location;

                for( int i = 0; i < m_Offsets.Length; i += 2 )
                    {
                    int x = X + m_Offsets[( offset + i ) % m_Offsets.Length];
                    int y = Y + m_Offsets[( offset + i + 1 ) % m_Offsets.Length];

                    if( Map.CanSpawnMobile( x, y, Z ) )
                        {
                        selectedOffset = new Point3D( x, y, Z );
                        break;
                        }
                    else
                        {
                        int z = Map.GetAverageZ( x, y );

                        if( Map.CanSpawnMobile( x, y, z ) )
                            {
                            selectedOffset = new Point3D( x, y, z );
                            break;
                            }
                        }
                    }

                BaseCreature.Summon( minion, false, this, selectedOffset, SummoningSound, SummoningDuration );
                minion.Combatant = victim;
                minions++;
                }

            /* NOTA: 
             * 
             * Cada 6 minions esperamos el doble de tiempo que el pautado,
             * esto logra que no se sumonee 28 summons y se tarde lo mismo 
             * que cuando se summonean 3 de ellos. Eh lo.
             */

            m_NextSummonTime = DateTime.Now + TimeSpan.FromSeconds( SummoningDelay.TotalSeconds * ( 0.8 + ( minions * 0.2 ) ) );

            return minions;
            }

        #endregion

        #region Earthquake

        public virtual void Earthquake()
            {
            if( Map == null )
                return;

            ArrayList targets = new ArrayList();

            foreach( Mobile m in this.GetMobilesInRange( 6 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player )
                    targets.Add( m );
                }

            PlaySound( 0x2F3 );

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = targets[i];

                double damage = m.Hits * 0.6;

                if( damage < 10.0 )
                    damage = 10.0;
                else if( damage > 75.0 )
                    damage = 75.0;

                DoHarmful( m );

                AOS.Damage( m, this, (int)damage, 100, 0, 0, 0, 0 );

                if( m.Alive && m.Body.IsHuman && !m.Mounted )
                    m.Animate( 20, 7, 1, true, false, 0 ); // take hit
                }
            }

        #endregion

        #region Multi Breath

        public override void BreathStart( Mobile target )
            {
            base.BreathStart( target ); //tiramos un firebreath al objetivo original.

            if( !DoesMultiFirebreathing || Utility.RandomDouble() > MultiFirebreathingChance )
                return;

            ArrayList posibleTgts = new ArrayList();

            foreach( Mobile m in target.Map.GetMobilesInRange( target.Location, BreathMaxRange ) )
                if( m != null && !m.Deleted && m != target && m.Alive && !m.IsDeadBondedPet &&
                    ( m.AccessLevel < AccessLevel.Counselor || CanSee( m ) ) && CanBeHarmful( m ) &&
                    ( m.Player || ( m is BaseCreature && ( (BaseCreature)m ).Controled ) ) )
                    posibleTgts.Add( m );

            int maxTgts = BreathMaxTargets - 1; //BreathMaxTargets - 1 + el primer firebreath que va al target original.
            int mt = 0;
            int maxAtt = 3;
            int at = 0;

            for( int i = 0; i < posibleTgts.Count && mt++ < maxTgts && at++ < maxAtt; i++ )
                {
                int x = Utility.Random( posibleTgts.Count );
                Mobile t = posibleTgts[x];

                if( t == null || !CanBeHarmful( t ) )
                    return;

                BreathStallMovement();
                BreathPlayAngerSound();
                BreathPlayAngerAnimation();

                Direction = GetDirectionTo( t );

                Timer.DelayCall( TimeSpan.FromSeconds( BreathEffectDelay ), new TimerStateCallback( BreathEffect_Callback ), t );

                posibleTgts.RemoveAt( x );
                at = 0;
                }
            }

        public override int BreathComputeDamage()       //Que haga un toke menos de daño, 
            {                                           //si va a meter 5 firebreaths....
            int fromBase = base.BreathComputeDamage();  //Además, lo usa la Hydra que tiene 1.5Ks de hits, y el Abscess con sus 7Ks.

            if( DoesMultiFirebreathing )
                return (int)( fromBase * ( BreathDamagePercent / 10 ) );

            return fromBase;
            }

        #endregion

        #region Triple Energy Bolts

        private int Bolts = 0;

        public virtual void TripleBolt( Mobile to )
            {
            Bolts = 0;
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            }

        public virtual void Bolt_Callback( object state )
            {
            Mobile to = state as Mobile;

            if( to == null )
                return;

            DoHarmful( to );

            to.BoltEffect( 0 );

            int damage = Utility.RandomMinMax( 23, 29 );

            AOS.Damage( to, this, damage, 0, 0, 0, 0, 100, false );

            if( ++Bolts == 3 && damage > 0 )
                to.SendMessage( "You get shocked and dazed!" );
            }

        #endregion

        #region Teleport

        private Timer m_Timer;

        public static int[] m_Offsets = new int[]
			    {
				-1, -1,
				-1,  0,
				-1,  1,
				0, -1,
				0,  1,
				1, -1,
				1,  0,
				1,  1
			    };

        private class TeleportTimer : Timer
            {
            private BaseSpecialCreature m_Owner;

            public TeleportTimer( BaseSpecialCreature owner )
                : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
                {
                m_Owner = owner;
                }

            protected override void OnTick()
                {
                if( m_Owner.Deleted )
                    {
                    Stop();
                    return;
                    }

                if( Utility.RandomDouble() > m_Owner.TeleportingChance )
                    return;

                Map map = m_Owner.Map;

                if( map == null )
                    return;

                ArrayList<Mobile> toTeleport = new ArrayList<Mobile>();

                foreach( Mobile m in m_Owner.Region.GetMobiles() )
                    if( m != m_Owner && m.Player && m_Owner.CanBeHarmful( m ) && m_Owner.CanSee( m ) && m.AccessLevel < AccessLevel.Counselor )
                        toTeleport.Add( m );

                if( toTeleport.Count > 0 )
                    {
                    int offset = Utility.Random( 8 ) * 2;

                    Point3D to = m_Owner.Location;

                    for( int i = 0; i < m_Offsets.Length; i += 2 )
                        {
                        int x = m_Owner.X + BaseSpecialCreature.m_Offsets[( offset + i ) % BaseSpecialCreature.m_Offsets.Length];
                        int y = m_Owner.Y + BaseSpecialCreature.m_Offsets[( offset + i + 1 ) % BaseSpecialCreature.m_Offsets.Length];

                        if( map.CanSpawnMobile( x, y, m_Owner.Z ) )
                            {
                            to = new Point3D( x, y, m_Owner.Z );
                            break;
                            }
                        else
                            {
                            int z = map.GetAverageZ( x, y );

                            if( map.CanSpawnMobile( x, y, z ) )
                                {
                                to = new Point3D( x, y, z );
                                break;
                                }
                            }
                        }

                    Mobile m = toTeleport[Utility.Random( toTeleport.Count )];

                    Point3D from = m.Location;

                    m.Location = to;

                    SpellHelper.Turn( m_Owner, m );
                    SpellHelper.Turn( m, m_Owner );

                    m.ProcessDelta();

                    Effects.SendLocationParticles( EffectItem.Create( from, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
                    Effects.SendLocationParticles( EffectItem.Create( to, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );

                    m.PlaySound( 0x1FE );

                    m_Owner.Combatant = m;
                    }
                }
            }

        #endregion

        #region NoxStrike

        public virtual void NoxStrike( Mobile attacker )
            {
            /* Counterattack with Hit Poison Area
             * 20-25 damage, unresistable
             * Lethal poison, 100% of the time
             * Particle effect: Type: "2" From: "0x4061A107" To: "0x0" ItemId: "0x36BD" ItemIdName: "explosion" FromLocation: "(296 615, 17)" ToLocation: "(296 615, 17)" Speed: "1" Duration: "10" FixedDirection: "True" Explode: "False" Hue: "0xA6" RenderMode: "0x0" Effect: "0x1F78" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x4061A107" Layer: "255" Unknown: "0x0"
             * Doesn't work on provoked monsters
             */

            if( attacker is BaseCreature && ( (BaseCreature)attacker ).BardProvoked )
                return;

            Mobile target = null;

            if( attacker is BaseCreature )
                {
                Mobile m = ( (BaseCreature)attacker ).GetMaster();

                if( m != null )
                    target = m;
                }

            if( target == null || !target.InRange( this, 18 ) )
                target = attacker;

            this.Animate( 10, 4, 1, true, false, 0 );

            ArrayList targets = new ArrayList();

            foreach( Mobile m in target.GetMobilesInRange( 8 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player && m.Alive )
                    targets.Add( m );
                }

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = targets[i];

                DoHarmful( m );

                AOS.Damage( m, this, Utility.RandomMinMax( 20, 25 ), true, 0, 0, 0, 100, 0 );

                m.FixedParticles( 0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255 );
                m.ApplyPoison( this, Poison.Lethal );
                }
            }

        #endregion

        #region DrainLife

        public virtual void DrainLife()
            {
            ArrayList ArrayList = new ArrayList();

            foreach( Mobile m in Region.GetMobiles() )
                {
                if( m == this || !CanBeHarmful( m ) || !CanSee( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != Team ) )
                    ArrayList.Add( m );
                else if( m.Player )
                    ArrayList.Add( m );
                }

            foreach( Mobile m in ArrayList )
                {
                DoHarmful( m );

                m.FixedParticles( 0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist );
                m.PlaySound( 0x231 );

                m.SendMessage( "You feel the life drain out of you!" );

                int toDrain = Utility.RandomMinMax( 10, 40 );

                Hits += toDrain;
                m.Damage( toDrain, this );
                }
            }

        #endregion

        public BaseSpecialCreature( AIType ai, FightMode mode, int iRangePerception, int iRangeFight, double dActiveSpeed, double dPassiveSpeed )
            : base( ai, mode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public BaseSpecialCreature( Serial serial )
            : base( serial )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); }
        public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); }
        }
    }

and this is the errors

Code:
RunUO - Running with nothing!
RunUO - [www.runuo.com] Version 1.0.0, Build 28438
Scripts: Compiling C# scripts...failed (10 errors, 7 warnings)
 - Warning: Scripts\Andaria\Items\PSBook.cs: CS0162: (line 288, column 20) Unrea
chable code detected
 - Warning: Scripts\Andaria\Lillibeth\Craft\LostAlchemy\RepairTarget.cs: CS0168:
 (line 32, column 9) The variable 'number' is declared but never used
 - Warning: Scripts\Andaria\Lillibeth\Mobiles\Eater\Eater.cs: CS0183: (line 76,
column 9) The given expression is always of the provided ('Server.Mobiles.BaseCr
eature') type
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS002
9: (line 216, column 28) Cannot implicitly convert type 'object' to 'Server.Mobi
le'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS002
9: (line 261, column 28) Cannot implicitly convert type 'object' to 'Server.Mobi
le'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS002
9: (line 467, column 28) Cannot implicitly convert type 'object' to 'Server.Mobi
le'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS150
2: (line 471, column 17) The best overloaded method match for 'Server.AOS.Damage
(Server.Mobile, Server.Mobile, int, int, int, int, int, int, bool)' has some inv
alid arguments
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS150
3: (line 471, column 70) Argument '4': cannot convert from 'bool' to 'int'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS150
3: (line 471, column 90) Argument '9': cannot convert from 'int' to 'bool'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS011
7: (line 486, column 34) 'Server.Region' does not contain a definition for 'GetM
obiles'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS152
6: (line 366, column 61) A new expression requires () or [] after type
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS152
5: (line 366, column 70) Invalid expression term ')'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS102
6: (line 366, column 71) ) expected
 - Warning: Scripts\Andaria\Lillibeth\PvP System\Evil Reward System\CloakOfTheDa
mned.cs: CS0162: (line 57, column 4) Unreachable code detected
 - Warning: Scripts\Andaria\Lillibeth\PvP System\Evil Reward System\ShroudOfSoul
s.cs: CS0162: (line 48, column 4) Unreachable code detected
 - Warning: Scripts\Mobiles\PlayerMobile.custom.cs: CS0162: (line 3160, column 4
) Unreachable code detected
 - Warning: Scripts\Mobiles\Special\BaseChampion.custom.cs: CS0184: (line 195, c
olumn 10) The given expression is never of the provided ('Server.Mobiles.Serado'
) type
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.
 

Kenko

Page
try this
Code:
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Spells;

namespace Server.Mobiles
    {
    public abstract class BaseSpecialCreature : BaseCreature
        {
        public virtual bool DoesTeleporting { get { return false; } }
        public virtual double TeleportingChance { get { return 0.625; } }

        public virtual bool DoesNoxStriking { get { return false; } }
        public virtual double NoxStrikingChance { get { return 0.250; } }

        public virtual bool DoesLifeDraining { get { return false; } }
        public virtual double LifeDrainingChance
            {
            get
                {
                if( Hits < ( HitsMax / Utility.RandomMinMax( 1, 3 ) ) )
                    return 0.125;

                return 0.0;
                }
            }

        public virtual bool DoesTripleBolting { get { return false; } }
        public virtual double TripleBoltingChance { get { return 0.250; } }

        public virtual bool DoesMultiFirebreathing { get { return false; } }
        public virtual double MultiFirebreathingChance { get { return 1.000; } }
        public virtual int BreathDamagePercent { get { return 100; } }
        public virtual int BreathMaxTargets { get { return 5; } }
        public virtual int BreathMaxRange { get { return 5; } }
        public override bool HasBreath { get { return DoesMultiFirebreathing; } }

        public virtual bool DoesEarthquaking { get { return false; } }
        public virtual double EarthquakingChance { get { return 0.250; } }

        public virtual bool DoesSummoning { get { return false; } }
        public virtual double SummoningChance { get { return 0.150; } }
        public virtual double SummoningLowChance { get { return 0.050; } }
        public virtual Type SummoningType { get { return null; } }
        public virtual TimeSpan SummoningDuration { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual TimeSpan SummoningDelay { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual int SummoningSound { get { return -1; } }
        public virtual int SummoningMin { get { return 1; } }
        public virtual int SummoningMax { get { return 1; } }

        public override void OnGotMeleeAttack( Mobile attacker )
            {
            base.OnGotMeleeAttack( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesNoxStriking && NoxStrikingChance >= Utility.RandomDouble() )
                NoxStrike( target );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        public override void OnGaveMeleeAttack( Mobile defender )
            {
            base.OnGaveMeleeAttack( defender );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesEarthquaking && EarthquakingChance >= Utility.RandomDouble() )
                Earthquake();
            }

        public override void OnDamagedBySpell( Mobile attacker )
            {
            base.OnDamagedBySpell( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        #region Summoning

        private DateTime m_NextSummonTime = DateTime.Now;

        public virtual int SummonMinions( Mobile victim )
            {
            int minions = 0;

            if( Map == null || Map == Map.Internal || Map != victim.Map || SummoningType == null )
                return minions;

            if( m_NextSummonTime >= DateTime.Now && Utility.RandomDouble() > SummoningLowChance )
                return minions;

            #region Cantidad de Summons
            int min = SummoningMin;
            int max = SummoningMax;

            if( min > max )
                {
                int aux = min;
                max = min;
                min = max;
                }

            int amount = min;

            if( min != max )
                amount = Utility.RandomMinMax( min, max );

            if( amount < 1 )
                amount = 1;
            #endregion

            for( int m = 0; m < amount; m++ )
                {
                BaseCreature minion;

                try { minion = (BaseCreature)Activator.CreateInstance( SummoningType ); }
                catch { continue; }

                int offset = Utility.Random( 8 ) * 2;
                Point3D selectedOffset = victim.Location;

                for( int i = 0; i < m_Offsets.Length; i += 2 )
                    {
                    int x = X + m_Offsets[( offset + i ) % m_Offsets.Length];
                    int y = Y + m_Offsets[( offset + i + 1 ) % m_Offsets.Length];

                    if( Map.CanSpawnMobile( x, y, Z ) )
                        {
                        selectedOffset = new Point3D( x, y, Z );
                        break;
                        }
                    else
                        {
                        int z = Map.GetAverageZ( x, y );

                        if( Map.CanSpawnMobile( x, y, z ) )
                            {
                            selectedOffset = new Point3D( x, y, z );
                            break;
                            }
                        }
                    }

                BaseCreature.Summon( minion, false, this, selectedOffset, SummoningSound, SummoningDuration );
                minion.Combatant = victim;
                minions++;
                }

            /* NOTA: 
             * 
             * Cada 6 minions esperamos el doble de tiempo que el pautado,
             * esto logra que no se sumonee 28 summons y se tarde lo mismo 
             * que cuando se summonean 3 de ellos. Eh lo.
             */

            m_NextSummonTime = DateTime.Now + TimeSpan.FromSeconds( SummoningDelay.TotalSeconds * ( 0.8 + ( minions * 0.2 ) ) );

            return minions;
            }

        #endregion

        #region Earthquake

        public virtual void Earthquake()
            {
            if( Map == null )
                return;

            ArrayList targets = new ArrayList();

            foreach( Mobile m in this.GetMobilesInRange( 6 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player )
                    targets.Add( m );
                }

            PlaySound( 0x2F3 );

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = (Mobile)targets[i];

                double damage = m.Hits * 0.6;

                if( damage < 10.0 )
                    damage = 10.0;
                else if( damage > 75.0 )
                    damage = 75.0;

                DoHarmful( m );

                AOS.Damage( m, this, (int)damage, 100, 0, 0, 0, 0 );

                if( m.Alive && m.Body.IsHuman && !m.Mounted )
                    m.Animate( 20, 7, 1, true, false, 0 ); // take hit
                }
            }

        #endregion

        #region Multi Breath

        public override void BreathStart( Mobile target )
            {
            base.BreathStart( target ); //tiramos un firebreath al objetivo original.

            if( !DoesMultiFirebreathing || Utility.RandomDouble() > MultiFirebreathingChance )
                return;

            ArrayList posibleTgts = new ArrayList();

            foreach( Mobile m in target.Map.GetMobilesInRange( target.Location, BreathMaxRange ) )
                if( m != null && !m.Deleted && m != target && m.Alive && !m.IsDeadBondedPet &&
                    ( m.AccessLevel < AccessLevel.Counselor || CanSee( m ) ) && CanBeHarmful( m ) &&
                    ( m.Player || ( m is BaseCreature && ( (BaseCreature)m ).Controled ) ) )
                    posibleTgts.Add( m );

            int maxTgts = BreathMaxTargets - 1; //BreathMaxTargets - 1 + el primer firebreath que va al target original.
            int mt = 0;
            int maxAtt = 3;
            int at = 0;

            for( int i = 0; i < posibleTgts.Count && mt++ < maxTgts && at++ < maxAtt; i++ )
                {
                int x = Utility.Random( posibleTgts.Count );
                Mobile t = (Mobile)posibleTgts[x];

                if( t == null || !CanBeHarmful( t ) )
                    return;

                BreathStallMovement();
                BreathPlayAngerSound();
                BreathPlayAngerAnimation();

                Direction = GetDirectionTo( t );

                Timer.DelayCall( TimeSpan.FromSeconds( BreathEffectDelay ), new TimerStateCallback( BreathEffect_Callback ), t );

                posibleTgts.RemoveAt( x );
                at = 0;
                }
            }

        public override int BreathComputeDamage()       //Que haga un toke menos de daño, 
            {                                           //si va a meter 5 firebreaths....
            int fromBase = base.BreathComputeDamage();  //Además, lo usa la Hydra que tiene 1.5Ks de hits, y el Abscess con sus 7Ks.

            if( DoesMultiFirebreathing )
                return (int)( fromBase * ( BreathDamagePercent / 10 ) );

            return fromBase;
            }

        #endregion

        #region Triple Energy Bolts

        private int Bolts = 0;

        public virtual void TripleBolt( Mobile to )
            {
            Bolts = 0;
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            }

        public virtual void Bolt_Callback( object state )
            {
            Mobile to = state as Mobile;

            if( to == null )
                return;

            DoHarmful( to );

            to.BoltEffect( 0 );

            int damage = Utility.RandomMinMax( 23, 29 );

            AOS.Damage( to, this, damage, 0, 0, 0, 0, 100, false );

            if( ++Bolts == 3 && damage > 0 )
                to.SendMessage( "You get shocked and dazed!" );
            }

        #endregion

        #region Teleport

        private Timer m_Timer;

        public static int[] m_Offsets = new int[]
			    {
				-1, -1,
				-1,  0,
				-1,  1,
				0, -1,
				0,  1,
				1, -1,
				1,  0,
				1,  1
			    };

        private class TeleportTimer : Timer
            {
            private BaseSpecialCreature m_Owner;

            public TeleportTimer( BaseSpecialCreature owner )
                : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
                {
                m_Owner = owner;
                }

            protected override void OnTick()
                {
                if( m_Owner.Deleted )
                    {
                    Stop();
                    return;
                    }

                if( Utility.RandomDouble() > m_Owner.TeleportingChance )
                    return;

                Map map = m_Owner.Map;

                if( map == null )
                    return;

                ArrayList toTeleport = new ArrayList();

                foreach( Mobile m in m_Owner.Region.GetMobiles() )
                    if( m != m_Owner && m.Player && m_Owner.CanBeHarmful( m ) && m_Owner.CanSee( m ) && m.AccessLevel < AccessLevel.Counselor )
                        toTeleport.Add( m );

                if( toTeleport.Count > 0 )
                    {
                    int offset = Utility.Random( 8 ) * 2;

                    Point3D to = m_Owner.Location;

                    for( int i = 0; i < m_Offsets.Length; i += 2 )
                        {
                        int x = m_Owner.X + BaseSpecialCreature.m_Offsets[( offset + i ) % BaseSpecialCreature.m_Offsets.Length];
                        int y = m_Owner.Y + BaseSpecialCreature.m_Offsets[( offset + i + 1 ) % BaseSpecialCreature.m_Offsets.Length];

                        if( map.CanSpawnMobile( x, y, m_Owner.Z ) )
                            {
                            to = new Point3D( x, y, m_Owner.Z );
                            break;
                            }
                        else
                            {
                            int z = map.GetAverageZ( x, y );

                            if( map.CanSpawnMobile( x, y, z ) )
                                {
                                to = new Point3D( x, y, z );
                                break;
                                }
                            }
                        }

                    Mobile m = toTeleport[Utility.Random( toTeleport.Count )];

                    Point3D from = m.Location;

                    m.Location = to;

                    SpellHelper.Turn( m_Owner, m );
                    SpellHelper.Turn( m, m_Owner );

                    m.ProcessDelta();

                    Effects.SendLocationParticles( EffectItem.Create( from, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
                    Effects.SendLocationParticles( EffectItem.Create( to, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );

                    m.PlaySound( 0x1FE );

                    m_Owner.Combatant = m;
                    }
                }
            }

        #endregion

        #region NoxStrike

        public virtual void NoxStrike( Mobile attacker )
            {
            /* Counterattack with Hit Poison Area
             * 20-25 damage, unresistable
             * Lethal poison, 100% of the time
             * Particle effect: Type: "2" From: "0x4061A107" To: "0x0" ItemId: "0x36BD" ItemIdName: "explosion" FromLocation: "(296 615, 17)" ToLocation: "(296 615, 17)" Speed: "1" Duration: "10" FixedDirection: "True" Explode: "False" Hue: "0xA6" RenderMode: "0x0" Effect: "0x1F78" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x4061A107" Layer: "255" Unknown: "0x0"
             * Doesn't work on provoked monsters
             */

            if( attacker is BaseCreature && ( (BaseCreature)attacker ).BardProvoked )
                return;

            Mobile target = null;

            if( attacker is BaseCreature )
                {
                Mobile m = ( (BaseCreature)attacker ).GetMaster();

                if( m != null )
                    target = m;
                }

            if( target == null || !target.InRange( this, 18 ) )
                target = attacker;

            this.Animate( 10, 4, 1, true, false, 0 );

            ArrayList targets = new ArrayList();

            foreach( Mobile m in target.GetMobilesInRange( 8 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player && m.Alive )
                    targets.Add( m );
                }

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = (Mobile)targets[i];

                DoHarmful( m );

                AOS.Damage( m, this, Utility.RandomMinMax( 20, 25 ), 0, 0, 0, 100, 0, true );

                m.FixedParticles( 0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255 );
                m.ApplyPoison( this, Poison.Lethal );
                }
            }

        #endregion

        #region DrainLife

        public virtual void DrainLife()
            {
            ArrayList ArrayList = new ArrayList();

            foreach( Mobile m in GetMobilesInRange(3) )
                {
                if( m == this || !CanBeHarmful( m ) || !CanSee( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != Team ) )
                    ArrayList.Add( m );
                else if( m.Player )
                    ArrayList.Add( m );
                }

            foreach( Mobile m in ArrayList )
                {
                DoHarmful( m );

                m.FixedParticles( 0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist );
                m.PlaySound( 0x231 );

                m.SendMessage( "You feel the life drain out of you!" );

                int toDrain = Utility.RandomMinMax( 10, 40 );

                Hits += toDrain;
                m.Damage( toDrain, this );
                }
            }

        #endregion

        public BaseSpecialCreature( AIType ai, FightMode mode, int iRangePerception, int iRangeFight, double dActiveSpeed, double dPassiveSpeed )
            : base( ai, mode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public BaseSpecialCreature( Serial serial )
            : base( serial )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); }
        public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); }
        }
    }
 

lillibeth

Wanderer
whit this script

Code:
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Spells;

namespace Server.Mobiles
    {
    public abstract class BaseSpecialCreature : BaseCreature
        {
        public virtual bool DoesTeleporting { get { return false; } }
        public virtual double TeleportingChance { get { return 0.625; } }

        public virtual bool DoesNoxStriking { get { return false; } }
        public virtual double NoxStrikingChance { get { return 0.250; } }

        public virtual bool DoesLifeDraining { get { return false; } }
        public virtual double LifeDrainingChance
            {
            get
                {
                if( Hits < ( HitsMax / Utility.RandomMinMax( 1, 3 ) ) )
                    return 0.125;

                return 0.0;
                }
            }

        public virtual bool DoesTripleBolting { get { return false; } }
        public virtual double TripleBoltingChance { get { return 0.250; } }

        public virtual bool DoesMultiFirebreathing { get { return false; } }
        public virtual double MultiFirebreathingChance { get { return 1.000; } }
        public virtual int BreathDamagePercent { get { return 100; } }
        public virtual int BreathMaxTargets { get { return 5; } }
        public virtual int BreathMaxRange { get { return 5; } }
        public override bool HasBreath { get { return DoesMultiFirebreathing; } }

        public virtual bool DoesEarthquaking { get { return false; } }
        public virtual double EarthquakingChance { get { return 0.250; } }

        public virtual bool DoesSummoning { get { return false; } }
        public virtual double SummoningChance { get { return 0.150; } }
        public virtual double SummoningLowChance { get { return 0.050; } }
        public virtual Type SummoningType { get { return null; } }
        public virtual TimeSpan SummoningDuration { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual TimeSpan SummoningDelay { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual int SummoningSound { get { return -1; } }
        public virtual int SummoningMin { get { return 1; } }
        public virtual int SummoningMax { get { return 1; } }

        public override void OnGotMeleeAttack( Mobile attacker )
            {
            base.OnGotMeleeAttack( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesNoxStriking && NoxStrikingChance >= Utility.RandomDouble() )
                NoxStrike( target );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        public override void OnGaveMeleeAttack( Mobile defender )
            {
            base.OnGaveMeleeAttack( defender );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesEarthquaking && EarthquakingChance >= Utility.RandomDouble() )
                Earthquake();
            }

        public override void OnDamagedBySpell( Mobile attacker )
            {
            base.OnDamagedBySpell( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        #region Summoning

        private DateTime m_NextSummonTime = DateTime.Now;

        public virtual int SummonMinions( Mobile victim )
            {
            int minions = 0;

            if( Map == null || Map == Map.Internal || Map != victim.Map || SummoningType == null )
                return minions;

            if( m_NextSummonTime >= DateTime.Now && Utility.RandomDouble() > SummoningLowChance )
                return minions;

            #region Cantidad de Summons
            int min = SummoningMin;
            int max = SummoningMax;

            if( min > max )
                {
                int aux = min;
                max = min;
                min = max;
                }

            int amount = min;

            if( min != max )
                amount = Utility.RandomMinMax( min, max );

            if( amount < 1 )
                amount = 1;
            #endregion

            for( int m = 0; m < amount; m++ )
                {
                BaseCreature minion;

                try { minion = (BaseCreature)Activator.CreateInstance( SummoningType ); }
                catch { continue; }

                int offset = Utility.Random( 8 ) * 2;
                Point3D selectedOffset = victim.Location;

                for( int i = 0; i < m_Offsets.Length; i += 2 )
                    {
                    int x = X + m_Offsets[( offset + i ) % m_Offsets.Length];
                    int y = Y + m_Offsets[( offset + i + 1 ) % m_Offsets.Length];

                    if( Map.CanSpawnMobile( x, y, Z ) )
                        {
                        selectedOffset = new Point3D( x, y, Z );
                        break;
                        }
                    else
                        {
                        int z = Map.GetAverageZ( x, y );

                        if( Map.CanSpawnMobile( x, y, z ) )
                            {
                            selectedOffset = new Point3D( x, y, z );
                            break;
                            }
                        }
                    }

                BaseCreature.Summon( minion, false, this, selectedOffset, SummoningSound, SummoningDuration );
                minion.Combatant = victim;
                minions++;
                }

            /* NOTA: 
             * 
             * Cada 6 minions esperamos el doble de tiempo que el pautado,
             * esto logra que no se sumonee 28 summons y se tarde lo mismo 
             * que cuando se summonean 3 de ellos. Eh lo.
             */

            m_NextSummonTime = DateTime.Now + TimeSpan.FromSeconds( SummoningDelay.TotalSeconds * ( 0.8 + ( minions * 0.2 ) ) );

            return minions;
            }

        #endregion

        #region Earthquake

        public virtual void Earthquake()
            {
            if( Map == null )
                return;

            ArrayList targets = new ArrayList();

            foreach( Mobile m in this.GetMobilesInRange( 6 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player )
                    targets.Add( m );
                }

            PlaySound( 0x2F3 );

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = (Mobile)targets[i];

                double damage = m.Hits * 0.6;

                if( damage < 10.0 )
                    damage = 10.0;
                else if( damage > 75.0 )
                    damage = 75.0;

                DoHarmful( m );

                AOS.Damage( m, this, (int)damage, 100, 0, 0, 0, 0 );

                if( m.Alive && m.Body.IsHuman && !m.Mounted )
                    m.Animate( 20, 7, 1, true, false, 0 ); // take hit
                }
            }

        #endregion

        #region Multi Breath

        public override void BreathStart( Mobile target )
            {
            base.BreathStart( target ); //tiramos un firebreath al objetivo original.

            if( !DoesMultiFirebreathing || Utility.RandomDouble() > MultiFirebreathingChance )
                return;

            ArrayList posibleTgts = new ArrayList();

            foreach( Mobile m in target.Map.GetMobilesInRange( target.Location, BreathMaxRange ) )
                if( m != null && !m.Deleted && m != target && m.Alive && !m.IsDeadBondedPet &&
                    ( m.AccessLevel < AccessLevel.Counselor || CanSee( m ) ) && CanBeHarmful( m ) &&
                    ( m.Player || ( m is BaseCreature && ( (BaseCreature)m ).Controled ) ) )
                    posibleTgts.Add( m );

            int maxTgts = BreathMaxTargets - 1; //BreathMaxTargets - 1 + el primer firebreath que va al target original.
            int mt = 0;
            int maxAtt = 3;
            int at = 0;

            for( int i = 0; i < posibleTgts.Count && mt++ < maxTgts && at++ < maxAtt; i++ )
                {
                int x = Utility.Random( posibleTgts.Count );
                Mobile t = (Mobile)posibleTgts[x];

                if( t == null || !CanBeHarmful( t ) )
                    return;

                BreathStallMovement();
                BreathPlayAngerSound();
                BreathPlayAngerAnimation();

                Direction = GetDirectionTo( t );

                Timer.DelayCall( TimeSpan.FromSeconds( BreathEffectDelay ), new TimerStateCallback( BreathEffect_Callback ), t );

                posibleTgts.RemoveAt( x );
                at = 0;
                }
            }

        public override int BreathComputeDamage()       //Que haga un toke menos de daño, 
            {                                           //si va a meter 5 firebreaths....
            int fromBase = base.BreathComputeDamage();  //Además, lo usa la Hydra que tiene 1.5Ks de hits, y el Abscess con sus 7Ks.

            if( DoesMultiFirebreathing )
                return (int)( fromBase * ( BreathDamagePercent / 10 ) );

            return fromBase;
            }

        #endregion

        #region Triple Energy Bolts

        private int Bolts = 0;

        public virtual void TripleBolt( Mobile to )
            {
            Bolts = 0;
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            }

        public virtual void Bolt_Callback( object state )
            {
            Mobile to = state as Mobile;

            if( to == null )
                return;

            DoHarmful( to );

            to.BoltEffect( 0 );

            int damage = Utility.RandomMinMax( 23, 29 );

            AOS.Damage( to, this, damage, 0, 0, 0, 0, 100, false );

            if( ++Bolts == 3 && damage > 0 )
                to.SendMessage( "You get shocked and dazed!" );
            }

        #endregion

        #region Teleport

        private Timer m_Timer;

        public static int[] m_Offsets = new int[]
			    {
				-1, -1,
				-1,  0,
				-1,  1,
				0, -1,
				0,  1,
				1, -1,
				1,  0,
				1,  1
			    };

        private class TeleportTimer : Timer
            {
            private BaseSpecialCreature m_Owner;

            public TeleportTimer( BaseSpecialCreature owner )
                : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
                {
                m_Owner = owner;
                }

            protected override void OnTick()
                {
                if( m_Owner.Deleted )
                    {
                    Stop();
                    return;
                    }

                if( Utility.RandomDouble() > m_Owner.TeleportingChance )
                    return;

                Map map = m_Owner.Map;

                if( map == null )
                    return;

                ArrayList toTeleport = new ArrayList();

                foreach( Mobile m in m_Owner.Region.GetMobiles() )
                    if( m != m_Owner && m.Player && m_Owner.CanBeHarmful( m ) && m_Owner.CanSee( m ) && m.AccessLevel < AccessLevel.Counselor )
                        toTeleport.Add( m );

                if( toTeleport.Count > 0 )
                    {
                    int offset = Utility.Random( 8 ) * 2;

                    Point3D to = m_Owner.Location;

                    for( int i = 0; i < m_Offsets.Length; i += 2 )
                        {
                        int x = m_Owner.X + BaseSpecialCreature.m_Offsets[( offset + i ) % BaseSpecialCreature.m_Offsets.Length];
                        int y = m_Owner.Y + BaseSpecialCreature.m_Offsets[( offset + i + 1 ) % BaseSpecialCreature.m_Offsets.Length];

                        if( map.CanSpawnMobile( x, y, m_Owner.Z ) )
                            {
                            to = new Point3D( x, y, m_Owner.Z );
                            break;
                            }
                        else
                            {
                            int z = map.GetAverageZ( x, y );

                            if( map.CanSpawnMobile( x, y, z ) )
                                {
                                to = new Point3D( x, y, z );
                                break;
                                }
                            }
                        }

                    Mobile m = toTeleport[Utility.Random( toTeleport.Count )];

                    Point3D from = m.Location;

                    m.Location = to;

                    SpellHelper.Turn( m_Owner, m );
                    SpellHelper.Turn( m, m_Owner );

                    m.ProcessDelta();

                    Effects.SendLocationParticles( EffectItem.Create( from, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
                    Effects.SendLocationParticles( EffectItem.Create( to, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );

                    m.PlaySound( 0x1FE );

                    m_Owner.Combatant = m;
                    }
                }
            }

        #endregion

        #region NoxStrike

        public virtual void NoxStrike( Mobile attacker )
            {
            /* Counterattack with Hit Poison Area
             * 20-25 damage, unresistable
             * Lethal poison, 100% of the time
             * Particle effect: Type: "2" From: "0x4061A107" To: "0x0" ItemId: "0x36BD" ItemIdName: "explosion" FromLocation: "(296 615, 17)" ToLocation: "(296 615, 17)" Speed: "1" Duration: "10" FixedDirection: "True" Explode: "False" Hue: "0xA6" RenderMode: "0x0" Effect: "0x1F78" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x4061A107" Layer: "255" Unknown: "0x0"
             * Doesn't work on provoked monsters
             */

            if( attacker is BaseCreature && ( (BaseCreature)attacker ).BardProvoked )
                return;

            Mobile target = null;

            if( attacker is BaseCreature )
                {
                Mobile m = ( (BaseCreature)attacker ).GetMaster();

                if( m != null )
                    target = m;
                }

            if( target == null || !target.InRange( this, 18 ) )
                target = attacker;

            this.Animate( 10, 4, 1, true, false, 0 );

            ArrayList targets = new ArrayList();

            foreach( Mobile m in target.GetMobilesInRange( 8 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player && m.Alive )
                    targets.Add( m );
                }

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = (Mobile)targets[i];

                DoHarmful( m );

                AOS.Damage( m, this, Utility.RandomMinMax( 20, 25 ), 0, 0, 0, 100, 0, true );

                m.FixedParticles( 0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255 );
                m.ApplyPoison( this, Poison.Lethal );
                }
            }

        #endregion

        #region DrainLife

        public virtual void DrainLife()
            {
            ArrayList ArrayList = new ArrayList();

            foreach( Mobile m in GetMobilesInRange(3) )
                {
                if( m == this || !CanBeHarmful( m ) || !CanSee( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != Team ) )
                    ArrayList.Add( m );
                else if( m.Player )
                    ArrayList.Add( m );
                }

            foreach( Mobile m in ArrayList )
                {
                DoHarmful( m );

                m.FixedParticles( 0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist );
                m.PlaySound( 0x231 );

                m.SendMessage( "You feel the life drain out of you!" );

                int toDrain = Utility.RandomMinMax( 10, 40 );

                Hits += toDrain;
                m.Damage( toDrain, this );
                }
            }

        #endregion

        public BaseSpecialCreature( AIType ai, FightMode mode, int iRangePerception, int iRangeFight, double dActiveSpeed, double dPassiveSpeed )
            : base( ai, mode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public BaseSpecialCreature( Serial serial )
            : base( serial )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); }
        public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); }
        }
    }

i get onlytwo errors...those

Code:
RunUO - Running with nothing!
RunUO - [www.runuo.com] Version 1.0.0, Build 28438
Scripts: Compiling C# scripts...failed (2 errors, 7 warnings)
 - Warning: Scripts\Andaria\Items\PSBook.cs: CS0162: (line 288, column 20) Unrea
chable code detected
 - Warning: Scripts\Andaria\Lillibeth\Craft\LostAlchemy\RepairTarget.cs: CS0168:
 (line 32, column 9) The variable 'number' is declared but never used
 - Warning: Scripts\Andaria\Lillibeth\Mobiles\Eater\Eater.cs: CS0183: (line 76,
column 9) The given expression is always of the provided ('Server.Mobiles.BaseCr
eature') type
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS011
7: (line 368, column 38) 'Server.Region' does not contain a definition for 'GetM
obiles'
 - Error: Scripts\Andaria\Lillibeth\Prove TEcniche\BaseSpecialCreature.cs: CS002
9: (line 400, column 32) Cannot implicitly convert type 'object' to 'Server.Mobi
le'
 - Warning: Scripts\Andaria\Lillibeth\PvP System\Evil Reward System\CloakOfTheDa
mned.cs: CS0162: (line 57, column 4) Unreachable code detected
 - Warning: Scripts\Andaria\Lillibeth\PvP System\Evil Reward System\ShroudOfSoul
s.cs: CS0162: (line 48, column 4) Unreachable code detected
 - Warning: Scripts\Mobiles\PlayerMobile.custom.cs: CS0162: (line 3160, column 4
) Unreachable code detected
 - Warning: Scripts\Mobiles\Special\BaseChampion.custom.cs: CS0184: (line 195, c
olumn 10) The given expression is never of the provided ('Server.Mobiles.Serado'
) type
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.
 

Kenko

Page
Code:
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Spells;

namespace Server.Mobiles
    {
    public abstract class BaseSpecialCreature : BaseCreature
        {
        public virtual bool DoesTeleporting { get { return false; } }
        public virtual double TeleportingChance { get { return 0.625; } }

        public virtual bool DoesNoxStriking { get { return false; } }
        public virtual double NoxStrikingChance { get { return 0.250; } }

        public virtual bool DoesLifeDraining { get { return false; } }
        public virtual double LifeDrainingChance
            {
            get
                {
                if( Hits < ( HitsMax / Utility.RandomMinMax( 1, 3 ) ) )
                    return 0.125;

                return 0.0;
                }
            }

        public virtual bool DoesTripleBolting { get { return false; } }
        public virtual double TripleBoltingChance { get { return 0.250; } }

        public virtual bool DoesMultiFirebreathing { get { return false; } }
        public virtual double MultiFirebreathingChance { get { return 1.000; } }
        public virtual int BreathDamagePercent { get { return 100; } }
        public virtual int BreathMaxTargets { get { return 5; } }
        public virtual int BreathMaxRange { get { return 5; } }
        public override bool HasBreath { get { return DoesMultiFirebreathing; } }

        public virtual bool DoesEarthquaking { get { return false; } }
        public virtual double EarthquakingChance { get { return 0.250; } }

        public virtual bool DoesSummoning { get { return false; } }
        public virtual double SummoningChance { get { return 0.150; } }
        public virtual double SummoningLowChance { get { return 0.050; } }
        public virtual Type SummoningType { get { return null; } }
        public virtual TimeSpan SummoningDuration { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual TimeSpan SummoningDelay { get { return TimeSpan.FromMinutes( 2.0 ); } }
        public virtual int SummoningSound { get { return -1; } }
        public virtual int SummoningMin { get { return 1; } }
        public virtual int SummoningMax { get { return 1; } }

        public override void OnGotMeleeAttack( Mobile attacker )
            {
            base.OnGotMeleeAttack( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesNoxStriking && NoxStrikingChance >= Utility.RandomDouble() )
                NoxStrike( target );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        public override void OnGaveMeleeAttack( Mobile defender )
            {
            base.OnGaveMeleeAttack( defender );

            if( DoesLifeDraining && LifeDrainingChance >= Utility.RandomDouble() )
                DrainLife();

            if( DoesEarthquaking && EarthquakingChance >= Utility.RandomDouble() )
                Earthquake();
            }

        public override void OnDamagedBySpell( Mobile attacker )
            {
            base.OnDamagedBySpell( attacker );

            Mobile target = attacker;

            if( target is BaseCreature && ( (BaseCreature)target ).Controled )
                target = ( (BaseCreature)target ).ControlMaster;

            if( target == null )
                target = attacker;

            if( DoesTripleBolting && TripleBoltingChance >= Utility.RandomDouble() )
                TripleBolt( target );

            if( DoesSummoning && SummoningChance >= Utility.RandomDouble() )
                SummonMinions( target );
            }

        #region Summoning

        private DateTime m_NextSummonTime = DateTime.Now;

        public virtual int SummonMinions( Mobile victim )
            {
            int minions = 0;

            if( Map == null || Map == Map.Internal || Map != victim.Map || SummoningType == null )
                return minions;

            if( m_NextSummonTime >= DateTime.Now && Utility.RandomDouble() > SummoningLowChance )
                return minions;

            #region Cantidad de Summons
            int min = SummoningMin;
            int max = SummoningMax;

            if( min > max )
                {
                int aux = min;
                max = min;
                min = max;
                }

            int amount = min;

            if( min != max )
                amount = Utility.RandomMinMax( min, max );

            if( amount < 1 )
                amount = 1;
            #endregion

            for( int m = 0; m < amount; m++ )
                {
                BaseCreature minion;

                try { minion = (BaseCreature)Activator.CreateInstance( SummoningType ); }
                catch { continue; }

                int offset = Utility.Random( 8 ) * 2;
                Point3D selectedOffset = victim.Location;

                for( int i = 0; i < m_Offsets.Length; i += 2 )
                    {
                    int x = X + m_Offsets[( offset + i ) % m_Offsets.Length];
                    int y = Y + m_Offsets[( offset + i + 1 ) % m_Offsets.Length];

                    if( Map.CanSpawnMobile( x, y, Z ) )
                        {
                        selectedOffset = new Point3D( x, y, Z );
                        break;
                        }
                    else
                        {
                        int z = Map.GetAverageZ( x, y );

                        if( Map.CanSpawnMobile( x, y, z ) )
                            {
                            selectedOffset = new Point3D( x, y, z );
                            break;
                            }
                        }
                    }

                BaseCreature.Summon( minion, false, this, selectedOffset, SummoningSound, SummoningDuration );
                minion.Combatant = victim;
                minions++;
                }

            /* NOTA: 
             * 
             * Cada 6 minions esperamos el doble de tiempo que el pautado,
             * esto logra que no se sumonee 28 summons y se tarde lo mismo 
             * que cuando se summonean 3 de ellos. Eh lo.
             */

            m_NextSummonTime = DateTime.Now + TimeSpan.FromSeconds( SummoningDelay.TotalSeconds * ( 0.8 + ( minions * 0.2 ) ) );

            return minions;
            }

        #endregion

        #region Earthquake

        public virtual void Earthquake()
            {
            if( Map == null )
                return;

            ArrayList targets = new ArrayList();

            foreach( Mobile m in this.GetMobilesInRange( 6 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player )
                    targets.Add( m );
                }

            PlaySound( 0x2F3 );

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = (Mobile)targets[i];

                double damage = m.Hits * 0.6;

                if( damage < 10.0 )
                    damage = 10.0;
                else if( damage > 75.0 )
                    damage = 75.0;

                DoHarmful( m );

                AOS.Damage( m, this, (int)damage, 100, 0, 0, 0, 0 );

                if( m.Alive && m.Body.IsHuman && !m.Mounted )
                    m.Animate( 20, 7, 1, true, false, 0 ); // take hit
                }
            }

        #endregion

        #region Multi Breath

        public override void BreathStart( Mobile target )
            {
            base.BreathStart( target ); //tiramos un firebreath al objetivo original.

            if( !DoesMultiFirebreathing || Utility.RandomDouble() > MultiFirebreathingChance )
                return;

            ArrayList posibleTgts = new ArrayList();

            foreach( Mobile m in target.Map.GetMobilesInRange( target.Location, BreathMaxRange ) )
                if( m != null && !m.Deleted && m != target && m.Alive && !m.IsDeadBondedPet &&
                    ( m.AccessLevel < AccessLevel.Counselor || CanSee( m ) ) && CanBeHarmful( m ) &&
                    ( m.Player || ( m is BaseCreature && ( (BaseCreature)m ).Controled ) ) )
                    posibleTgts.Add( m );

            int maxTgts = BreathMaxTargets - 1; //BreathMaxTargets - 1 + el primer firebreath que va al target original.
            int mt = 0;
            int maxAtt = 3;
            int at = 0;

            for( int i = 0; i < posibleTgts.Count && mt++ < maxTgts && at++ < maxAtt; i++ )
                {
                int x = Utility.Random( posibleTgts.Count );
                Mobile t = (Mobile)posibleTgts[x];

                if( t == null || !CanBeHarmful( t ) )
                    return;

                BreathStallMovement();
                BreathPlayAngerSound();
                BreathPlayAngerAnimation();

                Direction = GetDirectionTo( t );

                Timer.DelayCall( TimeSpan.FromSeconds( BreathEffectDelay ), new TimerStateCallback( BreathEffect_Callback ), t );

                posibleTgts.RemoveAt( x );
                at = 0;
                }
            }

        public override int BreathComputeDamage()       //Que haga un toke menos de daño, 
            {                                           //si va a meter 5 firebreaths....
            int fromBase = base.BreathComputeDamage();  //Además, lo usa la Hydra que tiene 1.5Ks de hits, y el Abscess con sus 7Ks.

            if( DoesMultiFirebreathing )
                return (int)( fromBase * ( BreathDamagePercent / 10 ) );

            return fromBase;
            }

        #endregion

        #region Triple Energy Bolts

        private int Bolts = 0;

        public virtual void TripleBolt( Mobile to )
            {
            Bolts = 0;
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            Timer.DelayCall( TimeSpan.FromSeconds( Utility.Random( 3 ) ), new TimerStateCallback( Bolt_Callback ), to );
            }

        public virtual void Bolt_Callback( object state )
            {
            Mobile to = state as Mobile;

            if( to == null )
                return;

            DoHarmful( to );

            to.BoltEffect( 0 );

            int damage = Utility.RandomMinMax( 23, 29 );

            AOS.Damage( to, this, damage, 0, 0, 0, 0, 100, false );

            if( ++Bolts == 3 && damage > 0 )
                to.SendMessage( "You get shocked and dazed!" );
            }

        #endregion

        #region Teleport

        private Timer m_Timer;

        public static int[] m_Offsets = new int[]
			    {
				-1, -1,
				-1,  0,
				-1,  1,
				0, -1,
				0,  1,
				1, -1,
				1,  0,
				1,  1
			    };

        private class TeleportTimer : Timer
            {
            private BaseSpecialCreature m_Owner;

            public TeleportTimer( BaseSpecialCreature owner )
                : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
                {
                m_Owner = owner;
                }

            protected override void OnTick()
                {
                if( m_Owner.Deleted )
                    {
                    Stop();
                    return;
                    }

                if( Utility.RandomDouble() > m_Owner.TeleportingChance )
                    return;

                Map map = m_Owner.Map;

                if( map == null )
                    return;

                ArrayList toTeleport = new ArrayList();

                foreach( Mobile m in m_Owner.GetMobilesInRange(6) )
                    if( m != m_Owner && m.Player && m_Owner.CanBeHarmful( m ) && m_Owner.CanSee( m ) && m.AccessLevel < AccessLevel.Counselor )
                        toTeleport.Add( m );

                if( toTeleport.Count > 0 )
                    {
                    int offset = Utility.Random( 8 ) * 2;

                    Point3D to = m_Owner.Location;

                    for( int i = 0; i < m_Offsets.Length; i += 2 )
                        {
                        int x = m_Owner.X + BaseSpecialCreature.m_Offsets[( offset + i ) % BaseSpecialCreature.m_Offsets.Length];
                        int y = m_Owner.Y + BaseSpecialCreature.m_Offsets[( offset + i + 1 ) % BaseSpecialCreature.m_Offsets.Length];

                        if( map.CanSpawnMobile( x, y, m_Owner.Z ) )
                            {
                            to = new Point3D( x, y, m_Owner.Z );
                            break;
                            }
                        else
                            {
                            int z = map.GetAverageZ( x, y );

                            if( map.CanSpawnMobile( x, y, z ) )
                                {
                                to = new Point3D( x, y, z );
                                break;
                                }
                            }
                        }

                    Mobile m = (Mobile)toTeleport[Utility.Random( toTeleport.Count )];

                    Point3D from = m.Location;

                    m.Location = to;

                    SpellHelper.Turn( m_Owner, m );
                    SpellHelper.Turn( m, m_Owner );

                    m.ProcessDelta();

                    Effects.SendLocationParticles( EffectItem.Create( from, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
                    Effects.SendLocationParticles( EffectItem.Create( to, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );

                    m.PlaySound( 0x1FE );

                    m_Owner.Combatant = m;
                    }
                }
            }

        #endregion

        #region NoxStrike

        public virtual void NoxStrike( Mobile attacker )
            {
            /* Counterattack with Hit Poison Area
             * 20-25 damage, unresistable
             * Lethal poison, 100% of the time
             * Particle effect: Type: "2" From: "0x4061A107" To: "0x0" ItemId: "0x36BD" ItemIdName: "explosion" FromLocation: "(296 615, 17)" ToLocation: "(296 615, 17)" Speed: "1" Duration: "10" FixedDirection: "True" Explode: "False" Hue: "0xA6" RenderMode: "0x0" Effect: "0x1F78" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x4061A107" Layer: "255" Unknown: "0x0"
             * Doesn't work on provoked monsters
             */

            if( attacker is BaseCreature && ( (BaseCreature)attacker ).BardProvoked )
                return;

            Mobile target = null;

            if( attacker is BaseCreature )
                {
                Mobile m = ( (BaseCreature)attacker ).GetMaster();

                if( m != null )
                    target = m;
                }

            if( target == null || !target.InRange( this, 18 ) )
                target = attacker;

            this.Animate( 10, 4, 1, true, false, 0 );

            ArrayList targets = new ArrayList();

            foreach( Mobile m in target.GetMobilesInRange( 8 ) )
                {
                if( m == this || !CanBeHarmful( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != this.Team ) )
                    targets.Add( m );
                else if( m.Player && m.Alive )
                    targets.Add( m );
                }

            for( int i = 0; i < targets.Count; ++i )
                {
                Mobile m = (Mobile)targets[i];

                DoHarmful( m );

                AOS.Damage( m, this, Utility.RandomMinMax( 20, 25 ), 0, 0, 0, 100, 0, true );

                m.FixedParticles( 0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255 );
                m.ApplyPoison( this, Poison.Lethal );
                }
            }

        #endregion

        #region DrainLife

        public virtual void DrainLife()
            {
            ArrayList ArrayList = new ArrayList();

            foreach( Mobile m in GetMobilesInRange(3) )
                {
                if( m == this || !CanBeHarmful( m ) || !CanSee( m ) || m.AccessLevel >= AccessLevel.Counselor )
                    continue;

                if( m is BaseCreature && ( ( (BaseCreature)m ).Controled || ( (BaseCreature)m ).Summoned || ( (BaseCreature)m ).Team != Team ) )
                    ArrayList.Add( m );
                else if( m.Player )
                    ArrayList.Add( m );
                }

            foreach( Mobile m in ArrayList )
                {
                DoHarmful( m );

                m.FixedParticles( 0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist );
                m.PlaySound( 0x231 );

                m.SendMessage( "You feel the life drain out of you!" );

                int toDrain = Utility.RandomMinMax( 10, 40 );

                Hits += toDrain;
                m.Damage( toDrain, this );
                }
            }

        #endregion

        public BaseSpecialCreature( AIType ai, FightMode mode, int iRangePerception, int iRangeFight, double dActiveSpeed, double dPassiveSpeed )
            : base( ai, mode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public BaseSpecialCreature( Serial serial )
            : base( serial )
            {
            if( DoesTeleporting )
                {
                m_Timer = new TeleportTimer( this );
                m_Timer.Start();
                }
            }

        public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); }
        public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); }
        }
    }
 

Deiscianna

Wanderer
Great Script

Love this BaseSpecialCreature, this will give our shard some needed and great upgrades to creatures, thanks so much :)
 

spikeSOK

Wanderer
Having a little trouble with the message part of it. Uing your dreadhorn from the first post, i get this message.
Code:
RunUO - [www.runuo.com] Version 2.0, Build 2357.32527
Core: Running on .NET Framework Version 2.0.50727
Scripts: Compiling C# scripts...failed (1 errors, 0 warnings)
Errors:
 + Custom/FSSCustoms/ML/Mobiles/Dread Horn.cs:
    CS0103: Line 64: The name 'MessageType' does not exist in the current contex
t
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.

here is the script
Code:
using System;
using Server;
using Server.Items;

namespace Server.Mobiles
{
	[CorpseName( "a dread horn corpse" )]
	
	public class DreadHorn : BaseSpecialCreature
	{
		
		[Constructable]
		public DreadHorn() : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			Name = "a Dread Horn";
			Body = 257;
			BaseSoundID = 0xA8;

			SetStr( 1281, 1305 );
			SetDex( 591, 815 );
			SetInt( 1226, 1250 );

			SetHits( 169, 183 );
			SetStam( 636, 945 );

			SetDamage( 120, 170 );

			SetDamageType( ResistanceType.Physical, 100 );

			SetResistance( ResistanceType.Physical, 70, 82 );
			SetResistance( ResistanceType.Fire, 70, 82 );
			SetResistance( ResistanceType.Cold, 70, 82 );
			SetResistance( ResistanceType.Poison, 70, 82 );
			SetResistance( ResistanceType.Energy, 70, 82 );

			SetSkill( SkillName.EvalInt, 155.1, 200.0 );
			SetSkill( SkillName.Magery, 155.1, 200.0 );
			SetSkill( SkillName.MagicResist, 155.1, 200.0 );
			SetSkill( SkillName.Tactics, 155.1, 200.0 );
			SetSkill( SkillName.Wrestling, 155.1, 200.0 );

			Fame = 11500;
			Karma = -11500;

			VirtualArmor = 75;
			
		}

		public override void GenerateLoot()
		{
			AddLoot( LootPack.AosUltraRich );
			AddLoot( LootPack.AosSuperBoss );
		}

		public override bool AutoDispel{ get{ return true; } }
		public override bool BardImmune{ get{ return true; } }
		public override bool CanRummageCorpses{ get{ return true; } }                
		public override Poison PoisonImmune{ get{ return Poison.Lethal; } }		
		public override Poison HitPoison{ get{ return (0.8 >= Utility.RandomDouble() ? Poison.Greater : Poison.Deadly); } }
                public override bool DoesTeleporting  { get { return true; } }
                public override bool DoesEarthquaking { get { return true; } }
                public override void Earthquake()
            {
            PublicOverheadMessage( MessageType.Emote, 0x723, 1075081 ); //*Dreadhorn’s eyes light up, his mouth almost a             grin, as he slams one hoof to the ground!*
            base.Earthquake();
            }

		public DreadHorn( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 0 );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();
		}
	}
}

prolly missing something simple, thanks in advance for any help
 

Hazey

Wanderer
I would love to give you a list of all sorts of special attacks and how they would look ingame if your all ears.. this concept is very nice +Karma to you
 

koluch

Sorceror
Minor Issue:

When a player is dead and well out of range, they still get bolted.
I know there should be some type of check if the player is dead/cant be harmful/access level over Player/etc.
Suggestions on the proper coding to implement this?

Code:
[SIZE=2][COLOR=#008000]#[B]region [/B]Triple Energy Bolts
[/COLOR][/SIZE][B][SIZE=2][COLOR=#0000ff]private [/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]int [/B][/COLOR][/SIZE][SIZE=2][COLOR=#000000]Bolts [/COLOR][/SIZE][SIZE=2][COLOR=#006400]= [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0[/COLOR][/SIZE][SIZE=2][COLOR=#006400];
[/COLOR][/SIZE][B][SIZE=2][COLOR=#0000ff]public [/B][/COLOR][/SIZE][SIZE=2][COLOR=#a52a2a]virtual [/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]void [/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]TripleBolt[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Mobile to [/COLOR][/SIZE][SIZE=2][COLOR=#006400])
{
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]Bolts [/COLOR][/SIZE][SIZE=2][COLOR=#006400]= [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0[/COLOR][/SIZE][SIZE=2][COLOR=#006400];
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]Timer[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]DelayCall[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]TimeSpan[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]FromSeconds[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Utility[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]Random[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]3 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]) ), [/COLOR][/SIZE][B][SIZE=2][COLOR=#008b8b]new [/COLOR][/SIZE][SIZE=2][COLOR=#191970]TimerStateCallback[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Bolt_Callback [/COLOR][/SIZE][SIZE=2][COLOR=#006400]), [/COLOR][/SIZE][SIZE=2][COLOR=#000000]to [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]Timer[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]DelayCall[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]TimeSpan[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]FromSeconds[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Utility[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]Random[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]3 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]) ), [/COLOR][/SIZE][B][SIZE=2][COLOR=#008b8b]new [/COLOR][/SIZE][SIZE=2][COLOR=#191970]TimerStateCallback[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Bolt_Callback [/COLOR][/SIZE][SIZE=2][COLOR=#006400]), [/COLOR][/SIZE][SIZE=2][COLOR=#000000]to [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]Timer[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]DelayCall[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]TimeSpan[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]FromSeconds[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Utility[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]Random[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]3 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]) ), [/COLOR][/SIZE][B][SIZE=2][COLOR=#008b8b]new [/COLOR][/SIZE][SIZE=2][COLOR=#191970]TimerStateCallback[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Bolt_Callback [/COLOR][/SIZE][SIZE=2][COLOR=#006400]), [/COLOR][/SIZE][SIZE=2][COLOR=#000000]to [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
}
[/COLOR][/SIZE][B][SIZE=2][COLOR=#0000ff]public [/B][/COLOR][/SIZE][SIZE=2][COLOR=#a52a2a]virtual [/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]void [/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]Bolt_Callback[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]object [/COLOR][/SIZE][SIZE=2][COLOR=#000000]state [/COLOR][/SIZE][SIZE=2][COLOR=#006400])
{
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]Mobile to [/COLOR][/SIZE][SIZE=2][COLOR=#006400]= [/COLOR][/SIZE][SIZE=2][COLOR=#000000]state [/COLOR][/SIZE][B][SIZE=2][COLOR=#008b8b]as [/B][/COLOR][/SIZE][SIZE=2][COLOR=#000000]Mobile[/COLOR][/SIZE][SIZE=2][COLOR=#006400];
[/COLOR][/SIZE][SIZE=2][/SIZE][B][SIZE=2][COLOR=#0000ff]if[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]to [/COLOR][/SIZE][SIZE=2][COLOR=#006400]== [/COLOR][/SIZE][B][SIZE=2][COLOR=#000000]null [/COLOR][/B][/SIZE][SIZE=2][COLOR=#006400])
[/COLOR][/SIZE][SIZE=2][COLOR=#000080]return[/COLOR][/SIZE][SIZE=2][COLOR=#006400];
[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]DoHarmful[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]to [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]to[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]BoltEffect[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
[/COLOR][/SIZE][B][SIZE=2][COLOR=#ff0000]int [/B][/COLOR][/SIZE][SIZE=2][COLOR=#000000]damage [/COLOR][/SIZE][SIZE=2][COLOR=#006400]= [/COLOR][/SIZE][SIZE=2][COLOR=#000000]Utility[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]RandomMinMax[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]15[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]29 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);[/COLOR][/SIZE][SIZE=2][COLOR=#008000]//was 23-29
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]AOS[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]Damage[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#000000]to[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][B][SIZE=2][COLOR=#000000]this[/COLOR][/B][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#000000]damage[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][B][SIZE=2][COLOR=#008b8b]false[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0[/COLOR][/SIZE][SIZE=2][COLOR=#006400], [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]100 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
[/COLOR][/SIZE][B][SIZE=2][COLOR=#0000ff]if[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( ++[/COLOR][/SIZE][SIZE=2][COLOR=#000000]Bolts [/COLOR][/SIZE][SIZE=2][COLOR=#006400]== [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]3 [/COLOR][/SIZE][SIZE=2][COLOR=#006400]&& [/COLOR][/SIZE][SIZE=2][COLOR=#000000]damage [/COLOR][/SIZE][SIZE=2][COLOR=#006400]> [/COLOR][/SIZE][SIZE=2][COLOR=#00008b]0 [/COLOR][/SIZE][SIZE=2][COLOR=#006400])
[/COLOR][/SIZE][SIZE=2][COLOR=#000000]to[/COLOR][/SIZE][SIZE=2][COLOR=#006400].[/COLOR][/SIZE][B][SIZE=2][COLOR=#191970]SendMessage[/B][/COLOR][/SIZE][SIZE=2][COLOR=#006400]( [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]"You get shocked and dazed!" [/COLOR][/SIZE][SIZE=2][COLOR=#006400]);
}
[/COLOR][/SIZE][SIZE=2][COLOR=#008000]#[B]endregion[/B][/COLOR][/SIZE]
[SIZE=2][COLOR=#008000][B]
[/B][/COLOR][/SIZE]
Mobile to = state as Mobile;
if(to == null)
return;

Something along the line of:

Mobile to = state as Mobile;
if ( to == null || to == this || !CanBeHarmful( to) || !CanSee( to) || to.AccessLevel >= AccessLevel.Counselor )

with a

continue;

or

return;

LOVE the basespecialcreature, but would like to get this one minor thing corrected.

Thanks for the suggestions!

Koluch:)
 
That fatal bleed sounds cool lol I would imagine it being a bleed attack that cannot be healed and lasts until you die thus you would slowly bleed to death. You would need to lower the amount of damage though so that it doesn't just bleed a player right out maybe make it hit for 3 to 5 damage once every 15 seconds or so?
 

michal555

Wanderer
LordHogFred;600538 said:
Very nice,
Might I suggest adding a customisable aura effect to it?
Such as the cold effect or burning effect that would allow min/max damage and damage type to be configured.
Also perhaps adding a HealSelf property that would toggle the creature to use bandages, maybe thats a little more complex but just an idea :).
Anyway, very cool script :D
aura sounds cool ;] like poison - but cold/energy/fire dmg ;]
 

Tru

Knight
This is a nice script especially combined with the "Monster Features AI Extension" they both add that little something extra for creatures you dont really know anymore.
 
Tru;726607 said:
This is a nice script especially combined with the "Monster Features AI Extension" they both add that little something extra for creatures you dont really know anymore.

Got a link to the "Monster Features AI Extension" I did a search and found nothing :(
 
Top