\\Scripts\Items\SkillItems\Magical\DruidicSpellbook.cs
[code:1]
using System;
using Server.Network;
using Server.Gumps;
using Server.Spells;
namespace Server.Items
{
public class DruidicSpellbook : Spellbook
{
public override SpellbookType SpellbookType{ get{ return SpellbookType.Druidic; } }
public override int BookOffset{ get{ return 300; } }
public override int BookCount{ get{ return 16; } }
public override Item Dupe( int amount )
{
Spellbook book = new DruidicSpellbook();
book.Content = this.Content;
return base.Dupe( book, amount );
}
[Constructable]
public DruidicSpellbook() : this( (ulong)0 )
{
}
[Constructable]
public DruidicSpellbook( ulong content ) : base( content, 0xEFA )
{
Hue = 0x48C;
Name = "Tome of Nature";
}
public override void OnDoubleClick( Mobile from )
{
if ( from.InRange( GetWorldLocation(), 1 ) )
{
from.CloseGump( typeof( DruidicSpellbookGump ) );
from.SendGump( new DruidicSpellbookGump( from, this ) );
}
}
public DruidicSpellbook( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magical\Spellbook.cs
[code:1]
using System;
using System.Collections;
using Server.Network;
using Server.Spells;
namespace Server.Items
{
public enum SpellbookType
{
Invalid = -1,
Regular,
Necromancer,
Paladin,
Druidic
}
public class Spellbook : Item
{
public static void Initialize()
{
EventSink.OpenSpellbookRequest += new OpenSpellbookRequestEventHandler( EventSink_OpenSpellbookRequest );
EventSink.CastSpellRequest += new CastSpellRequestEventHandler( EventSink_CastSpellRequest );
}
private static void EventSink_OpenSpellbookRequest( OpenSpellbookRequestEventArgs e )
{
Mobile from = e.Mobile;
if ( !Multis.DesignContext.Check( from ) )
return; // They are customizing
SpellbookType type;
switch ( e.Type )
{
default:
case 1: type = SpellbookType.Regular; break;
case 2: type = SpellbookType.Necromancer; break;
case 3: type = SpellbookType.Paladin; break;
case 4: type = SpellbookType.Druidic; break;
}
Spellbook book = Spellbook.Find( from, -1, type );
if ( book != null )
book.DisplayTo( from );
}
private static void EventSink_CastSpellRequest( CastSpellRequestEventArgs e )
{
Mobile from = e.Mobile;
if ( !Multis.DesignContext.Check( from ) )
return; // They are customizing
Spellbook book = e.Spellbook as Spellbook;
int spellID = e.SpellID;
if ( book == null || !book.HasSpell( spellID ) )
book = Find( from, spellID );
if ( book != null && book.HasSpell( spellID ) )
{
Spell spell = SpellRegistry.NewSpell( spellID, from, null );
if ( spell != null )
spell.Cast();
else
from.SendLocalizedMessage( 502345 ); // This spell has been temporarily disabled.
}
else
{
from.SendLocalizedMessage( 500015 ); // You do not have that spell!
}
}
private static Hashtable m_Table = new Hashtable();
public static SpellbookType GetTypeForSpell( int spellID )
{
if ( spellID >= 0 && spellID < 64 )
return SpellbookType.Regular;
else if ( spellID >= 100 && spellID < 116 )
return SpellbookType.Necromancer;
else if ( spellID >= 200 && spellID < 210 )
return SpellbookType.Paladin;
else if ( spellID >= 300 && spellID < 316 )
return SpellbookType.Druidic;
return SpellbookType.Invalid;
}
public static Spellbook FindRegular( Mobile from )
{
return Find( from, -1, SpellbookType.Regular );
}
public static Spellbook FindNecromancer( Mobile from )
{
return Find( from, -1, SpellbookType.Necromancer );
}
public static Spellbook FindPaladin( Mobile from )
{
return Find( from, -1, SpellbookType.Paladin );
}
public static Spellbook FindDruidic( Mobile from )
{
return Find( from, -1, SpellbookType.Druidic );
}
public static Spellbook Find( Mobile from, int spellID )
{
return Find( from, spellID, GetTypeForSpell( spellID ) );
}
public static Spellbook Find( Mobile from, int spellID, SpellbookType type )
{
if ( from == null )
return null;
ArrayList list = (ArrayList)m_Table[from];
if ( from.Deleted )
{
m_Table.Remove( from );
return null;
}
bool searchAgain = false;
if ( list == null )
m_Table[from] = list = FindAllSpellbooks( from );
else
searchAgain = true;
Spellbook book = FindSpellbookInList( list, from, spellID, type );
if ( book == null && searchAgain )
{
m_Table[from] = list = FindAllSpellbooks( from );
book = FindSpellbookInList( list, from, spellID, type );
}
return book;
}
public static Spellbook FindSpellbookInList( ArrayList list, Mobile from, int spellID, SpellbookType type )
{
Container pack = from.Backpack;
for ( int i = list.Count - 1; i >= 0; --i )
{
if ( i >= list.Count )
continue;
Spellbook book = (Spellbook)list;
if ( !book.Deleted && (book.Parent == from || (pack != null && book.Parent == pack)) && ValidateSpellbook( book, spellID, type ) )
return book;
list.Remove( i );
}
return null;
}
public static ArrayList FindAllSpellbooks( Mobile from )
{
ArrayList list = new ArrayList();
Item item = from.FindItemOnLayer( Layer.OneHanded );
if ( item is Spellbook )
list.Add( item );
Container pack = from.Backpack;
if ( pack == null )
return list;
for ( int i = 0; i < pack.Items.Count; ++i )
{
item = (Item)pack.Items;
if ( item is Spellbook )
list.Add( item );
}
return list;
}
public static bool ValidateSpellbook( Spellbook book, int spellID, SpellbookType type )
{
return ( book.SpellbookType == type && ( spellID == -1 || book.HasSpell( spellID ) ) );
}
public virtual SpellbookType SpellbookType{ get{ return SpellbookType.Regular; } }
public virtual int BookOffset{ get{ return 0; } }
public virtual int BookCount{ get{ return 64; } }
private ulong m_Content;
private int m_Count;
public override bool AllowEquipedCast( Mobile from )
{
return true;
}
public override Item Dupe( int amount )
{
Spellbook book = new Spellbook();
book.Content = this.Content;
return base.Dupe( book, amount );
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if ( dropped is SpellScroll && dropped.Amount == 1 )
{
SpellScroll scroll = (SpellScroll)dropped;
SpellbookType type = GetTypeForSpell( scroll.SpellID );
if ( type != this.SpellbookType )
{
return false;
}
else if ( HasSpell( scroll.SpellID ) )
{
from.SendLocalizedMessage( 500179 ); // That spell is already present in that spellbook.
return false;
}
else
{
int val = scroll.SpellID - BookOffset;
if ( val >= 0 && val < BookCount )
{
m_Content |= (ulong)1 << val;
++m_Count;
InvalidateProperties();
scroll.Delete();
from.Send( new PlaySound( 0x249, GetWorldLocation() ) );
return true;
}
return false;
}
}
else
{
return false;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public ulong Content
{
get
{
return m_Content;
}
set
{
if ( m_Content != value )
{
m_Content = value;
m_Count = 0;
while ( value > 0 )
{
m_Count += (int)(value & 0x1);
value >>= 1;
}
InvalidateProperties();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int SpellCount
{
get
{
return m_Count;
}
}
[Constructable]
public Spellbook() : this( (ulong)0 )
{
}
[Constructable]
public Spellbook( ulong content ) : this( content, 0xEFA )
{
}
public Spellbook( ulong content, int itemID ) : base( itemID )
{
Weight = 3.0;
Layer = Layer.OneHanded;
LootType = LootType.Blessed;
Content = content;
}
public bool HasSpell( int spellID )
{
spellID -= BookOffset;
return ( spellID >= 0 && spellID < BookCount && (m_Content & ((ulong)1 << spellID)) != 0 );
}
public Spellbook( Serial serial ) : base( serial )
{
}
private static readonly ClientVersion Version_400a = new ClientVersion( "4.0.0a" );
public void DisplayTo( Mobile to )
{
// The client must know about the spellbook or it will crash!
if ( Parent == null )
{
to.Send( this.WorldPacket );
}
else if ( Parent is Item )
{
// What will happen if the client doesn't know about our parent?
to.Send( new ContainerContentUpdate( this ) );
}
else if ( Parent is Mobile )
{
// What will happen if the client doesn't know about our parent?
to.Send( new EquipUpdate( this ) );
}
to.Send( new DisplaySpellbook( this ) );
if ( Core.AOS && to.NetState != null && to.NetState.Version != null && to.NetState.Version >= Version_400a )
to.Send( new NewSpellbookContent( this, ItemID, BookOffset + 1, m_Content ) );
else
to.Send( new SpellbookContent( m_Count, BookOffset + 1, m_Content, this ) );
}
public override bool DisplayLootType{ get{ return false; } }
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1042886, m_Count.ToString() ); // ~1_NUMBERS_OF_SPELLS~ Spells
}
public override void OnSingleClick( Mobile from )
{
base.OnSingleClick( from );
this.LabelTo( from, 1042886, m_Count.ToString() );
}
public override void OnDoubleClick( Mobile from )
{
Container pack = from.Backpack;
if ( Parent == from || ( pack != null && Parent == pack ) )
DisplayTo( from );
else
from.SendLocalizedMessage( 500207 ); // The spellbook must be in your backpack (and not in a container within) to open.
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Content );
writer.Write( m_Count );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
LootType = LootType.Blessed;
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Content = reader.ReadULong();
m_Count = reader.ReadInt();
break;
}
}
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\BlendWithForestScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class BlendWithForestScroll : SpellScroll
{
[Constructable]
public BlendWithForestScroll() : this( 1 )
{
}
[Constructable]
public BlendWithForestScroll( int amount ) : base( 306, 0x136C )
{
Name = "Blend With Forest";
Hue = 0x58B;
}
public BlendWithForestScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new BlendWithForestScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\GraspingRootsScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class GraspingRootsScroll : SpellScroll
{
[Constructable]
public GraspingRootsScroll() : this( 1 )
{
}
[Constructable]
public GraspingRootsScroll( int amount ) : base( 305, 0x136C )
{
Name = "Hollow Reed";
Hue = 0x58B;
}
public GraspingRootsScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new GraspingRootsScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\HollowReedScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class HollowReedScroll : SpellScroll
{
[Constructable]
public HollowReedScroll() : this( 1 )
{
}
[Constructable]
public HollowReedScroll( int amount ) : base( 302, 0x136C )
{
Name = "Hollow Reed";
Hue = 0x58B;
}
public HollowReedScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new HollowReedScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\PackOfBeastScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class PackOfBeastScroll : SpellScroll
{
[Constructable]
public PackOfBeastScroll() : this( 1 )
{
}
[Constructable]
public PackOfBeastScroll( int amount ) : base( 303, 0x136C )
{
Name = "Pack Of Beast";
Hue = 0x58B;
}
public PackOfBeastScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new PackOfBeastScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\SheildOfEarthScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SheildOfEarthScroll : SpellScroll
{
[Constructable]
public SheildOfEarthScroll() : this( 1 )
{
}
[Constructable]
public SheildOfEarthScroll( int amount ) : base( 301, 0x136C )
{
Name = "Sheild Of Earth";
Hue = 0x58B;
}
public SheildOfEarthScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new SheildOfEarthScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\SpringOFLifeScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SpringOfLifeScroll : SpellScroll
{
[Constructable]
public SpringOfLifeScroll() : this( 1 )
{
}
[Constructable]
public SpringOfLifeScroll( int amount ) : base( 304, 0x136C )
{
Name = "Spring Of Life";
Hue = 0x58B;
}
public SpringOfLifeScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new SpringOfLifeScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\SwarmOfInsectsScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SwarmOfInsectsScroll : SpellScroll
{
[Constructable]
public SwarmOfInsectsScroll() : this( 1 )
{
}
[Constructable]
public SwarmOfInsectsScroll( int amount ) : base( 307, 0x136C )
{
Name = "Swarm Of Insects";
Hue = 0x58B;
}
public SwarmOfInsectsScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new SwarmOfInsectsScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Items\SkillItems\Magica\Scrolls\Druid\VolcanicEruptionScroll.cs
[code:1]
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class VolcanicEruptionScroll : SpellScroll
{
[Constructable]
public VolcanicEruptionScroll() : this( 1 )
{
}
[Constructable]
public VolcanicEruptionScroll( int amount ) : base( 308, 0x136C )
{
Name = "Volcanic Eruption";
Hue = 0x58B;
}
public VolcanicEruptionScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override Item Dupe( int amount )
{
return base.Dupe( new VolcanicEruptionScroll( amount ), amount );
}
}
}
[/code:1]
\\Scripts\Spells\Initializer.cs
[code:1]
using System;
using Server;
namespace Server.Spells
{
public class Initializer
{
public static void Initialize()
{
// Regular spells
// First circle
Register( 00, typeof( First.ClumsySpell ) );
Register( 01, typeof( First.CreateFoodSpell ) );
Register( 02, typeof( First.FeeblemindSpell ) );
Register( 03, typeof( First.HealSpell ) );
Register( 04, typeof( First.MagicArrowSpell ) );
Register( 05, typeof( First.NightSightSpell ) );
Register( 06, typeof( First.ReactiveArmorSpell ) );
Register( 07, typeof( First.WeakenSpell ) );
// Second circle
Register( 08, typeof( Second.AgilitySpell ) );
Register( 09, typeof( Second.CunningSpell ) );
Register( 10, typeof( Second.CureSpell ) );
Register( 11, typeof( Second.HarmSpell ) );
Register( 12, typeof( Second.MagicTrapSpell ) );
Register( 13, typeof( Second.RemoveTrapSpell ) );
Register( 14, typeof( Second.ProtectionSpell ) );
Register( 15, typeof( Second.StrengthSpell ) );
// Third circle
Register( 16, typeof( Third.BlessSpell ) );
Register( 17, typeof( Third.FireballSpell ) );
Register( 18, typeof( Third.MagicLockSpell ) );
Register( 19, typeof( Third.PoisonSpell ) );
Register( 20, typeof( Third.TelekinesisSpell ) );
Register( 21, typeof( Third.TeleportSpell ) );
Register( 22, typeof( Third.UnlockSpell ) );
Register( 23, typeof( Third.WallOfStoneSpell ) );
// Fourth circle
Register( 24, typeof( Fourth.ArchCureSpell ) );
Register( 25, typeof( Fourth.ArchProtectionSpell ) );
Register( 26, typeof( Fourth.CurseSpell ) );
Register( 27, typeof( Fourth.FireFieldSpell ) );
Register( 28, typeof( Fourth.GreaterHealSpell ) );
Register( 29, typeof( Fourth.LightningSpell ) );
Register( 30, typeof( Fourth.ManaDrainSpell ) );
Register( 31, typeof( Fourth.RecallSpell ) );
// Fifth circle
Register( 32, typeof( Fifth.BladeSpiritsSpell ) );
Register( 33, typeof( Fifth.DispelFieldSpell ) );
Register( 34, typeof( Fifth.IncognitoSpell ) );
Register( 35, typeof( Fifth.MagicReflectSpell ) );
Register( 36, typeof( Fifth.MindBlastSpell ) );
Register( 37, typeof( Fifth.ParalyzeSpell ) );
Register( 38, typeof( Fifth.PoisonFieldSpell ) );
Register( 39, typeof( Fifth.SummonCreatureSpell ) );
// Sixth circle
Register( 40, typeof( Sixth.DispelSpell ) );
Register( 41, typeof( Sixth.EnergyBoltSpell ) );
Register( 42, typeof( Sixth.ExplosionSpell ) );
Register( 43, typeof( Sixth.InvisibilitySpell ) );
Register( 44, typeof( Sixth.MarkSpell ) );
Register( 45, typeof( Sixth.MassCurseSpell ) );
Register( 46, typeof( Sixth.ParalyzeFieldSpell ) );
Register( 47, typeof( Sixth.RevealSpell ) );
// Seventh circle
Register( 48, typeof( Seventh.ChainLightningSpell ) );
Register( 49, typeof( Seventh.EnergyFieldSpell ) );
Register( 50, typeof( Seventh.FlameStrikeSpell ) );
Register( 51, typeof( Seventh.GateTravelSpell ) );
Register( 52, typeof( Seventh.ManaVampireSpell ) );
Register( 53, typeof( Seventh.MassDispelSpell ) );
Register( 54, typeof( Seventh.MeteorSwarmSpell ) );
Register( 55, typeof( Seventh.PolymorphSpell ) );
// Eighth circle
Register( 56, typeof( Eighth.EarthquakeSpell ) );
Register( 57, typeof( Eighth.EnergyVortexSpell ) );
Register( 58, typeof( Eighth.ResurrectionSpell ) );
Register( 59, typeof( Eighth.AirElementalSpell ) );
Register( 60, typeof( Eighth.SummonDaemonSpell ) );
Register( 61, typeof( Eighth.EarthElementalSpell ) );
Register( 62, typeof( Eighth.FireElementalSpell ) );
Register( 63, typeof( Eighth.WaterElementalSpell ) );
// Druid Spells
Register( 301, typeof( Druid.SheildOfEarthSpell ) );
Register( 302, typeof( Druid.HollowReedSpell ) );
Register( 303, typeof( Druid.PackOfBeastSpell ) );
Register( 304, typeof( Druid.SpringOfLifeSpell ) );
Register( 305, typeof( Druid.GraspingRootsSpell ) );
Register( 306, typeof( Druid.BlendWithForestSpell ) );
Register( 307, typeof( Druid.SwarmOfInsectsSpell ) );
Register( 308, typeof( Druid.VolcanicEruptionSpell ) );
if ( Core.AOS )
{
// Necromancy spells
Register( 101, typeof( Necromancy.BloodOathSpell ) );
Register( 102, typeof( Necromancy.CorpseSkinSpell ) );
Register( 103, typeof( Necromancy.CurseWeaponSpell ) );
Register( 104, typeof( Necromancy.EvilOmenSpell ) );
Register( 105, typeof( Necromancy.HorrificBeastSpell ) );
Register( 106, typeof( Necromancy.LichFormSpell ) );
Register( 107, typeof( Necromancy.MindRotSpell ) );
Register( 108, typeof( Necromancy.PainSpikeSpell ) );
Register( 109, typeof( Necromancy.PoisonStrikeSpell ) );
Register( 110, typeof( Necromancy.StrangleSpell ) );
Register( 111, typeof( Necromancy.SummonFamiliarSpell ) );
Register( 112, typeof( Necromancy.VampiricEmbraceSpell ) );
Register( 113, typeof( Necromancy.VengefulSpiritSpell ) );
Register( 114, typeof( Necromancy.WitherSpell ) );
Register( 115, typeof( Necromancy.WraithFormSpell ) );
// Paladin abilities
Register( 200, typeof( Chivalry.CleanseByFireSpell ) );
Register( 201, typeof( Chivalry.CloseWoundsSpell ) );
Register( 202, typeof( Chivalry.ConsecrateWeaponSpell ) );
Register( 206, typeof( Chivalry.HolyLightSpell ) );
Register( 207, typeof( Chivalry.NobleSacrificeSpell ) );
}
}
public static void Register( int spellID, Type type )
{
SpellRegistry.Register( spellID, type );
}
}
}
[/code:1]
\\Scripts\Spells\Reagents.cs
[code:1]
using System;
using Server.Items;
namespace Server.Spells
{
public class Reagent
{
private static Type[] m_Types = new Type[16]
{
typeof( BlackPearl ),
typeof( Bloodmoss ),
typeof( Garlic ),
typeof( Ginseng ),
typeof( MandrakeRoot ),
typeof( Nightshade ),
typeof( SulfurousAsh ),
typeof( SpidersSilk ),
typeof( BatWing ),
typeof( GraveDust ),
typeof( DaemonBlood ),
typeof( NoxCrystal ),
typeof( PigIron ),
typeof( SpringWater ),
typeof( DestroyingAngel ),
typeof( PetrafiedWood )
};
public Type[] Types
{
get{ return m_Types; }
}
public static Type BlackPearl
{
get{ return m_Types[0]; }
set{ m_Types[0] = value; }
}
public static Type Bloodmoss
{
get{ return m_Types[1]; }
set{ m_Types[1] = value; }
}
public static Type Garlic
{
get{ return m_Types[2]; }
set{ m_Types[2] = value; }
}
public static Type Ginseng
{
get{ return m_Types[3]; }
set{ m_Types[3] = value; }
}
public static Type MandrakeRoot
{
get{ return m_Types[4]; }
set{ m_Types[4] = value; }
}
public static Type Nightshade
{
get{ return m_Types[5]; }
set{ m_Types[5] = value; }
}
public static Type SulfurousAsh
{
get{ return m_Types[6]; }
set{ m_Types[6] = value; }
}
public static Type SpidersSilk
{
get{ return m_Types[7]; }
set{ m_Types[7] = value; }
}
public static Type BatWing
{
get{ return m_Types[8]; }
set{ m_Types[8] = value; }
}
public static Type GraveDust
{
get{ return m_Types[9]; }
set{ m_Types[9] = value; }
}
public static Type DaemonBlood
{
get{ return m_Types[10]; }
set{ m_Types[10] = value; }
}
public static Type NoxCrystal
{
get{ return m_Types[11]; }
set{ m_Types[11] = value; }
}
public static Type PigIron
{
get{ return m_Types[12]; }
set{ m_Types[12] = value; }
}
public static Type SpringWater
{
get{ return m_Types[13]; }
set{ m_Types[13] = value; }
}
public static Type DestroyingAngel
{
get{ return m_Types[14]; }
set{ m_Types[14] = value; }
}
public static Type PetrafiedWood
{
get{ return m_Types[15]; }
set{ m_Types[15] = value; }
}
}
}
[/code:1]
\\Scripts\Base\SpellRegistry.cs
[code:1]
using System;
namespace Server.Spells
{
public class SpellRegistry
{
private static Type[] m_Types = new Type[400];
private static int m_Count;
public static Type[] Types
{
get
{
m_Count = -1;
return m_Types;
}
}
public static int Count
{
get
{
if ( m_Count == -1 )
{
m_Count = 0;
for ( int i = 0; i < 64; ++i )
{
if ( m_Types != null )
++m_Count;
}
}
return m_Count;
}
}
public static void Register( int spellID, Type type )
{
if ( spellID < 0 || spellID >= m_Types.Length )
return;
if ( m_Types[spellID] == null )
++m_Count;
m_Types[spellID] = type;
}
private static object[] m_Params = new object[2];
public static Spell NewSpell( int spellID, Mobile caster, Item scroll )
{
if ( spellID < 0 || spellID >= m_Types.Length )
return null;
Type t = m_Types[spellID];
if ( t == null )
return null;
m_Params[0] = caster;
m_Params[1] = scroll;
return (Spell)Activator.CreateInstance( t, m_Params );
}
private static string[] m_CircleNames = new string[]
{
"First",
"Second",
"Third",
"Fourth",
"Fifth",
"Sixth",
"Seventh",
"Eighth",
"Necromancy",
"Druid"
};
public static Spell NewSpell( string name, Mobile caster, Item scroll )
{
for ( int i = 0; i < m_CircleNames.Length; ++i )
{
Type t = ScriptCompiler.FindTypeByFullName( String.Format( "Server.Spells.{0}.{1}", m_CircleNames, name ) );
if ( t != null )
{
m_Params[0] = caster;
m_Params[1] = scroll;
return (Spell)Activator.CreateInstance( t, m_Params );
}
}
return null;
}
}
}
[/code:1]
\\Scrips\Spells\Druid\DruidicSpell.cs
[code:1]
using System;
using Server;
namespace Server.Spells.Druid
{
public abstract class DruidicSpell : Spell
{
public abstract double CastDelay{ get; }
public abstract double RequiredSkill{ get; }
public abstract int RequiredMana{ get; }
public override SkillName CastSkill{ get{ return SkillName.AnimalLore; } }
public override SkillName DamageSkill{ get{ return SkillName.AnimalTaming; } }
public override bool ClearHandsOnCast{ get{ return false; } }
public DruidicSpell( Mobile caster, Item scroll, SpellInfo info ) : base( caster, scroll, info )
{
}
public override void GetCastSkills( out double min, out double max )
{
min = RequiredSkill;
max = RequiredSkill + 30.0;
}
public override int GetMana()
{
return RequiredMana;
}
public override TimeSpan GetCastDelay()
{
return TimeSpan.FromSeconds( CastDelay );
}
}
}
[/code:1]
\\Scrips\Spells\Druid\BlendWithForest.cs
[code:1]
using System;
using Server;
using Server.Targeting;
using Server.Items;
namespace Server.Spells.Druid
{
public class BlendWithForestSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Blend With Forest", "Kes Ohm",
SpellCircle.Sixth,
206,
9002,
false,
Reagent.Bloodmoss,
Reagent.Nightshade
);
public override double CastDelay{ get{ return 2.0; } }
public override double RequiredSkill{ get{ return 75.0; } }
public override int RequiredMana{ get{ return 60; } }
public BlendWithForestSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckBSequence( m ) )
{
SpellHelper.Turn( Caster, m );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( m.X, m.Y, m.Z + 16 ), Caster.Map, EffectItem.DefaultDuration ), 0x376A, 10, 15, 5045 );
m.Hidden = true;
TimeSpan duration = TimeSpan.FromSeconds( Caster.Skills[CastSkill].Value * 1.5 );
new InternalTimer( m, duration ).Start();
}
FinishSequence();
}
private class InternalTimer : Timer
{
private Mobile m_Mobile;
public InternalTimer( Mobile m, TimeSpan duration ) : base( duration )
{
m_Mobile = m;
}
protected override void OnTick()
{
m_Mobile.RevealingAction();
}
}
public class InternalTarget : Target
{
private BlendWithForestSpell m_Owner;
public InternalTarget( BlendWithForestSpell owner ) : base( 12, false, TargetFlags.Beneficial )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
{
m_Owner.Target( (Mobile)o );
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
[/code:1]
\\Scrips\Spells\Druid\GraspingRoots.cs
[code:1]
using System;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
namespace Server.Spells.Druid
{
public class GraspingRootsSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Grasping Roots", "En Ohm Sepa Tia Kes",
SpellCircle.Fifth,
218,
9012,
false,
Reagent.SpringWater,
Reagent.Bloodmoss,
Reagent.SpidersSilk
);
public override double CastDelay{ get{ return 1.5; } }
public override double RequiredSkill{ get{ return 40.0; } }
public override int RequiredMana{ get{ return 40; } }
public GraspingRootsSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckHSequence( m ) )
{
SpellHelper.Turn( Caster, m );
double duration;
// Algorithm: ((20% of AnimalTamin) + 7) seconds [- 50% if resisted] seems to work??
duration = 7.0 + (Caster.Skills[DamageSkill].Value * 0.2);
// Resist if Str + Dex / 2 is greater than CastSkill eg. AnimalLore seems to work??
if ( ( Caster.Skills[CastSkill].Value ) < ( ( m.Str + m.Dex ) * 0.5 ) )
duration *= 0.5;
// no less than 0 seconds no more than 9 seconds
if ( duration < 0.0 )
duration = 0.0;
if ( duration > 9.0 )
duration = 9.0;
m.PlaySound( 0x2A1 );
m.Paralyze( TimeSpan.FromSeconds( duration ) );
m.FixedParticles( 0x375A, 2, 10, 5027, 0x3D, 2, EffectLayer.Waist );
{
Point3D loc = new Point3D( m.X, m.Y, m.Z );
Item item = new InternalItem( loc, Caster.Map, Caster );
}
}
FinishSequence();
}
//[DispellableField]
private class InternalItem : Item
{
private Timer m_Timer;
private DateTime m_End;
//public override bool BlocksFit{ get{ return true; } }
public InternalItem( Point3D loc, Map map, Mobile caster ) : base( 0xC5F )
{
Visible = false;
Movable = false;
MoveToWorld( loc, map );
if ( caster.InLOS( this ) )
Visible = true;
else
Delete();
if ( Deleted )
return;
m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( 30.0 ) );
m_Timer.Start();
m_End = DateTime.Now + TimeSpan.FromSeconds( 30.0 );
}
public InternalItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( m_End - DateTime.Now );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if ( m_Timer != null )
m_Timer.Stop();
}
private class InternalTimer : Timer
{
private InternalItem m_Item;
public InternalTimer( InternalItem item, TimeSpan duration ) : base( duration )
{
m_Item = item;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
private class InternalTarget : Target
{
private GraspingRootsSpell m_Owner;
public InternalTarget( GraspingRootsSpell owner ) : base( 12, true, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
m_Owner.Target( (Mobile)o );
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
[/code:1]
\\Scrips\Spells\Druid\HollowReedSpell.cs
[code:1]
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Druid
{
public class HollowReedSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Hollow Reed", "En Crur Aeta Sec En Ess ",
SpellCircle.Second,
203,
9061,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.Nightshade
);
public override double CastDelay{ get{ return 1.0; } }
public override double RequiredSkill{ get{ return 30.0; } }
public override int RequiredMana{ get{ return 30; } }
public HollowReedSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckBSequence( m ) )
{
SpellHelper.Turn( Caster, m );
SpellHelper.AddStatBonus( Caster, m, StatType.Str );
SpellHelper.AddStatBonus( Caster, m, StatType.Dex );
m.PlaySound( 0x15 );
m.FixedParticles( 0x373A, 10, 15, 5018, EffectLayer.Waist );
}
FinishSequence();
}
private class InternalTarget : Target
{
private HollowReedSpell m_Owner;
public InternalTarget( HollowReedSpell owner ) : base( 12, false, TargetFlags.Beneficial )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
{
m_Owner.Target( (Mobile)o );
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
[/code:1]
\\Scrips\Spells\Druid\PackOfBeast.cs
[code:1]
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Druid
{
public class PackOfBeastSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Pack Of Beast", "En Sec Ohm Ess Sepa",
SpellCircle.Third,
266,
9040,
false,
Reagent.BlackPearl,
Reagent.Bloodmoss,
Reagent.PetrafiedWood
);
public override double CastDelay{ get{ return 1.0; } }
public override double RequiredSkill{ get{ return 40.0; } }
public override int RequiredMana{ get{ return 45; } }
public PackOfBeastSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
private static Type[] m_Types = new Type[]
{
typeof( BrownBear ),
typeof( TimberWolf ),
typeof( Panther ),
typeof( GreatHart ),
typeof( Hind ),
typeof( Alligator ),
typeof( Boar ),
typeof( GiantRat )
};
public override void OnCast()
{
if ( CheckSequence() )
{
try
{
Type beasttype = ( m_Types[Utility.Random( m_Types.Length )] );
BaseCreature creaturea = (BaseCreature)Activator.CreateInstance( beasttype );
BaseCreature creatureb = (BaseCreature)Activator.CreateInstance( beasttype );
BaseCreature creaturec = (BaseCreature)Activator.CreateInstance( beasttype );
BaseCreature creatured = (BaseCreature)Activator.CreateInstance( beasttype );
SpellHelper.Summon( creaturea, Caster, 0x215, TimeSpan.FromSeconds( 4.0 * Caster.Skills[CastSkill].Value ), false, false );
SpellHelper.Summon( creatureb, Caster, 0x215, TimeSpan.FromSeconds( 4.0 * Caster.Skills[CastSkill].Value ), false, false );
Double morebeast = 0 ;
morebeast = Utility.Random( 10 ) + ( Caster.Skills[CastSkill].Value * 0.1 );
if ( morebeast > 11 )
{
SpellHelper.Summon( creaturec, Caster, 0x215, TimeSpan.FromSeconds( 4.0 * Caster.Skills[CastSkill].Value ), false, false );
}
if ( morebeast > 18 )
{
SpellHelper.Summon( creatured, Caster, 0x215, TimeSpan.FromSeconds( 4.0 * Caster.Skills[CastSkill].Value ), false, false );
}
}
catch
{
}
}
FinishSequence();
}
public override TimeSpan GetCastDelay()
{
return TimeSpan.FromSeconds( 7.5 );
}
}
}
[/code:1]
\\Scrips\Spells\Druid\SheildOfEarth.cs
[code:1]
using System;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
namespace Server.Spells.Druid
{
public class SheildOfEarthSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Sheild Of Earth", "Kes En Sepa Ohm",
SpellCircle.First,
227,
9011,
false,
Reagent.Ginseng,
Reagent.SpringWater
);
public override double CastDelay{ get{ return 1.0; } }
public override double RequiredSkill{ get{ return 20.0; } }
public override int RequiredMana{ get{ return 15; } }
public SheildOfEarthSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( IPoint3D p )
{
if ( !Caster.CanSee( p ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( SpellHelper.CheckTown( p, Caster ) && CheckSequence() )
{
SpellHelper.Turn( Caster, p );
SpellHelper.GetSurfaceTop( ref p );
int dx = Caster.Location.X - p.X;
int dy = Caster.Location.Y - p.Y;
int rx = (dx - dy) * 44;
int ry = (dx + dy) * 44;
bool eastToWest;
if ( rx >= 0 && ry >= 0 )
{
eastToWest = false;
}
else if ( rx >= 0 )
{
eastToWest = true;
}
else if ( ry >= 0 )
{
eastToWest = true;
}
else
{
eastToWest = false;
}
Effects.PlaySound( p, Caster.Map, 0x50 );
for ( int i = -2; i <= 2; ++i )
{
Point3D loc = new Point3D( eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z );
bool canFit = SpellHelper.AdjustField( ref loc, Caster.Map, 22, true );
if ( !canFit )
continue;
Item item = new InternalItem( loc, Caster.Map, Caster );
Effects.SendLocationParticles( item, 0x376A, 9, 10, 5025 );
}
}
FinishSequence();
}
[DispellableField]
private class InternalItem : Item
{
private Timer m_Timer;
private DateTime m_End;
public override bool BlocksFit{ get{ return true; } }
public InternalItem( Point3D loc, Map map, Mobile caster ) : base( 0x0C92 )
{
Visible = false;
Movable = false;
MoveToWorld( loc, map );
if ( caster.InLOS( this ) )
Visible = true;
else
Delete();
if ( Deleted )
return;
m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( 30.0 ) );
m_Timer.Start();
m_End = DateTime.Now + TimeSpan.FromSeconds( 30.0 );
}
public InternalItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( m_End - DateTime.Now );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
TimeSpan duration = reader.ReadTimeSpan();
m_Timer = new InternalTimer( this, duration );
m_Timer.Start();
m_End = DateTime.Now + duration;
break;
}
case 0:
{
TimeSpan duration = TimeSpan.FromSeconds( 10.0 );
m_Timer = new InternalTimer( this, duration );
m_Timer.Start();
m_End = DateTime.Now + duration;
break;
}
}
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if ( m_Timer != null )
m_Timer.Stop();
}
private class InternalTimer : Timer
{
private InternalItem m_Item;
public InternalTimer( InternalItem item, TimeSpan duration ) : base( duration )
{
m_Item = item;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
private class InternalTarget : Target
{
private SheildOfEarthSpell m_Owner;
public InternalTarget( SheildOfEarthSpell owner ) : base( 12, true, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is IPoint3D )
m_Owner.Target( (IPoint3D)o );
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
[/code:1]
\\Scrips\Spells\Druid\SpringOfLife.cs
[code:1]
using System;
using System.Collections;
using Server.Network;
using Server.Items;
using Server.Targeting;
using Server.Spells.Druid;
namespace Server.Spells.Druid
{
public class SpringOfLifeSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Spring Of Life", "En Sepa Aete",
SpellCircle.Fourth,
204,
9061,
false,
Reagent.SpringWater,
Reagent.SpringWater
);
public override double CastDelay{ get{ return 1.0; } }
public override double RequiredSkill{ get{ return 40.0; } }
public override int RequiredMana{ get{ return 40; } }
public SpringOfLifeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( IPoint3D p )
{
if ( !Caster.CanSee( p ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, p );
SpellHelper.GetSurfaceTop( ref p );
ArrayList targets = new ArrayList();
IPooledEnumerable eable = Caster.Map.GetMobilesInRange( new Point3D( p ), 3 );
foreach ( Mobile m in eable )
{
if ( Caster.CanBeBeneficial( m, false ) )
targets.Add( m );
}
eable.Free();
Effects.PlaySound( p, Caster.Map, 0x11 );
int val = (int)(Caster.Skills[CastSkill].Value/20.0 + 5);
if ( targets.Count > 0 )
{
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = (Mobile)targets;
if ( m.BeginAction( typeof( SpringOfLifeSpell ) ) )
{
Caster.DoBeneficial( m );
m.FixedParticles( 0x375A, 9, 20, 5027, EffectLayer.Head );
int toHeal = (int)(Caster.Skills[DamageSkill].Value * 0.6);
toHeal += Utility.Random( 1, 10 );
m.Heal( toHeal );
new InternalTimer( m, Caster, val ).Start();
m.FixedParticles( 0x375A, 9, 20, 5027, EffectLayer.Waist );
m.PlaySound( 0xAF );
}
}
}
}
FinishSequence();
}
private class InternalTimer : Timer
{
private Mobile m_Owner;
private int m_Val;
public InternalTimer( Mobile target, Mobile caster, int val ) : base( TimeSpan.FromSeconds( 0 ) )
{
double time = caster.Skills[SkillName.AnimalLore].Value * 1.2;
if ( time > 300 )
time = 300;
Delay = TimeSpan.FromSeconds( time );
Priority = TimerPriority.TwoFiftyMS;
m_Owner = target;
m_Val = val;
}
protected override void OnTick()
{
m_Owner.EndAction( typeof( SpringOfLifeSpell ) );
m_Owner.Str -= m_Val;
if ( m_Owner.Str < 0 )
m_Owner.Str = 0;
}
}
private class InternalTarget : Target
{
private SpringOfLifeSpell m_Owner;
public InternalTarget( SpringOfLifeSpell owner ) : base( 12, true, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
IPoint3D p = o as IPoint3D;
if ( p != null )
m_Owner.Target( p );
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
[/code:1]
\\Scrips\Spells\Druid\SwarmOfInsects.cs
[code:1]
using System;
using System.Collections;
using Server.Network;
using Server.Items;
using Server.Targeting;
namespace Server.Spells.Druid
{
public class SwarmOfInsectsSpell : DruidicSpell
{
private static SpellInfo m_Info = new SpellInfo(
"Swarm Of Insects", "Ess Ohm En Sec Tia",
SpellCircle.Seventh,
263,
9032,
false,
Reagent.Garlic,
Reagent.Nightshade,
Reagent.DestroyingAngel
);
public override double CastDelay{ get{ return 2.0; } }
public override double RequiredSkill{ get{ return 85.0; } }
public override int RequiredMana{ get{ return 70; } }
public SwarmOfInsectsSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( Mobile m )
{
if ( CheckHSequence( m ) )
{
SpellHelper.Turn( Caster, m );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
CheckResisted( m ); // Check magic resist for skill, but do not use return value
m.FixedParticles( 0x91B, 1, 240, 9916, 0, 3, EffectLayer.Head );
m.PlaySound( 0x1E5 );
double damage = ((Caster.Skills[CastSkill].Value - m.Skills[SkillName.AnimalLore].Value) / 10) + 30;
if ( damage < 1 )
damage = 1;
if ( m_Table.Contains( m ) )
damage /= 10;
else
new InternalTimer( m, damage * 0.5 ).Start();
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private static Hashtable m_Table = new Hashtable();
private class InternalTimer : Timer
{
private Mobile m_Mobile;
private int m_ToRestore;
public InternalTimer( Mobile m, double toRestore ) : base( TimeSpan.FromSeconds( 20.0 ) )
{
Priority = TimerPriority.OneSecond;
m_Mobile = m;
m_ToRestore = (int)toRestore;
m_Table[m] = this;
}
protected override void OnTick()
{
m_Table.Remove( m_Mobile );
if ( m_Mobile.Alive )
m_Mobile.Hits += m_ToRestore;
}
}
private class InternalTarget : Target
{
private SwarmOfInsectsSpell m_Owner;
public InternalTarget( SwarmOfInsectsSpell owner ) : base( 12, false, TargetFlags.Harmful )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
m_Owner.Target( (Mobile) o );
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
[/code:1]