#W# Initial Commit: Avatars Conquest

This commit is contained in:
WarrentyExpired 2026-07-04 10:35:30 -04:00
commit 5df497787a
7510 changed files with 416048 additions and 0 deletions

View file

@ -0,0 +1,79 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.First
{
public class ClumsySpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Clumsy", "Uus Jux",
212,
9031,
Reagent.Bloodmoss,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public ClumsySpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
SpellHelper.AddStatCurse( Caster, m, StatType.Dex );
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles( 0x3779, 10, 15, 5002, EffectLayer.Head );
m.PlaySound( 0x1DF );
HarmfulSpell( m );
}
FinishSequence();
}
private class InternalTarget : Target
{
private ClumsySpell m_Owner;
public InternalTarget( ClumsySpell 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();
}
}
}
}

View file

@ -0,0 +1,95 @@
using System;
using Server.Items;
namespace Server.Spells.First
{
public class CreateFoodSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Create Food", "In Mani Ylem",
224,
9011,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public CreateFoodSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
private static FoodInfo[] m_Food = new FoodInfo[]
{
new FoodInfo( typeof( Grapes ), "a grape bunch" ),
new FoodInfo( typeof( Ham ), "a ham" ),
new FoodInfo( typeof( CheeseWedge ), "a wedge of cheese" ),
new FoodInfo( typeof( Muffins ), "muffins" ),
new FoodInfo( typeof( FishSteak ), "a fish steak" ),
new FoodInfo( typeof( Ribs ), "cut of ribs" ),
new FoodInfo( typeof( CookedBird ), "a cooked bird" ),
new FoodInfo( typeof( Sausage ), "sausage" ),
new FoodInfo( typeof( Apple ), "an apple" ),
new FoodInfo( typeof( Peach ), "a peach" )
};
public override void OnCast()
{
if ( CheckSequence() )
{
FoodInfo foodInfo = m_Food[Utility.Random( m_Food.Length )];
Item food = foodInfo.Create();
if ( food != null )
{
Caster.AddToBackpack( food );
if ( Utility.RandomBool() )
Caster.AddToBackpack( new FlaskAle() );
else
Caster.AddToBackpack( new FlaskWine() );
// You magically create food in your backpack:
Caster.SendLocalizedMessage( 1042695, true, " " + foodInfo.Name );
Caster.FixedParticles( 0, 10, 5, 2003, EffectLayer.RightHand );
Caster.PlaySound( 0x1E2 );
}
}
FinishSequence();
}
}
public class FoodInfo
{
private Type m_Type;
private string m_Name;
public Type Type{ get{ return m_Type; } set{ m_Type = value; } }
public string Name{ get{ return m_Name; } set{ m_Name = value; } }
public FoodInfo( Type type, string name )
{
m_Type = type;
m_Name = name;
}
public Item Create()
{
Item item;
try
{
item = (Item)Activator.CreateInstance( m_Type );
}
catch
{
item = null;
}
return item;
}
}
}

View file

@ -0,0 +1,79 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.First
{
public class FeeblemindSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Feeblemind", "Rel Wis",
212,
9031,
Reagent.Ginseng,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public FeeblemindSpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
SpellHelper.AddStatCurse( Caster, m, StatType.Int );
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles( 0x3779, 10, 15, 5004, EffectLayer.Head );
m.PlaySound( 0x1E4 );
HarmfulSpell( m );
}
FinishSequence();
}
private class InternalTarget : Target
{
private FeeblemindSpell m_Owner;
public InternalTarget( FeeblemindSpell 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();
}
}
}
}

View file

@ -0,0 +1,89 @@
using System;
using Server;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
namespace Server.Spells.First
{
public class HealSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Heal", "In Mani",
224,
9061,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public HealSpell( 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 ( m.IsDeadBondedPet )
{
Caster.SendLocalizedMessage( 1060177 ); // You cannot heal a creature that is already dead!
}
else if ( m is Golem )
{
Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500951 ); // You cannot heal that.
}
else if ( m.Poisoned )
{
Caster.LocalOverheadMessage( MessageType.Regular, 0x22, (Caster == m) ? 1005000 : 1010398 );
}
else if ( CheckBSequence( m ) )
{
SpellHelper.Turn( Caster, m );
int toHeal = (int)(Caster.Skills[SkillName.Magery].Value * 0.1);
toHeal += Utility.Random( 1, 5 );
//m.Heal( toHeal, Caster );
SpellHelper.Heal( toHeal, m, Caster );
m.FixedParticles( 0x376A, 9, 32, 5005, EffectLayer.Waist );
m.PlaySound( 0x1F2 );
}
FinishSequence();
}
public class InternalTarget : Target
{
private HealSpell m_Owner;
public InternalTarget( HealSpell 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();
}
}
}
}

View file

@ -0,0 +1,88 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.First
{
public class MagicArrowSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Arrow", "In Por Ylem",
212,
9041,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public MagicArrowSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool DelayedDamageStacking { get { return true; } }
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckHSequence( m ) )
{
Mobile source = Caster;
SpellHelper.Turn( source, m );
SpellHelper.CheckReflect( (int)this.Circle, ref source, ref m );
double damage = Utility.Random( 4, 4 );
if ( CheckResisted( m ) )
{
damage *= 0.75;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
damage *= GetDamageScalar( m );
source.MovingParticles( m, 0x36E4, 5, 0, false, false, 3006, 0, 0 );
source.PlaySound( 0x1E5 );
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private class InternalTarget : Target
{
private MagicArrowSpell m_Owner;
public InternalTarget( MagicArrowSpell 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();
}
}
}
}

View file

@ -0,0 +1,74 @@
using System;
using Server.Targeting;
using Server.Network;
using Server;
namespace Server.Spells.First
{
public class NightSightSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Night Sight", "In Lor",
236,
9031,
Reagent.SulfurousAsh,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public NightSightSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new NightSightTarget( this );
}
private class NightSightTarget : Target
{
private Spell m_Spell;
public NightSightTarget( Spell spell ) : base( 12, false, TargetFlags.Beneficial )
{
m_Spell = spell;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile && m_Spell.CheckBSequence( (Mobile) targeted ) )
{
Mobile targ = (Mobile)targeted;
SpellHelper.Turn( m_Spell.Caster, targ );
if ( targ.BeginAction( typeof( LightCycle ) ) )
{
new LightCycle.NightSightTimer( targ ).Start();
int level = (int)( LightCycle.DungeonLevel * ( from.Skills[SkillName.Magery].Value/100 ) );
if ( level < 0 )
level = 0;
targ.LightLevel = level;
targ.FixedParticles( 0x376A, 9, 32, 5007, EffectLayer.Waist );
targ.PlaySound( 0x1E3 );
}
else
{
from.SendMessage( "{0} already have nightsight.", from == targ ? "You" : "They" );
}
}
m_Spell.FinishSequence();
}
protected override void OnTargetFinish( Mobile from )
{
m_Spell.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,79 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.First
{
public class ReactiveArmorSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Reactive Armor", "Flam Sanct",
236,
9011,
Reagent.Garlic,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public ReactiveArmorSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( Caster.MeleeDamageAbsorb > 0 )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
return false;
}
else if ( !Caster.CanBeginAction( typeof( DefensiveSpell ) ) )
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
return false;
}
return true;
}
private static Hashtable m_Table = new Hashtable();
public override void OnCast()
{
if ( Caster.MeleeDamageAbsorb > 0 )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if ( !Caster.CanBeginAction( typeof( DefensiveSpell ) ) )
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
}
else if ( CheckSequence() )
{
if ( Caster.BeginAction( typeof( DefensiveSpell ) ) )
{
int value = (int)(Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Meditation].Value + Caster.Skills[SkillName.Concentration].Value);
value /= 3;
if ( value < 0 )
value = 1;
else if ( value > 75 )
value = 75;
Caster.MeleeDamageAbsorb = value;
Caster.FixedParticles( 0x376A, 9, 32, 5008, EffectLayer.Waist );
Caster.PlaySound( 0x1F2 );
}
else
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
}
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,79 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.First
{
public class WeakenSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Weaken", "Des Mani",
212,
9031,
Reagent.Garlic,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public WeakenSpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
SpellHelper.AddStatCurse( Caster, m, StatType.Str );
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles( 0x3779, 10, 15, 5009, EffectLayer.Waist );
m.PlaySound( 0x1E6 );
HarmfulSpell( m );
}
FinishSequence();
}
public class InternalTarget : Target
{
private WeakenSpell m_Owner;
public InternalTarget( WeakenSpell 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();
}
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Second
{
public class AgilitySpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Agility", "Ex Uus",
212,
9061,
Reagent.Bloodmoss,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public AgilitySpell( 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.Dex );
m.FixedParticles( 0x375A, 10, 15, 5010, EffectLayer.Waist );
m.PlaySound( 0x1e7 );
}
FinishSequence();
}
private class InternalTarget : Target
{
private AgilitySpell m_Owner;
public InternalTarget( AgilitySpell 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();
}
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Second
{
public class CunningSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Cunning", "Uus Wis",
212,
9061,
Reagent.MandrakeRoot,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public CunningSpell( 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.Int );
m.FixedParticles( 0x375A, 10, 15, 5011, EffectLayer.Head );
m.PlaySound( 0x1EB );
}
FinishSequence();
}
private class InternalTarget : Target
{
private CunningSpell m_Owner;
public InternalTarget( CunningSpell 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();
}
}
}
}

View file

@ -0,0 +1,92 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Second
{
public class CureSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Cure", "An Nox",
212,
9061,
Reagent.Garlic,
Reagent.Ginseng
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public CureSpell( 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 );
Poison p = m.Poison;
if ( p != null )
{
int chanceToCure = 10000 + (int)(Caster.Skills[SkillName.Magery].Value * 75) - ((p.Level + 1) * (1750));
chanceToCure /= 100;
if ( chanceToCure > Utility.Random( 100 ) )
{
if ( m.CurePoison( Caster ) )
{
if ( Caster != m )
Caster.SendLocalizedMessage( 1010058 ); // You have cured the target of all poisons!
m.SendLocalizedMessage( 1010059 ); // You have been cured of all poisons.
}
}
else
{
m.SendLocalizedMessage( 1010060 ); // You have failed to cure your target!
}
}
m.FixedParticles( 0x373A, 10, 15, 5012, EffectLayer.Waist );
m.PlaySound( 0x1E0 );
}
FinishSequence();
}
public class InternalTarget : Target
{
private CureSpell m_Owner;
public InternalTarget( CureSpell 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();
}
}
}
}

View file

@ -0,0 +1,97 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Second
{
public class HarmSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Harm", "An Mani",
212,
9041,
Reagent.Nightshade,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public HarmSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return false; } }
public override double GetSlayerDamageScalar( Mobile target )
{
return 1.0; //This spell isn't affected by slayer spellbooks
}
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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
double damage = Utility.Random( 1, 15 );
if ( CheckResisted( m ) )
{
damage *= 0.75;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
damage *= GetDamageScalar( m );
if ( !m.InRange( Caster, 2 ) )
damage *= 0.25; // 1/4 damage at > 2 tile range
else if ( !m.InRange( Caster, 1 ) )
damage *= 0.50; // 1/2 damage at 2 tile range
m.FixedParticles( 0x374A, 10, 15, 5013, EffectLayer.Waist );
m.PlaySound( 0x1F1 );
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private class InternalTarget : Target
{
private HarmSpell m_Owner;
public InternalTarget( HarmSpell 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();
}
}
}
}

View file

@ -0,0 +1,172 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Items;
using Server.Regions;
namespace Server.Spells.Second
{
public class MagicTrapSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Trap", "In Jux",
212,
9001,
Reagent.Garlic,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public MagicTrapSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( TrapableContainer item )
{
if ( !Caster.CanSee( item ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( item.TrapType != TrapType.None && item.TrapType != TrapType.MagicTrap )
{
base.DoFizzle();
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
item.TrapType = TrapType.MagicTrap;
item.TrapPower = (int)( ( Caster.Skills[SkillName.Concentration].Value + Caster.Skills[SkillName.Magery].Value ) / 3 );
item.TrapLevel = 0;
Point3D loc = item.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X + 1, loc.Y, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X, loc.Y - 1, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X - 1, loc.Y, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X, loc.Y + 1, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X, loc.Y, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0, 0, 0, 5014 );
Effects.PlaySound( loc, item.Map, 0x1EF );
}
FinishSequence();
}
public void Doorway( BaseDoor item )
{
if ( !(Caster.Region is DungeonRegion) )
{
Caster.SendMessage( "This spell only works on dungeon doors." );
}
else if ( !Caster.CanSee( item ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( item.TrapType != TrapType.None && item.TrapType != TrapType.MagicTrap )
{
base.DoFizzle();
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
item.TrapType = TrapType.MagicTrap;
item.TrapPower = (int)( ( Caster.Skills[SkillName.Concentration].Value + Caster.Skills[SkillName.Magery].Value ) / 3 );
item.TrapLevel = 0;
Point3D loc = item.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X + 1, loc.Y, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X, loc.Y - 1, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X - 1, loc.Y, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X, loc.Y + 1, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 9502 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc.X, loc.Y, loc.Z ), item.Map, EffectItem.DefaultDuration ), 0, 0, 0, 5014 );
Effects.PlaySound( loc, item.Map, 0x1EF );
double time = Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Concentration].Value + 20.0;
DateTime currentTime = DateTime.Now;
DateTime laterTime = currentTime.AddSeconds(time);
item.Rigged = laterTime;
}
FinishSequence();
}
public void Targets( BaseDoor targ )
{
if ( !(Caster.Region is DungeonRegion) )
{
Caster.SendMessage( "This spell only works on dungeon doors." );
}
else if ( targ.Sealed > DateTime.Now )
{
Caster.SendMessage( "That door is already magically locked." );
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, targ );
Point3D loc = targ.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( loc, targ.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5020 );
Effects.PlaySound( loc, targ.Map, 0x1FA );
// The door is now locked!
Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 502401 );
double time = Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Concentration].Value + 20.0;
DateTime currentTime = DateTime.Now;
DateTime laterTime = currentTime.AddSeconds(time);
targ.Sealed = laterTime;
}
FinishSequence();
}
private class InternalTarget : Target
{
private MagicTrapSpell m_Owner;
public InternalTarget( MagicTrapSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is LootChest )
((LootChest)o).Setup();
if ( o is TrapableContainer )
{
m_Owner.Target( (TrapableContainer)o );
}
else if ( o is BaseDoor )
{
m_Owner.Doorway( (BaseDoor)o );
}
else
{
from.SendMessage( "You can't trap that" );
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,105 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Second
{
public class ProtectionSpell : MagerySpell
{
private static Hashtable m_Registry = new Hashtable();
public static Hashtable Registry { get { return m_Registry; } }
private static SpellInfo m_Info = new SpellInfo(
"Protection", "Uus Sanct",
236,
9011,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public ProtectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( m_Registry.ContainsKey( Caster ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
return false;
}
else if ( !Caster.CanBeginAction( typeof( DefensiveSpell ) ) )
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
return false;
}
return true;
}
public override void OnCast()
{
if ( m_Registry.ContainsKey( Caster ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if ( !Caster.CanBeginAction( typeof( DefensiveSpell ) ) )
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
}
else if ( CheckSequence() )
{
if ( Caster.BeginAction( typeof( DefensiveSpell ) ) )
{
double value = (int)(Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Meditation].Value + Caster.Skills[SkillName.Concentration].Value);
value /= 4;
if ( value < 0 )
value = 0;
else if ( value > 75 )
value = 75.0;
Registry.Add( Caster, value );
new InternalTimer( Caster ).Start();
Caster.FixedParticles( 0x375A, 9, 20, 5016, EffectLayer.Waist );
Caster.PlaySound( 0x1ED );
}
else
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
}
}
FinishSequence();
}
private class InternalTimer : Timer
{
private Mobile m_Caster;
public InternalTimer( Mobile caster ) : base( TimeSpan.FromSeconds( 0 ) )
{
double val = caster.Skills[SkillName.Magery].Value + caster.Skills[SkillName.Concentration].Value;
if ( val < 15 )
val = 15;
else if ( val > 240 )
val = 240;
m_Caster = caster;
Delay = TimeSpan.FromSeconds( val );
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
ProtectionSpell.Registry.Remove( m_Caster );
DefensiveSpell.Nullify( m_Caster );
}
}
}
}

View file

@ -0,0 +1,139 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Items;
namespace Server.Spells.Second
{
public class RemoveTrapSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Remove Trap", "An Jux",
212,
9001,
Reagent.Bloodmoss,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public RemoveTrapSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
Caster.SendMessage( "What do you wish to untrap?" );
}
public void Target( TrapableContainer item )
{
if ( !Caster.CanSee( item ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( item.TrapType != TrapType.None && item.TrapType != TrapType.MagicTrap )
{
base.DoFizzle();
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
Point3D loc = item.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( loc, item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5015 );
Effects.PlaySound( loc, item.Map, 0x1F0 );
item.TrapType = TrapType.None;
item.TrapPower = 0;
item.TrapLevel = 0;
}
FinishSequence();
}
public void Trapped( BaseTrap item )
{
if ( !Caster.CanSee( item ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
Point3D loc = item.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( loc, item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5015 );
Effects.PlaySound( loc, item.Map, 0x1F0 );
item.WhenDisarmed = (DateTime.Now).AddMinutes((double)(Utility.RandomMinMax(20,40)));
}
FinishSequence();
}
public void Doorway( BaseDoor item )
{
if ( !Caster.CanSee( item ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
Point3D loc = item.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( loc, item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5015 );
Effects.PlaySound( loc, item.Map, 0x1F0 );
item.TrapType = TrapType.None;
item.TrapPower = 0;
item.TrapLevel = 0;
}
FinishSequence();
}
private class InternalTarget : Target
{
private RemoveTrapSpell m_Owner;
public InternalTarget( RemoveTrapSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is LootChest )
((LootChest)o).Setup();
if ( o is TrapableContainer )
{
m_Owner.Target( (TrapableContainer)o );
}
else if ( o is BaseTrap && !(o is MushroomTrap))
{
m_Owner.Trapped( (BaseTrap)o );
}
else if ( o is BaseDoor )
{
m_Owner.Doorway( (BaseDoor)o );
}
else
{
from.SendMessage( "You can't disarm that" );
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Second
{
public class StrengthSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Strength", "Uus Mani",
212,
9061,
Reagent.MandrakeRoot,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public StrengthSpell( 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 );
m.FixedParticles( 0x375A, 10, 15, 5017, EffectLayer.Waist );
m.PlaySound( 0x1EE );
}
FinishSequence();
}
private class InternalTarget : Target
{
private StrengthSpell m_Owner;
public InternalTarget( StrengthSpell 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();
}
}
}
}

View file

@ -0,0 +1,72 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Third
{
public class BlessSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Bless", "Rel Sanct",
203,
9061,
Reagent.Garlic,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public BlessSpell( 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.DisableSkillCheck = true;
SpellHelper.AddStatBonus( Caster, m, StatType.Dex );
SpellHelper.AddStatBonus( Caster, m, StatType.Int ); SpellHelper.DisableSkillCheck = false;
m.FixedParticles( 0x373A, 10, 15, 5018, EffectLayer.Waist );
m.PlaySound( 0x1EA );
}
FinishSequence();
}
private class InternalTarget : Target
{
private BlessSpell m_Owner;
public InternalTarget( BlessSpell 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();
}
}
}
}

View file

@ -0,0 +1,84 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Third
{
public class FireballSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Fireball", "Vas Flam",
203,
9041,
Reagent.BlackPearl
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public FireballSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckHSequence( m ) )
{
Mobile source = Caster;
SpellHelper.Turn( source, m );
SpellHelper.CheckReflect( (int)this.Circle, ref source, ref m );
double damage = Utility.Random( 10, 7 );
if ( CheckResisted( m ) )
{
damage *= 0.75;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
damage *= GetDamageScalar( m );
source.MovingParticles( m, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
source.PlaySound( 0x44B );
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private class InternalTarget : Target
{
private FireballSpell m_Owner;
public InternalTarget( FireballSpell 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();
}
}
}
}

View file

@ -0,0 +1,124 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Items;
using Server.Regions;
namespace Server.Spells.Third
{
public class MagicLockSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Lock", "An Por",
215,
9001,
Reagent.Garlic,
Reagent.Bloodmoss,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public MagicLockSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( LockableContainer targ )
{
if ( Multis.BaseHouse.CheckLockedDownOrSecured( targ ) )
{
// You cannot cast this on a locked down item.
Caster.LocalOverheadMessage( MessageType.Regular, 0x22, 501761 );
}
else if ( targ.Locked || targ.LockLevel == 0 )
{
// Target must be an unlocked chest.
Caster.SendLocalizedMessage( 501762 );
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, targ );
Point3D loc = targ.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( loc, targ.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5020 );
Effects.PlaySound( loc, targ.Map, 0x1FA );
// The chest is now locked!
Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501763 );
targ.LockLevel = -255; // signal magic lock
targ.Locked = true;
}
FinishSequence();
}
public void Targets( BaseDoor targ )
{
if ( !(Caster.Region is DungeonRegion) )
{
Caster.SendMessage( "This spell only works on dungeon doors." );
}
else if ( targ.Sealed > DateTime.Now )
{
Caster.SendMessage( "That door is already magically locked." );
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, targ );
Point3D loc = targ.GetWorldLocation();
Effects.SendLocationParticles( EffectItem.Create( loc, targ.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5020 );
Effects.PlaySound( loc, targ.Map, 0x1FA );
// The door is now locked!
Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 502401 );
double time = Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Concentration].Value + 20.0;
DateTime currentTime = DateTime.Now;
DateTime laterTime = currentTime.AddSeconds(time);
targ.Sealed = laterTime;
}
FinishSequence();
}
private class InternalTarget : Target
{
private MagicLockSpell m_Owner;
public InternalTarget( MagicLockSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is LootChest )
((LootChest)o).Setup();
if ( o is LockableContainer )
m_Owner.Target( (LockableContainer)o );
else if ( o is BaseDoor )
m_Owner.Targets( (BaseDoor)o );
else
from.SendMessage( "Target must be an unlocked chest or dungeon door." );
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,103 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Third
{
public class PoisonSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Poison", "In Nox",
203,
9051,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public PoisonSpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
if ( CheckResisted( m ) )
{
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
else
{
int level;
double total = Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Poisoning].Value;
double dist = Caster.GetDistanceToSqrt( m );
if ( dist >= 3.0 )
total -= (dist - 3.0) * 10.0;
if ( total >= 200.0 && 1 > Utility.Random( 10 ) )
level = 3;
else if ( total > 170.0 )
level = 2;
else if ( total > 130.0 )
level = 1;
else
level = 0;
m.ApplyPoison( Caster, Poison.GetPoison( level ) );
}
m.FixedParticles( 0x374A, 10, 15, 5021, EffectLayer.Waist );
m.PlaySound( 0x205 );
HarmfulSpell( m );
}
FinishSequence();
}
private class InternalTarget : Target
{
private PoisonSpell m_Owner;
public InternalTarget( PoisonSpell 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();
}
}
}
}

View file

@ -0,0 +1,112 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Regions;
using Server.Items;
namespace Server.Spells.Third
{
public class TelekinesisSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Telekinesis", "Ort Por Ylem",
203,
9031,
Reagent.Bloodmoss,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public TelekinesisSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( ITelekinesisable obj )
{
if ( CheckSequence() )
{
SpellHelper.Turn( Caster, obj );
obj.OnTelekinesis( Caster );
}
FinishSequence();
}
public void Target( Container item )
{
if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
object root = item.RootParent;
if ( !item.IsAccessibleTo( Caster ) )
{
item.OnDoubleClickNotAccessible( Caster );
}
else if ( !item.CheckItemUse( Caster, item ) )
{
}
else if ( root != null && root is Mobile && root != Caster )
{
item.OnSnoop( Caster );
}
else if ( item is Corpse && !((Corpse)item).CheckLoot( Caster, null ) )
{
}
else if ( Caster.Region.OnDoubleClick( Caster, item ) )
{
Effects.SendLocationParticles( EffectItem.Create( item.Location, item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5022 );
Effects.PlaySound( item.Location, item.Map, 0x1F5 );
item.OnItemUsed( Caster, item );
}
}
FinishSequence();
}
public class InternalTarget : Target
{
private TelekinesisSpell m_Owner;
public InternalTarget( TelekinesisSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is LootChest )
((LootChest)o).Setup();
if ( o is ITelekinesisable )
m_Owner.Target( (ITelekinesisable)o );
else if ( o is Container )
m_Owner.Target( (Container)o );
else
from.SendLocalizedMessage( 501857 ); // This spell won't work on that!
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}
namespace Server
{
public interface ITelekinesisable : IPoint3D
{
void OnTelekinesis( Mobile from );
}
}

View file

@ -0,0 +1,121 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Regions;
using Server.Items;
namespace Server.Spells.Third
{
public class TeleportSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Teleport", "Rel Por",
215,
9031,
Reagent.Bloodmoss,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public TeleportSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( Server.Misc.WeightOverloading.IsOverloaded( Caster ) )
{
Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
return false;
}
return true;
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( IPoint3D p )
{
IPoint3D orig = p;
Map map = Caster.Map;
SpellHelper.GetSurfaceTop( ref p );
if ( Server.Misc.WeightOverloading.IsOverloaded( Caster ) )
{
Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
}
else if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( SpellHelper.CheckMulti( new Point3D( p ), map ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, orig );
Mobile m = Caster;
Point3D from = m.Location;
Point3D to = new Point3D( p );
m.Location = to;
m.ProcessDelta();
if ( m.Player )
{
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 );
}
else
{
m.FixedParticles( 0x376A, 9, 32, 0x13AF, EffectLayer.Waist );
}
m.PlaySound( 0x1FE );
IPooledEnumerable eable = m.GetItemsInRange( 0 );
foreach ( Item item in eable )
{
if ( item is Server.Spells.Sixth.ParalyzeFieldSpell.InternalItem || item is Server.Spells.Fifth.PoisonFieldSpell.InternalItem || item is Server.Spells.Fourth.FireFieldSpell.FireFieldItem )
item.OnMoveOver( m );
}
eable.Free();
}
FinishSequence();
}
public class InternalTarget : Target
{
private TeleportSpell m_Owner;
public InternalTarget( TeleportSpell 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();
}
}
}
}

View file

@ -0,0 +1,104 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Items;
using Server.Regions;
namespace Server.Spells.Third
{
public class UnlockSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Unlock Spell", "Ex Por",
215,
9001,
Reagent.Bloodmoss,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public UnlockSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
private class InternalTarget : Target
{
private UnlockSpell m_Owner;
public InternalTarget( UnlockSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is LootChest )
((LootChest)o).Setup();
IPoint3D loc = o as IPoint3D;
if ( loc == null )
return;
if ( m_Owner.CheckSequence() ) {
SpellHelper.Turn( from, o );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( loc ), from.Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5024 );
Effects.PlaySound( loc, from.Map, 0x1FF );
if ( o is Mobile )
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 503101 ); // That did not need to be unlocked.
else if ( o is BaseDoor )
{
BaseDoor door = (BaseDoor)o;
if ( door.Sealed < DateTime.Now )
from.SendMessage( "That does not need to be unlocked." );
else
{
door.Sealed = DateTime.MinValue;
}
}
else if ( !( o is LockableContainer ) )
from.SendLocalizedMessage( 501666 ); // You can't unlock that!
else {
LockableContainer cont = (LockableContainer)o;
if ( Multis.BaseHouse.CheckSecured( cont ) )
from.SendLocalizedMessage( 503098 ); // You cannot cast this on a secure item.
else if ( !cont.Locked )
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 503101 ); // That did not need to be unlocked.
else if ( cont.LockLevel == 0 )
from.SendLocalizedMessage( 501666 ); // You can't unlock that!
else {
int level = (int)( ( from.Skills[SkillName.Magery].Value + from.Skills[SkillName.Concentration].Value ) * 0.4) - 4;
if ( level >= cont.RequiredSkill && !(cont is TreasureMapChest && ((TreasureMapChest)cont).Level > 2) ) {
cont.Locked = false;
if ( cont.LockLevel == -255 )
cont.LockLevel = cont.RequiredSkill - 10;
}
else
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 503099 ); // My spell does not seem to have an effect on that lock.
}
}
}
m_Owner.FinishSequence();
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,213 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
namespace Server.Spells.Third
{
public class WallOfStoneSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Wall of Stone", "In Sanct Ylem",
227,
9011,
false,
Reagent.Bloodmoss,
Reagent.Garlic
);
public override SpellCircle Circle { get { return SpellCircle.Third; } }
public WallOfStoneSpell( 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, 0x1F6 );
for ( int i = -1; i <= 1; ++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 );
//Effects.SendLocationParticles( EffectItem.Create( loc, Caster.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 5025 );
if ( !canFit )
continue;
Item item = new InternalItem( loc, Caster.Map, Caster );
Effects.SendLocationParticles( item, 0x376A, 9, 10, 5025 );
//new InternalItem( loc, Caster.Map, Caster );
}
}
FinishSequence();
}
[DispellableField]
private class InternalItem : Item
{
private Timer m_Timer;
private DateTime m_End;
private Mobile m_Caster;
public override bool BlocksFit{ get{ return true; } }
public InternalItem( Point3D loc, Map map, Mobile caster ) : base( 0x82 )
{
Visible = false;
Movable = false;
MoveToWorld( loc, map );
m_Caster = caster;
if ( caster.InLOS( this ) )
Visible = true;
else
Delete();
if ( Deleted )
return;
m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( 10.0 ) );
m_Timer.Start();
m_End = DateTime.Now + TimeSpan.FromSeconds( 10.0 );
}
public InternalItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.WriteDeltaTime( m_End );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
m_End = reader.ReadDeltaTime();
m_Timer = new InternalTimer( this, m_End - DateTime.Now );
m_Timer.Start();
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 )
{
Priority = TimerPriority.OneSecond;
m_Item = item;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
private class InternalTarget : Target
{
private WallOfStoneSpell m_Owner;
public InternalTarget( WallOfStoneSpell 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();
}
}
}
}

View file

@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using Server.Network;
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
namespace Server.Spells.Fourth
{
public class ArchCureSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Arch Cure", "Vas An Nox",
215,
9061,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public ArchCureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
// Archcure is now 1/4th of a second faster
public override TimeSpan CastDelayBase{ get{ return base.CastDelayBase - TimeSpan.FromSeconds( 0.25 ); } }
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 );
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
Mobile m_directtarget = p as Mobile;
if ( map != null )
{
bool OldUO = true;
//you can target directly someone/something and become criminal if it's a criminal action
if ( m_directtarget != null )
targets.Add ( m_directtarget );
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), (2+(int)(Caster.Skills[SkillName.Concentration].Value/20)) );
foreach ( Mobile m in eable )
{
// Archcure area effect won't cure aggressors or victims, nor murderers, criminals or monsters
// red players can cure only themselves and guildies with arch cure area.
if ( Caster.CanBeBeneficial( m, false ) && ( OldUO || !IsAggressor( m ) && !IsAggressed( m ) && (( IsInnocentTo ( Caster, m ) && IsInnocentTo ( m, Caster ) ) || ( IsAllyTo ( Caster, m ) )) && m != m_directtarget && m is PlayerMobile || m == Caster && m != m_directtarget ))
targets.Add( m );
}
eable.Free();
}
Effects.PlaySound( p, Caster.Map, 0x299 );
if ( targets.Count > 0 )
{
int cured = 0;
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
Caster.DoBeneficial( m );
Poison poison = m.Poison;
if ( poison != null )
{
int chanceToCure = 10000 + (int)(Caster.Skills[SkillName.Magery].Value * 75) - ((poison.Level + 1) * 1750);
chanceToCure /= 100;
chanceToCure -= 1;
if ( chanceToCure > Utility.Random( 100 ) && m.CurePoison( Caster ) )
++cured;
}
m.FixedParticles( 0x373A, 10, 15, 5012, EffectLayer.Waist );
m.PlaySound( 0x1E0 );
}
if ( cured > 0 )
Caster.SendLocalizedMessage( 1010058 ); // You have cured the target of all poisons!
}
}
FinishSequence();
}
private bool IsAggressor( Mobile m )
{
foreach ( AggressorInfo info in Caster.Aggressors )
{
if ( m == info.Attacker && !info.Expired )
return true;
}
return false;
}
private bool IsAggressed( Mobile m )
{
foreach ( AggressorInfo info in Caster.Aggressed )
{
if ( m == info.Defender && !info.Expired )
return true;
}
return false;
}
private static bool IsInnocentTo( Mobile from, Mobile to )
{
return ( Notoriety.Compute( from, (Mobile)to ) == Notoriety.Innocent );
}
private static bool IsAllyTo( Mobile from, Mobile to )
{
return ( Notoriety.Compute( from, (Mobile)to ) == Notoriety.Ally );
}
private class InternalTarget : Target
{
private ArchCureSpell m_Owner;
public InternalTarget( ArchCureSpell 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();
}
}
}
}

View file

@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using Server.Network;
using Server.Items;
using Server.Targeting;
using Server.Engines.PartySystem;
namespace Server.Spells.Fourth
{
public class ArchProtectionSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Arch Protection", "Vas Uus Sanct",
215,
9011,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public ArchProtectionSpell( 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 );
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), (3+(int)(Caster.Skills[SkillName.Concentration].Value/20)) );
foreach ( Mobile m in eable )
{
if ( Caster.CanBeBeneficial( m, false ) )
targets.Add( m );
}
eable.Free();
}
Effects.PlaySound( p, Caster.Map, 0x299 );
int val = (int)(Caster.Skills[SkillName.Magery].Value/10.0 + 1);
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
val = val + (int)(Caster.Skills[SkillName.Concentration].Value/20.0);
if ( targets.Count > 0 )
{
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
if ( m.BeginAction( typeof( ArchProtectionSpell ) ) )
{
Caster.DoBeneficial( m );
m.VirtualArmorMod += val;
new InternalTimer( m, Caster, val ).Start();
m.FixedParticles( 0x375A, 9, 20, 5027, EffectLayer.Waist );
m.PlaySound( 0x1F7 );
}
}
}
}
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.Magery].Value * 1.2;
if ( time > 144 )
time = 144;
Delay = TimeSpan.FromSeconds( time );
Priority = TimerPriority.OneSecond;
m_Owner = target;
m_Val = val;
}
protected override void OnTick()
{
m_Owner.EndAction( typeof( ArchProtectionSpell ) );
m_Owner.VirtualArmorMod -= m_Val;
if ( m_Owner.VirtualArmorMod < 0 )
m_Owner.VirtualArmorMod = 0;
}
}
private class InternalTarget : Target
{
private ArchProtectionSpell m_Owner;
public InternalTarget( ArchProtectionSpell 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();
}
}
}
}

103
Scripts/Spells/4th/Curse.cs Normal file
View file

@ -0,0 +1,103 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Fourth
{
public class CurseSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Curse", "Des Sanct",
227,
9031,
Reagent.Nightshade,
Reagent.Garlic,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public CurseSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
private static Hashtable m_UnderEffect = new Hashtable();
public static void RemoveEffect( object state )
{
Mobile m = (Mobile)state;
m_UnderEffect.Remove( m );
}
public static bool UnderEffect( Mobile m )
{
return m_UnderEffect.Contains( m );
}
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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
SpellHelper.AddStatCurse( Caster, m, StatType.Str ); SpellHelper.DisableSkillCheck = true;
SpellHelper.AddStatCurse( Caster, m, StatType.Dex );
SpellHelper.AddStatCurse( Caster, m, StatType.Int ); SpellHelper.DisableSkillCheck = false;
Timer t = (Timer)m_UnderEffect[m];
if ( Caster.Player && m.Player /*&& Caster != m */ && t == null ) //On OSI you CAN curse yourself and get this effect.
{
TimeSpan duration = SpellHelper.GetDuration( Caster, m );
m_UnderEffect[m] = t = Timer.DelayCall( duration, new TimerStateCallback( RemoveEffect ), m );
}
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles( 0x374A, 10, 15, 5028, EffectLayer.Waist );
m.PlaySound( 0x1E1 );
HarmfulSpell( m );
}
FinishSequence();
}
private class InternalTarget : Target
{
private CurseSpell m_Owner;
public InternalTarget( CurseSpell 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();
}
}
}
}

View file

@ -0,0 +1,312 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
namespace Server.Spells.Fourth
{
public class FireFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Fire Field", "In Flam Grav",
215,
9041,
false,
Reagent.BlackPearl,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public FireFieldSpell( 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, 0x20C );
int itemID = eastToWest ? 0x398C : 0x3996;
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
TimeSpan duration = TimeSpan.FromSeconds( ( 4.0 + (Caster.Skills[SkillName.Magery].Value * 0.5) ) + (Caster.Skills[SkillName.Concentration].Value/10) );
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 );
new FireFieldItem( itemID, loc, Caster, Caster.Map, duration, i );
}
}
FinishSequence();
}
[DispellableField]
public class FireFieldItem : Item
{
private Timer m_Timer;
private DateTime m_End;
private Mobile m_Caster;
private int m_Damage;
public override bool BlocksFit{ get{ return true; } }
public FireFieldItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val )
: this( itemID, loc, caster, map, duration, val, 2 )
{
}
public FireFieldItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val, int damage ) : base( itemID )
{
bool canFit = SpellHelper.AdjustField( ref loc, map, 12, false );
Visible = false;
Movable = false;
Light = LightType.Circle300;
MoveToWorld( loc, map );
m_Caster = caster;
m_Damage = damage;
m_End = DateTime.Now + duration;
m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( Math.Abs( val ) * 0.2 ), caster.InLOS( this ), canFit );
m_Timer.Start();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if ( m_Timer != null )
m_Timer.Stop();
}
public FireFieldItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 2 ); // version
writer.Write( m_Damage );
writer.Write( m_Caster );
writer.WriteDeltaTime( m_End );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 2:
{
m_Damage = reader.ReadInt();
goto case 1;
}
case 1:
{
m_Caster = reader.ReadMobile();
goto case 0;
}
case 0:
{
m_End = reader.ReadDeltaTime();
m_Timer = new InternalTimer( this, TimeSpan.Zero, true, true );
m_Timer.Start();
break;
}
}
if( version < 2 )
m_Damage = 2;
}
public override bool OnMoveOver( Mobile m )
{
if ( Visible && m_Caster != null && SpellHelper.ValidIndirectTarget( m_Caster, m ) && m_Caster.CanBeHarmful( m, false ) )
{
if ( SpellHelper.CanRevealCaster( m ) )
m_Caster.RevealingAction();
m_Caster.DoHarmful( m );
int damage = m_Damage;
if ( m.CheckSkill( SkillName.MagicResist, 0.0, 30.0 ) )
{
damage = 1;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
Ultima.Damage( m, m_Caster, damage );
m.PlaySound( 0x208 );
if ( m is BaseCreature )
((BaseCreature) m).OnHarmfulSpell( m_Caster );
}
return true;
}
private class InternalTimer : Timer
{
private FireFieldItem m_Item;
private bool m_InLOS, m_CanFit;
private static Queue m_Queue = new Queue();
public InternalTimer( FireFieldItem item, TimeSpan delay, bool inLOS, bool canFit ) : base( delay, TimeSpan.FromSeconds( 1.0 ) )
{
m_Item = item;
m_InLOS = inLOS;
m_CanFit = canFit;
Priority = TimerPriority.FiftyMS;
}
protected override void OnTick()
{
if ( m_Item.Deleted )
return;
if ( !m_Item.Visible )
{
if ( m_InLOS && m_CanFit )
m_Item.Visible = true;
else
m_Item.Delete();
if ( !m_Item.Deleted )
{
m_Item.ProcessDelta();
Effects.SendLocationParticles( EffectItem.Create( m_Item.Location, m_Item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 5029 );
}
}
else if ( DateTime.Now > m_Item.m_End )
{
m_Item.Delete();
Stop();
}
else
{
Map map = m_Item.Map;
Mobile caster = m_Item.m_Caster;
if ( map != null && caster != null )
{
foreach ( Mobile m in m_Item.GetMobilesInRange( 0 ) )
{
if ( (m.Z + 16) > m_Item.Z && (m_Item.Z + 12) > m.Z && SpellHelper.ValidIndirectTarget( caster, m ) && caster.CanBeHarmful( m, false ) )
m_Queue.Enqueue( m );
}
while ( m_Queue.Count > 0 )
{
Mobile m = (Mobile)m_Queue.Dequeue();
if ( SpellHelper.CanRevealCaster( m ) )
caster.RevealingAction();
caster.DoHarmful( m );
int damage = m_Item.m_Damage;
if ( m.CheckSkill( SkillName.MagicResist, 0.0, 30.0 ) )
{
damage = 1;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
Ultima.Damage( m, caster, damage );
m.PlaySound( 0x208 );
if ( m is BaseCreature )
((BaseCreature) m).OnHarmfulSpell( caster );
}
}
}
}
}
}
private class InternalTarget : Target
{
private FireFieldSpell m_Owner;
public InternalTarget( FireFieldSpell 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();
}
}
}
}

View file

@ -0,0 +1,92 @@
using System;
using Server;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
namespace Server.Spells.Fourth
{
public class GreaterHealSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Greater Heal", "In Vas Mani",
204,
9061,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public GreaterHealSpell( 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 ( m.IsDeadBondedPet )
{
Caster.SendLocalizedMessage( 1060177 ); // You cannot heal a creature that is already dead!
}
else if ( m is Golem )
{
Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500951 ); // You cannot heal that.
}
else if ( m.Poisoned )
{
Caster.LocalOverheadMessage( MessageType.Regular, 0x22, (Caster == m) ? 1005000 : 1010398 );
}
else if ( CheckBSequence( m ) )
{
SpellHelper.Turn( Caster, m );
// Algorithm: (40% of magery) + (1-10)
int toHeal = (int)(Caster.Skills[SkillName.Magery].Value * 0.4);
toHeal += Utility.Random( 1, 10 );
//m.Heal( toHeal, Caster );
SpellHelper.Heal( toHeal, m, Caster );
m.FixedParticles( 0x376A, 9, 32, 5030, EffectLayer.Waist );
m.PlaySound( 0x202 );
}
FinishSequence();
}
public class InternalTarget : Target
{
private GreaterHealSpell m_Owner;
public InternalTarget( GreaterHealSpell 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();
}
}
}
}

View file

@ -0,0 +1,82 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Fourth
{
public class LightningSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Lightning", "Por Ort Grav",
239,
9021,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public LightningSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return false; } }
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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
double damage = Utility.Random( 12, 9 );
if ( CheckResisted( m ) )
{
damage *= 0.75;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
damage *= GetDamageScalar( m );
m.BoltEffect( 0 );
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private class InternalTarget : Target
{
private LightningSpell m_Owner;
public InternalTarget( LightningSpell 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();
}
}
}
}

View file

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Fourth
{
public class ManaDrainSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mana Drain", "Ort Rel",
215,
9031,
Reagent.BlackPearl,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public ManaDrainSpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
if ( CheckResisted( m ) )
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
else if ( m.Mana >= 100 )
m.Mana -= Utility.Random( 1, 100 );
else
m.Mana -= Utility.Random( 1, m.Mana );
m.FixedParticles( 0x374A, 10, 15, 5032, EffectLayer.Head );
m.PlaySound( 0x1F8 );
HarmfulSpell( m );
}
FinishSequence();
}
public override double GetResistPercent( Mobile target )
{
return 99.0;
}
private class InternalTarget : Target
{
private ManaDrainSpell m_Owner;
public InternalTarget( ManaDrainSpell 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();
}
}
}
}

View file

@ -0,0 +1,131 @@
using System;
using Server.Items;
using Server.Multis;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
using Server.Regions;
namespace Server.Spells.Fourth
{
public class RecallSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Recall", "Kal Ort Por",
239,
9031,
Reagent.BlackPearl,
Reagent.Bloodmoss,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public RecallSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void GetCastSkills( out double min, out double max )
{
base.GetCastSkills( out min, out max );
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool CheckCast()
{
if ( Server.Engines.Harvest.Fishing.IsOnBoat( Caster ) )
{
Caster.SendMessage( "The waves of the sea are distracting you from casting this spell!" );
Caster.FixedEffect( 0x3735, 6, 30 );
Caster.PlaySound( 0x5C );
return false;
}
else if ( SpellHelper.CheckCombat( Caster ) )
{
Caster.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
return false;
}
else if ( Server.Misc.WeightOverloading.IsOverloaded( Caster ) )
{
Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
return false;
}
return true;
}
public void Effect( Point3D loc, Map map, bool checkMulti )
{
if ( SpellHelper.CheckCombat( Caster ) )
{
Caster.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
}
else if ( Server.Misc.WeightOverloading.IsOverloaded( Caster ) )
{
Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
}
else if ( !map.CanSpawnMobile( loc.X, loc.Y, loc.Z ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( (checkMulti && SpellHelper.CheckMulti( loc, map )) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( CheckSequence() )
{
BaseCreature.TeleportPets( Caster, loc, map, true );
Caster.PlaySound( 0x1FC );
Caster.MoveToWorld( loc, map );
Caster.PlaySound( 0x1FC );
}
FinishSequence();
}
private class InternalTarget : Target
{
private RecallSpell m_Owner;
public InternalTarget( RecallSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
owner.Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501029 ); // Select Marked item.
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is MagicRune )
{
MagicRune rune = (MagicRune)o;
if ( rune.Marked && rune.Owner != from )
from.SendMessage( "This rune belongs to someone else." );
else if ( rune.Marked )
m_Owner.Effect( rune.Target, rune.TargetMap, true );
else
from.SendLocalizedMessage( 501805 ); // That rune is not yet marked.
}
else
{
from.Send( new MessageLocalized( from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 502357, from.Name, "" ) ); // I can not recall from that object.
}
}
protected override void OnNonlocalTarget( Mobile from, object o )
{
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,102 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Fifth
{
public class BladeSpiritsSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Blade Spirits", "In Jux Hur Ylem",
266,
9040,
false,
Reagent.BlackPearl,
Reagent.MandrakeRoot,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public BladeSpiritsSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override TimeSpan GetCastDelay()
{
return base.GetCastDelay() + TimeSpan.FromSeconds( 6.0 );
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if( (Caster.Followers + 1) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( IPoint3D p )
{
Map map = Caster.Map;
SpellHelper.GetSurfaceTop( ref p );
if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( SpellHelper.CheckTown( p, Caster ) && CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( Utility.Random( 80, 40 ) + (Caster.Skills.Concentration.Value / 5) );
BaseCreature.Summon( new BladeSpirits(), false, Caster, new Point3D( p ), 0x212, duration );
}
FinishSequence();
}
private class InternalTarget : Target
{
private BladeSpiritsSpell m_Owner;
public InternalTarget( BladeSpiritsSpell 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 OnTargetOutOfLOS( Mobile from, object o )
{
from.SendLocalizedMessage( 501943 ); // Target cannot be seen. Try again.
from.Target = new InternalTarget( m_Owner );
from.Target.BeginTimeout( from, TimeoutTime - DateTime.Now );
m_Owner = null;
}
protected override void OnTargetFinish( Mobile from )
{
if ( m_Owner != null )
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,88 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Items;
using Server.Misc;
namespace Server.Spells.Fifth
{
public class DispelFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Dispel Field", "An Grav",
206,
9002,
Reagent.BlackPearl,
Reagent.SpidersSilk,
Reagent.SulfurousAsh,
Reagent.Garlic
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public DispelFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( Item item )
{
Type t = item.GetType();
if ( !Caster.CanSee( item ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( !t.IsDefined( typeof( DispellableFieldAttribute ), false ) )
{
Caster.SendLocalizedMessage( 1005049 ); // That cannot be dispelled.
}
else if ( item is Magicgate && !((Magicgate)item).Dispellable )
{
Caster.SendLocalizedMessage( 1005047 ); // That magic is too chaotic
}
else if ( CheckSequence() )
{
SpellHelper.Turn( Caster, item );
Effects.SendLocationParticles( EffectItem.Create( item.Location, item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 20, 5042 );
Effects.PlaySound( item.GetWorldLocation(), item.Map, 0x201 );
item.Delete();
}
FinishSequence();
}
private class InternalTarget : Target
{
private DispelFieldSpell m_Owner;
public InternalTarget( DispelFieldSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Item )
{
m_Owner.Target( (Item)o );
}
else
{
m_Owner.Caster.SendLocalizedMessage( 1005049 ); // That cannot be dispelled.
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,176 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Misc;
using Server.Items;
using Server.Gumps;
using Server.Spells;
using Server.Spells.Seventh;
namespace Server.Spells.Fifth
{
public class IncognitoSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Incognito", "Kal In Ex",
206,
9002,
Reagent.Bloodmoss,
Reagent.Garlic,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public IncognitoSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !Caster.CanBeginAction( typeof( IncognitoSpell ) ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
return false;
}
return true;
}
public override void OnCast()
{
if ( !Caster.CanBeginAction( typeof( IncognitoSpell ) ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if ( Caster.BodyMod == 183 || Caster.BodyMod == 184 )
{
Caster.SendLocalizedMessage( 1042402 ); // You cannot use incognito while wearing body paint
}
else if ( DisguiseTimers.IsDisguised( Caster ) )
{
Caster.SendLocalizedMessage( 1061631 ); // You can't do that while disguised.
}
else if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) || Caster.IsBodyMod )
{
DoFizzle();
}
else if ( CheckSequence() )
{
if ( Caster.BeginAction( typeof( IncognitoSpell ) ) )
{
DisguiseTimers.StopTimer( Caster );
Caster.HueMod = Caster.Race.RandomSkinHue();
Caster.NameMod = Caster.Female ? NameList.RandomName( "female" ) : NameList.RandomName( "male" );
PlayerMobile pm = Caster as PlayerMobile;
if ( pm != null && pm.Race != null )
{
pm.SetHairMods( pm.Race.RandomHair( pm.Female ), pm.Race.RandomFacialHair( pm.Female ) );
pm.HairHue = pm.Race.RandomHairHue();
pm.FacialHairHue = pm.Race.RandomHairHue();
}
Caster.FixedParticles( 0x373A, 10, 15, 5036, EffectLayer.Head );
Caster.PlaySound( 0x3BD );
BaseArmor.ValidateMobile( Caster );
BaseClothing.ValidateMobile( Caster );
StopTimer( Caster );
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
int timeVal = (int)(((6 * Caster.Skills.Magery.Fixed) / 50) + 1 + (Caster.Skills[SkillName.Concentration].Value/5) );
if( timeVal > 144 )
timeVal = 144;
TimeSpan length = TimeSpan.FromSeconds( timeVal );
Timer t = new InternalTimer( Caster, length );
m_Timers[Caster] = t;
t.Start();
}
else
{
Caster.SendLocalizedMessage( 1079022 ); // You're already incognitoed!
}
}
FinishSequence();
}
private static Hashtable m_Timers = new Hashtable();
public static bool StopTimer( Mobile m )
{
Timer t = (Timer)m_Timers[m];
if ( t != null )
{
t.Stop();
m_Timers.Remove( m );
}
return ( t != null );
}
private static int[] m_HairIDs = new int[]
{
0x2044, 0x2045, 0x2046,
0x203C, 0x203B, 0x203D,
0x2047, 0x2048, 0x2049,
0x204A, 0x0000
};
private static int[] m_BeardIDs = new int[]
{
0x203E, 0x203F, 0x2040,
0x2041, 0x204B, 0x204C,
0x204D, 0x0000
};
private class InternalTimer : Timer
{
private Mobile m_Owner;
public InternalTimer( Mobile owner, TimeSpan length ) : base( length )
{
m_Owner = owner;
/*
int val = ((6 * owner.Skills.Magery.Fixed) / 50) + 1;
if ( val > 144 )
val = 144;
Delay = TimeSpan.FromSeconds( val );
* */
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
if ( !m_Owner.CanBeginAction( typeof( IncognitoSpell ) ) )
{
if ( m_Owner is PlayerMobile )
((PlayerMobile)m_Owner).SetHairMods( -1, -1 );
m_Owner.BodyMod = 0;
m_Owner.HueMod = -1;
m_Owner.NameMod = null;
m_Owner.EndAction( typeof( IncognitoSpell ) );
BaseArmor.ValidateMobile( m_Owner );
BaseClothing.ValidateMobile( m_Owner );
}
}
}
}
}

View file

@ -0,0 +1,77 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Fifth
{
public class MagicReflectSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Reflection", "In Jux Sanct",
242,
9012,
Reagent.Garlic,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public MagicReflectSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( Caster.MagicDamageAbsorb > 0 )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
return false;
}
else if ( !Caster.CanBeginAction( typeof( DefensiveSpell ) ) )
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
return false;
}
return true;
}
private static Hashtable m_Table = new Hashtable();
public override void OnCast()
{
if ( Caster.MagicDamageAbsorb > 0 )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if ( !Caster.CanBeginAction( typeof( DefensiveSpell ) ) )
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
}
else if ( CheckSequence() )
{
if ( Caster.BeginAction( typeof( DefensiveSpell ) ) )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
int value = (int)(Caster.Skills[SkillName.Magery].Value + Caster.Skills[SkillName.Concentration].Value);
value = (int)(8 + (value/200)*7.0);//absorb from 8 to 15 "circles"
Caster.MagicDamageAbsorb = value;
Caster.FixedParticles( 0x375A, 10, 15, 5037, EffectLayer.Waist );
Caster.PlaySound( 0x1E9 );
}
else
{
Caster.SendLocalizedMessage( 1005385 ); // The spell will not adhere to you at this time.
}
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,116 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Fifth
{
public class MindBlastSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mind Blast", "Por Corp Wis",
218,
9032,
Reagent.BlackPearl,
Reagent.MandrakeRoot,
Reagent.Nightshade,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public MindBlastSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckHSequence( m ) )
{
Mobile from = Caster, target = m;
SpellHelper.Turn( from, target );
SpellHelper.CheckReflect( (int)this.Circle, ref from, ref target );
// Algorithm: (highestStat - lowestStat) / 2 [- 50% if resisted]
int highestStat = target.Str, lowestStat = target.Str;
if ( target.Dex > highestStat )
highestStat = target.Dex;
if ( target.Dex < lowestStat )
lowestStat = target.Dex;
if ( target.Int > highestStat )
highestStat = target.Int;
if ( target.Int < lowestStat )
lowestStat = target.Int;
if ( highestStat > 150 )
highestStat = 150;
if ( lowestStat > 150 )
lowestStat = 150;
double damage = GetDamageScalar(m)*(highestStat - lowestStat) / 4;//less damage
if ( damage > 45 )
damage = 45;
if ( CheckResisted( target ) )
{
damage /= 2;
target.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
from.FixedParticles( 0x374A, 10, 15, 2038, EffectLayer.Head );
target.FixedParticles( 0x374A, 10, 15, 5038, EffectLayer.Head );
target.PlaySound( 0x213 );
SpellHelper.Damage( this, target, damage );
}
FinishSequence();
}
public override double GetSlayerDamageScalar( Mobile target )
{
return 1.0; //This spell isn't affected by slayer spellbooks
}
private class InternalTarget : Target
{
private MindBlastSpell m_Owner;
public InternalTarget( MindBlastSpell 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();
}
}
}
}

View file

@ -0,0 +1,85 @@
using System;
using Server.Mobiles;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Fifth
{
public class ParalyzeSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Paralyze", "An Ex Por",
218,
9012,
Reagent.Garlic,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public ParalyzeSpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
double duration;
// Algorithm: ((20% of magery) + 7) seconds [- 50% if resisted]
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
duration = 7.0 + (Caster.Skills[SkillName.Magery].Value * 0.2) + (Caster.Skills[SkillName.Concentration].Value/10);
if ( CheckResisted( m ) )
duration *= 0.75;
m.Paralyze( TimeSpan.FromSeconds( duration ) );
m.PlaySound( 0x204 );
m.FixedEffect( 0x376A, 6, 1 );
HarmfulSpell( m );
}
FinishSequence();
}
public class InternalTarget : Target
{
private ParalyzeSpell m_Owner;
public InternalTarget( ParalyzeSpell 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();
}
}
}
}

View file

@ -0,0 +1,285 @@
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
namespace Server.Spells.Fifth
{
public class PoisonFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Poison Field", "In Nox Grav",
230,
9052,
false,
Reagent.BlackPearl,
Reagent.Nightshade,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public PoisonFieldSpell( 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, 0x20B );
int itemID = eastToWest ? 0x3915 : 0x3922;
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
TimeSpan duration = TimeSpan.FromSeconds( 3 + (Caster.Skills.Magery.Fixed / 25) + (Caster.Skills[SkillName.Concentration].Value/10) );
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 );
new InternalItem( itemID, loc, Caster, Caster.Map, duration, i );
}
}
FinishSequence();
}
[DispellableField]
public class InternalItem : Item
{
private Timer m_Timer;
private DateTime m_End;
private Mobile m_Caster;
public override bool BlocksFit{ get{ return true; } }
public InternalItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val ) : base( itemID )
{
bool canFit = SpellHelper.AdjustField( ref loc, map, 12, false );
Visible = false;
Movable = false;
Light = LightType.Circle300;
MoveToWorld( loc, map );
m_Caster = caster;
m_End = DateTime.Now + duration;
m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( Math.Abs( val ) * 0.2 ), caster.InLOS( this ), canFit );
m_Timer.Start();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if ( m_Timer != null )
m_Timer.Stop();
}
public InternalItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( m_Caster );
writer.WriteDeltaTime( m_End );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
m_Caster = reader.ReadMobile();
goto case 0;
}
case 0:
{
m_End = reader.ReadDeltaTime();
m_Timer = new InternalTimer( this, TimeSpan.Zero, true, true );
m_Timer.Start();
break;
}
}
}
public void ApplyPoisonTo( Mobile m )
{
if ( m_Caster == null )
return;
Poison p = Poison.Regular;
if ( m.ApplyPoison( m_Caster, p ) == ApplyPoisonResult.Poisoned )
if ( SpellHelper.CanRevealCaster( m ) )
m_Caster.RevealingAction();
if ( m is BaseCreature )
( (BaseCreature) m ).OnHarmfulSpell( m_Caster );
}
public override bool OnMoveOver( Mobile m )
{
if ( Visible && m_Caster != null && SpellHelper.ValidIndirectTarget( m_Caster, m ) && m_Caster.CanBeHarmful( m, false ) )
{
m_Caster.DoHarmful( m );
ApplyPoisonTo( m );
m.PlaySound( 0x474 );
}
return true;
}
private class InternalTimer : Timer
{
private InternalItem m_Item;
private bool m_InLOS, m_CanFit;
private static Queue m_Queue = new Queue();
public InternalTimer( InternalItem item, TimeSpan delay, bool inLOS, bool canFit ) : base( delay, TimeSpan.FromSeconds( 1.5 ) )
{
m_Item = item;
m_InLOS = inLOS;
m_CanFit = canFit;
Priority = TimerPriority.FiftyMS;
}
protected override void OnTick()
{
if ( m_Item.Deleted )
return;
if ( !m_Item.Visible )
{
if ( m_InLOS && m_CanFit )
m_Item.Visible = true;
else
m_Item.Delete();
if ( !m_Item.Deleted )
{
m_Item.ProcessDelta();
Effects.SendLocationParticles( EffectItem.Create( m_Item.Location, m_Item.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 5040 );
}
}
else if ( DateTime.Now > m_Item.m_End )
{
m_Item.Delete();
Stop();
}
else
{
Map map = m_Item.Map;
Mobile caster = m_Item.m_Caster;
if ( map != null && caster != null )
{
bool eastToWest = ( m_Item.ItemID == 0x3915 );
IPooledEnumerable eable = map.GetMobilesInBounds( new Rectangle2D( m_Item.X - (eastToWest ? 0 : 1), m_Item.Y - (eastToWest ? 1 : 0), (eastToWest ? 1 : 2), (eastToWest ? 2 : 1) ) );
foreach ( Mobile m in eable )
{
if ( (m.Z + 16) > m_Item.Z && (m_Item.Z + 12) > m.Z && SpellHelper.ValidIndirectTarget( caster, m ) && caster.CanBeHarmful( m, false ) )
m_Queue.Enqueue( m );
}
eable.Free();
while ( m_Queue.Count > 0 )
{
Mobile m = (Mobile)m_Queue.Dequeue();
caster.DoHarmful( m );
m_Item.ApplyPoisonTo( m );
m.PlaySound( 0x474 );
}
}
}
}
}
}
private class InternalTarget : Target
{
private PoisonFieldSpell m_Owner;
public InternalTarget( PoisonFieldSpell 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();
}
}
}
}

View file

@ -0,0 +1,90 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Fifth
{
public class SummonCreatureSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Summon Creature", "Kal Xen",
16,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public SummonCreatureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
// NOTE: Creature list based on 1hr of summon/release on OSI.
private static Type[] m_Types = new Type[]
{
typeof( PolarBear ),
typeof( GrizzlyBear ),
typeof( BlackBear ),
typeof( Walrus ),
typeof( Chicken ),
typeof( Scorpion ),
typeof( GiantSerpent ),
typeof( Alligator ),
typeof( GreyWolf ),
typeof( Slime ),
typeof( Eagle ),
typeof( Gorilla ),
typeof( SnowLeopard ),
typeof( Pig ),
typeof( Deer ),
typeof( Rabbit )
};
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 2) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
if ( CheckSequence() )
{
try
{
BaseCreature creature = (BaseCreature)Activator.CreateInstance( m_Types[Utility.Random( m_Types.Length )] );
creature.ControlSlots = 2;
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( (4.0 * Caster.Skills[SkillName.Magery].Value) + (4.0 * Caster.Skills[SkillName.Concentration].Value) );
SpellHelper.Summon( creature, Caster, 0x215, duration, false, false );
}
catch
{
}
}
FinishSequence();
}
public override TimeSpan GetCastDelay()
{
return base.GetCastDelay() + TimeSpan.FromSeconds( 6.0 );
}
}
}

View file

@ -0,0 +1,84 @@
using System;
using Server.Misc;
using Server.Items;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
namespace Server.Spells.Sixth
{
public class DispelSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Dispel", "An Ort",
218,
9002,
Reagent.Garlic,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public DispelSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public class InternalTarget : Target
{
private DispelSpell m_Owner;
public InternalTarget( DispelSpell owner ) : base( 12, false, TargetFlags.Harmful )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
{
Mobile m = (Mobile)o;
BaseCreature bc = m as BaseCreature;
if ( !from.CanSee( m ) )
{
from.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( bc == null || !bc.IsDispellable )
{
from.SendLocalizedMessage( 1005049 ); // That cannot be dispelled.
}
else if ( m_Owner.CheckHSequence( m ) )
{
SpellHelper.Turn( from, m );
double dispelChance = (50.0 + ((100 * (from.Skills.Magery.Value - bc.DispelDifficulty)) / (bc.DispelFocus*2))) / 100;
if ( dispelChance > Utility.RandomDouble() )
{
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
Effects.PlaySound( m, m.Map, 0x201 );
m.Delete();
}
else
{
m.FixedEffect( 0x3779, 10, 20 );
from.SendLocalizedMessage( 1010084 ); // The creature resisted the attempt to dispel it!
}
}
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,88 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Sixth
{
public class EnergyBoltSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Energy Bolt", "Corp Por",
230,
9022,
Reagent.BlackPearl,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public EnergyBoltSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( CheckHSequence( m ) )
{
Mobile source = Caster;
SpellHelper.Turn( Caster, m );
SpellHelper.CheckReflect( (int)this.Circle, ref source, ref m );
double damage = Utility.Random( 24, 18 );
if ( CheckResisted( m ) )
{
damage *= 0.75;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
// Scale damage based on evalint and resist
damage *= GetDamageScalar( m );
// Do the effects
source.MovingParticles( m, 0x379F, 7, 0, false, true, 3043, 4043, 0x211 );
source.PlaySound( 0x20A );
// Deal the damage
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private class InternalTarget : Target
{
private EnergyBoltSpell m_Owner;
public InternalTarget( EnergyBoltSpell 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();
}
}
}
}

View file

@ -0,0 +1,121 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Sixth
{
public class ExplosionSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Explosion", "Vas Ort Flam",
230,
9041,
Reagent.Bloodmoss,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public ExplosionSpell( Mobile caster, Item scroll )
: base( caster, scroll, m_Info )
{
}
public override bool DelayedDamageStacking { get { return true; } }
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage { get { return false; } }
public void Target( Mobile m )
{
if ( !Caster.CanSee( m ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( Caster.CanBeHarmful( m ) && CheckSequence() )
{
Mobile attacker = Caster, defender = m;
SpellHelper.Turn( Caster, m );
SpellHelper.CheckReflect( (int) this.Circle, Caster, ref m );
InternalTimer t = new InternalTimer( this, attacker, defender, m );
t.Start();
}
FinishSequence();
}
private class InternalTimer : Timer
{
private MagerySpell m_Spell;
private Mobile m_Target;
private Mobile m_Attacker, m_Defender;
public InternalTimer( MagerySpell spell, Mobile attacker, Mobile defender, Mobile target ): base( TimeSpan.FromSeconds( 2.5 ) )
{
m_Spell = spell;
m_Attacker = attacker;
m_Defender = defender;
m_Target = target;
if ( m_Spell != null )
m_Spell.StartDelayedDamageContext( attacker, this );
Priority = TimerPriority.FiftyMS;
}
protected override void OnTick()
{
if ( m_Attacker.HarmfulCheck( m_Defender ) )
{
double damage = Utility.Random( 23, 22 );
if ( m_Spell.CheckResisted( m_Target ) )
{
damage *= 0.75;
m_Target.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
damage *= m_Spell.GetDamageScalar( m_Target );
m_Target.FixedParticles( 0x36BD, 20, 10, 5044, EffectLayer.Head );
m_Target.PlaySound( 0x307 );
SpellHelper.Damage( m_Spell, m_Target, damage );
if ( m_Spell != null )
m_Spell.RemoveDelayedDamageContext( m_Attacker );
}
}
}
private class InternalTarget : Target
{
private ExplosionSpell m_Owner;
public InternalTarget( ExplosionSpell 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();
}
}
}
}

View file

@ -0,0 +1,125 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
using Server.Items;
namespace Server.Spells.Sixth
{
public class InvisibilitySpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Invisibility", "An Lor Xen",
206,
9002,
Reagent.Bloodmoss,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public InvisibilitySpell( 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 ( m is Mobiles.BaseVendor || m is Mobiles.PlayerVendor || m is Mobiles.PlayerBarkeeper || m.AccessLevel > Caster.AccessLevel )
{
Caster.SendLocalizedMessage( 501857 ); // This spell won't work on that!
}
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.PlaySound( 0x3C4 );
m.Hidden = true;
m.Combatant = null;
m.Warmode = false;
RemoveTimer( m );
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
TimeSpan duration = TimeSpan.FromSeconds( (( 1.2 * Caster.Skills.Magery.Fixed) / 10 ) + (Caster.Skills[SkillName.Concentration].Value/5) );
Timer t = new InternalTimer( m, duration );
m_Table[m] = t;
t.Start();
}
FinishSequence();
}
private static Hashtable m_Table = new Hashtable();
public static bool HasTimer( Mobile m )
{
return m_Table[m] != null;
}
public static void RemoveTimer( Mobile m )
{
Timer t = (Timer)m_Table[m];
if ( t != null )
{
t.Stop();
m_Table.Remove( m );
}
}
private class InternalTimer : Timer
{
private Mobile m_Mobile;
public InternalTimer( Mobile m, TimeSpan duration ) : base( duration )
{
Priority = TimerPriority.OneSecond;
m_Mobile = m;
}
protected override void OnTick()
{
m_Mobile.RevealingAction();
RemoveTimer( m_Mobile );
}
}
public class InternalTarget : Target
{
private InvisibilitySpell m_Owner;
public InternalTarget( InvisibilitySpell 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();
}
}
}
}

View file

@ -0,0 +1,99 @@
using System;
using Server.Items;
using Server.Targeting;
using Server.Network;
using Server.Regions;
namespace Server.Spells.Sixth
{
public class MarkSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mark", "Kal Por Ylem",
218,
9002,
Reagent.BlackPearl,
Reagent.Bloodmoss,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public MarkSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool CheckCast()
{
if ( Server.Engines.Harvest.Fishing.IsOnBoat( Caster ) )
{
Caster.SendMessage( "The waves of the sea are distracting you from casting this spell!" );
Caster.FixedEffect( 0x3735, 6, 30 );
Caster.PlaySound( 0x5C );
return false;
}
if ( !base.CheckCast() )
return false;
return true;
}
public void Target( MagicRune rune )
{
if ( !Caster.CanSee( rune ) )
{
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( SpellHelper.CheckMulti( Caster.Location, Caster.Map, true ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( !rune.IsChildOf( Caster.Backpack ) )
{
Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1062422 ); // You must have this rune in your backpack in order to mark it.
}
else if ( CheckSequence() )
{
rune.Mark( Caster );
Caster.PlaySound( 0x1FA );
Effects.SendLocationEffect( Caster, Caster.Map, 14201, 16 );
}
FinishSequence();
}
private class InternalTarget : Target
{
private MarkSpell m_Owner;
public InternalTarget( MarkSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is MagicRune )
{
m_Owner.Target( (MagicRune) o );
}
else
{
from.Send( new MessageLocalized( from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 501797, from.Name, "" ) ); // I cannot mark that object.
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,108 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Sixth
{
public class MassCurseSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mass Curse", "Vas Des Sanct",
218,
9031,
false,
Reagent.Garlic,
Reagent.Nightshade,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public MassCurseSpell( 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 );
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), (2+(int)(Caster.Skills[SkillName.Concentration].Value/20)) );
foreach ( Mobile m in eable )
{
if ( SpellHelper.ValidIndirectTarget( Caster, m ) && Caster.CanSee( m ) && Caster.CanBeHarmful( m, false ) )
targets.Add( m );
}
eable.Free();
}
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
Caster.DoHarmful( m );
SpellHelper.AddStatCurse( Caster, m, StatType.Str ); SpellHelper.DisableSkillCheck = true;
SpellHelper.AddStatCurse( Caster, m, StatType.Dex );
SpellHelper.AddStatCurse( Caster, m, StatType.Int ); SpellHelper.DisableSkillCheck = false;
m.FixedParticles( 0x374A, 10, 15, 5028, EffectLayer.Waist );
m.PlaySound( 0x1FB );
HarmfulSpell( m );
}
}
FinishSequence();
}
private class InternalTarget : Target
{
private MassCurseSpell m_Owner;
public InternalTarget( MassCurseSpell 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();
}
}
}
}

View file

@ -0,0 +1,224 @@
using System;
using Server.Targeting;
using Server.Items;
using Server.Network;
using Server.Misc;
using Server.Mobiles;
namespace Server.Spells.Sixth
{
public class ParalyzeFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Paralyze Field", "In Ex Grav",
230,
9012,
false,
Reagent.BlackPearl,
Reagent.Ginseng,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public ParalyzeFieldSpell( 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, 0x20B );
int itemID = eastToWest ? 0x3967 : 0x3979;
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
TimeSpan duration = TimeSpan.FromSeconds( 3.0 + (Caster.Skills[SkillName.Magery].Value / 3.0) + (Caster.Skills[SkillName.Concentration].Value / 10.0) );
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, 12, false );
if ( !canFit )
continue;
Item item = new InternalItem( Caster, itemID, loc, Caster.Map, duration );
item.ProcessDelta();
Effects.SendLocationParticles( EffectItem.Create( loc, Caster.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 5048 );
}
}
FinishSequence();
}
[DispellableField]
public class InternalItem : Item
{
private Timer m_Timer;
private Mobile m_Caster;
private DateTime m_End;
public override bool BlocksFit{ get{ return true; } }
public InternalItem( Mobile caster, int itemID, Point3D loc, Map map, TimeSpan duration ) : base( itemID )
{
Visible = false;
Movable = false;
Light = LightType.Circle300;
MoveToWorld( loc, map );
if ( caster.InLOS( this ) )
Visible = true;
else
Delete();
if ( Deleted )
return;
m_Caster = caster;
m_Timer = new InternalTimer( this, duration );
m_Timer.Start();
m_End = DateTime.Now + duration;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if ( m_Timer != null )
m_Timer.Stop();
}
public InternalItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Caster );
writer.WriteDeltaTime( m_End );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Caster = reader.ReadMobile();
m_End = reader.ReadDeltaTime();
m_Timer = new InternalTimer( this, m_End - DateTime.Now );
m_Timer.Start();
break;
}
}
}
public override bool OnMoveOver( Mobile m )
{
if ( Visible && m_Caster != null && SpellHelper.ValidIndirectTarget( m_Caster, m ) && m_Caster.CanBeHarmful( m, false ) )
{
if ( SpellHelper.CanRevealCaster( m ) )
m_Caster.RevealingAction();
m_Caster.DoHarmful( m );
double duration = 7.0 + (m_Caster.Skills[SkillName.Magery].Value * 0.2);
m.Paralyze( TimeSpan.FromSeconds( duration ) );
m.PlaySound( 0x204 );
m.FixedEffect( 0x376A, 10, 16 );
if ( m is BaseCreature )
((BaseCreature) m).OnHarmfulSpell( m_Caster );
}
return true;
}
private class InternalTimer : Timer
{
private Item m_Item;
public InternalTimer( Item item, TimeSpan duration ) : base( duration )
{
Priority = TimerPriority.OneSecond;
m_Item = item;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
private class InternalTarget : Target
{
private ParalyzeFieldSpell m_Owner;
public InternalTarget( ParalyzeFieldSpell 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();
}
}
}
}

View file

@ -0,0 +1,121 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Sixth
{
public class RevealSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Reveal", "Wis Quas",
206,
9002,
Reagent.Bloodmoss,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public RevealSpell( 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 );
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), 1 + (int)(Caster.Skills[SkillName.Magery].Value / 20.0) + (int)(Caster.Skills[SkillName.Concentration].Value / 20.0) );
foreach ( Mobile m in eable )
{
if ( m.Hidden && (m.AccessLevel == AccessLevel.Player || Caster.AccessLevel > m.AccessLevel) && CheckDifficulty( Caster, m ) )
targets.Add( m );
}
eable.Free();
}
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
m.RevealingAction();
m.FixedParticles( 0x375A, 9, 20, 5049, EffectLayer.Head );
m.PlaySound( 0x1FD );
}
}
FinishSequence();
}
// Reveal uses magery and detect hidden vs. hide and stealth
private static bool CheckDifficulty( Mobile from, Mobile m )
{
// Reveal always reveals vs. invisibility spell
if ( InvisibilitySpell.HasTimer( m ) )
return true;
int magery = from.Skills[SkillName.Magery].Fixed;
int search = from.Skills[SkillName.Searching].Fixed;
int hiding = m.Skills[SkillName.Hiding].Fixed;
int stealth = m.Skills[SkillName.Stealth].Fixed;
int divisor = hiding + stealth;
int chance;
if ( divisor > 0 )
chance = 50 * (magery + search) / divisor;
else
chance = 100;
return chance > Utility.Random( 100 );
}
private class InternalTarget : Target
{
private RevealSpell m_Owner;
public InternalTarget( RevealSpell 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();
}
}
}
}

View file

@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using Server.Network;
using Server.Items;
using Server.Targeting;
namespace Server.Spells.Seventh
{
public class ChainLightningSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Chain Lightning", "Vas Ort Grav",
209,
9022,
false,
Reagent.BlackPearl,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public ChainLightningSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
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 );
if ( p is Item )
p = ((Item)p).GetWorldLocation();
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
{
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), 2 );
foreach ( Mobile m in eable )
{
if ( SpellHelper.ValidIndirectTarget( Caster, m ) && Caster.CanBeHarmful( m, false ) )
{
targets.Add( m );
}
}
eable.Free();
}
double damage = Utility.Random( 27, 22 );
if ( targets.Count > 0 )
{
damage /= targets.Count;
double toDeal;
for ( int i = 0; i < targets.Count; ++i )
{
toDeal = damage;
Mobile m = targets[i];
toDeal *= GetDamageScalar( m );
if ( CheckResisted( m ) )
{
toDeal *= 0.5;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
toDeal *= GetDamageScalar( m );
Caster.DoHarmful( m );
SpellHelper.Damage( this, m, toDeal );
m.BoltEffect( 0 );
}
}
else
{
Caster.PlaySound ( 0x29 );
}
}
FinishSequence();
}
private class InternalTarget : Target
{
private ChainLightningSpell m_Owner;
public InternalTarget( ChainLightningSpell 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();
}
}
}
}

View file

@ -0,0 +1,193 @@
using System;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
namespace Server.Spells.Seventh
{
public class EnergyFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Energy Field", "In Sanct Grav",
221,
9022,
false,
Reagent.BlackPearl,
Reagent.MandrakeRoot,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public EnergyFieldSpell( 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, 0x20B );
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
// (28% of concentration) + (28% of magery) + 2.0 seconds
TimeSpan duration = TimeSpan.FromSeconds( (Caster.Skills[SkillName.Concentration].Value * 0.28) + (Caster.Skills[SkillName.Magery].Value * 0.28) + 2.0 );
int itemID = eastToWest ? 0x3946 : 0x3956;
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, 12, false );
if ( !canFit )
continue;
Item item = new InternalItem( loc, Caster.Map, duration, itemID, Caster );
item.ProcessDelta();
Effects.SendLocationParticles( EffectItem.Create( loc, Caster.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 5051 );
}
}
FinishSequence();
}
[DispellableField]
private class InternalItem : Item
{
private Timer m_Timer;
private Mobile m_Caster;
public override bool BlocksFit{ get{ return true; } }
public InternalItem( Point3D loc, Map map, TimeSpan duration, int itemID, Mobile caster ) : base( itemID )
{
Visible = false;
Movable = false;
Light = LightType.Circle300;
MoveToWorld( loc, map );
m_Caster = caster;
if ( caster.InLOS( this ) )
Visible = true;
else
Delete();
if ( Deleted )
return;
m_Timer = new InternalTimer( this, duration );
m_Timer.Start();
}
public InternalItem( Serial serial ) : base( serial )
{
m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( 5.0 ) );
m_Timer.Start();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override 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 )
{
Priority = TimerPriority.OneSecond;
m_Item = item;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
private class InternalTarget : Target
{
private EnergyFieldSpell m_Owner;
public InternalTarget( EnergyFieldSpell 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();
}
}
}
}

View file

@ -0,0 +1,85 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Seventh
{
public class FlameStrikeSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Flame Strike", "Kal Vas Flam",
245,
9042,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public FlameStrikeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
double damage = Utility.Random( 27, 22 );
if ( CheckResisted( m ) )
{
damage *= 0.6;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
damage *= GetDamageScalar( m );
m.FixedParticles( 0x3709, 10, 30, 5052, EffectLayer.LeftFoot );
m.PlaySound( 0x208 );
SpellHelper.Damage( this, m, damage );
}
FinishSequence();
}
private class InternalTarget : Target
{
private FlameStrikeSpell m_Owner;
public InternalTarget( FlameStrikeSpell 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();
}
}
}
}

View file

@ -0,0 +1,192 @@
using System;
using Server.Network;
using Server.Multis;
using Server.Items;
using Server.Targeting;
using Server.Misc;
using Server.Regions;
using Server.Mobiles;
namespace Server.Spells.Seventh
{
public class GateTravelSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Gate Travel", "Vas Rel Por",
263,
9032,
Reagent.BlackPearl,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public GateTravelSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool CheckCast()
{
if ( Server.Engines.Harvest.Fishing.IsOnBoat( Caster ) )
{
Caster.SendMessage( "The waves of the sea are distracting you from casting this spell!" );
Caster.FixedEffect( 0x3735, 6, 30 );
Caster.PlaySound( 0x5C );
return false;
}
else if ( SpellHelper.CheckCombat( Caster ) )
{
Caster.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
return false;
}
return true;
}
private bool GateExistsAt(Map map, Point3D loc )
{
bool _gateFound = false;
IPooledEnumerable eable = map.GetItemsInRange( loc, 0 );
foreach ( Item item in eable )
{
if ( item is Magicgate )
{
_gateFound = true;
break;
}
}
eable.Free();
return _gateFound;
}
public void Effect( Point3D loc, Map map, bool checkMulti )
{
if ( SpellHelper.CheckCombat( Caster ) )
{
Caster.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
}
else if ( !map.CanSpawnMobile( loc.X, loc.Y, loc.Z ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( (checkMulti && SpellHelper.CheckMulti( loc, map )) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( GateExistsAt( Caster.Map, Caster.Location ) )
{
Caster.SendLocalizedMessage( 1071242 ); // There is already a gate there.
}
else if ( CheckSequence() )
{
Caster.SendLocalizedMessage( 501024 ); // You open a magical gate to another location
Effects.PlaySound( Caster.Location, Caster.Map, 0x20E );
InternalItem firstGate = new InternalItem( loc, map );
firstGate.MoveToWorld( Caster.Location, Caster.Map );
Effects.PlaySound( loc, map, 0x20E );
InternalItem secondGate = new InternalItem( Caster.Location, Caster.Map );
secondGate.MoveToWorld( loc, map );
}
FinishSequence();
}
[DispellableField]
private class InternalItem : Magicgate
{
public InternalItem( Point3D target, Map map ) : base( target, map )
{
Map = map;
Dispellable = true;
InternalTimer t = new InternalTimer( this );
t.Start();
}
public InternalItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
Delete();
}
private class InternalTimer : Timer
{
private Item m_Item;
public InternalTimer( Item item ) : base( TimeSpan.FromSeconds( 30.0 ) )
{
Priority = TimerPriority.OneSecond;
m_Item = item;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
private class InternalTarget : Target
{
private GateTravelSpell m_Owner;
public InternalTarget( GateTravelSpell owner ) : base( 12, false, TargetFlags.None )
{
m_Owner = owner;
owner.Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501029 ); // Select Marked item.
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is MagicRune )
{
MagicRune rune = (MagicRune)o;
if ( rune.Marked && rune.Owner != from )
from.SendMessage( "This rune belongs to someone else." );
else if ( rune.Marked )
m_Owner.Effect( rune.Target, rune.TargetMap, true );
else
from.SendLocalizedMessage( 501803 ); // That rune is not yet marked.
}
else
{
from.Send( new MessageLocalized( from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 501030, from.Name, "" ) ); // I can not gate travel from that object.
}
}
protected override void OnNonlocalTarget( Mobile from, object o )
{
}
protected override void OnTargetFinish( Mobile from )
{
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,97 @@
using System;
using Server.Targeting;
using Server.Network;
namespace Server.Spells.Seventh
{
public class ManaVampireSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mana Vampire", "Ort Sanct",
221,
9032,
Reagent.BlackPearl,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public ManaVampireSpell( 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 );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
if ( m.Spell != null )
m.Spell.OnCasterHurt();
m.Paralyzed = false;
int toDrain = 0;
if ( CheckResisted( m ) )
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
else
toDrain = m.Mana;
if ( toDrain > (Caster.ManaMax - Caster.Mana) )
toDrain = Caster.ManaMax - Caster.Mana;
m.Mana -= toDrain;
Caster.Mana += toDrain;
m.FixedParticles( 0x374A, 10, 15, 5054, EffectLayer.Head );
m.PlaySound( 0x1F9 );
HarmfulSpell( m );
}
FinishSequence();
}
public override double GetResistPercent( Mobile target )
{
return 98.0;
}
private class InternalTarget : Target
{
private ManaVampireSpell m_Owner;
public InternalTarget( ManaVampireSpell 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();
}
}
}
}

View file

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using Server.Misc;
using Server.Network;
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
namespace Server.Spells.Seventh
{
public class MassDispelSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mass Dispel", "Vas An Ort",
263,
9002,
Reagent.Garlic,
Reagent.MandrakeRoot,
Reagent.BlackPearl,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public MassDispelSpell( 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 );
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ); // PASSIVE CHECK
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), (8+(int)(Caster.Skills[SkillName.Concentration].Value/20)) );
foreach ( Mobile m in eable )
if ( m is BaseCreature && (m as BaseCreature).IsDispellable && Caster.CanBeHarmful( m, false ) )
targets.Add( m );
eable.Free();
}
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
BaseCreature bc = m as BaseCreature;
if ( bc == null )
continue;
double dispelChance = (50.0 + ((100 * (Caster.Skills.Magery.Value - bc.DispelDifficulty)) / (bc.DispelFocus*2))) / 100;
if ( dispelChance > Utility.RandomDouble() )
{
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
Effects.PlaySound( m, m.Map, 0x201 );
m.Delete();
}
else
{
Caster.DoHarmful( m );
m.FixedEffect( 0x3779, 10, 20 );
}
}
}
FinishSequence();
}
private class InternalTarget : Target
{
private MassDispelSpell m_Owner;
public InternalTarget( MassDispelSpell 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();
}
}
}
}

View file

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using Server.Network;
using Server.Items;
using Server.Targeting;
namespace Server.Spells.Seventh
{
public class MeteorSwarmSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Meteor Swarm", "Flam Kal Des Ylem",
233,
9042,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public MeteorSwarmSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return true; } }
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 );
if ( p is Item )
p = ((Item)p).GetWorldLocation();
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
{
IPooledEnumerable eable = map.GetMobilesInRange( new Point3D( p ), 2 );
foreach ( Mobile m in eable )
{
if ( Caster != m && SpellHelper.ValidIndirectTarget( Caster, m ) && Caster.CanBeHarmful( m, false ) )
{
targets.Add( m );
}
}
eable.Free();
}
double damage = Utility.Random( 27, 22 );
if ( targets.Count > 0 )
{
Effects.PlaySound( p, Caster.Map, 0x160 );
damage /= targets.Count;
double toDeal;
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
toDeal = damage;
toDeal *= GetDamageScalar( m );
if ( CheckResisted( m ) )
{
damage *= 0.5;
m.SendLocalizedMessage( 501783 ); // You feel yourself resisting magical energy.
}
toDeal *= GetDamageScalar( m );
Caster.DoHarmful( m );
SpellHelper.Damage( this, m, toDeal );
Caster.MovingParticles( m, 0x36D4, 7, 0, false, true, 9501, 1, 0, 0x100 );
}
}
}
FinishSequence();
}
private class InternalTarget : Target
{
private MeteorSwarmSpell m_Owner;
public InternalTarget( MeteorSwarmSpell 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();
}
}
}
}

View file

@ -0,0 +1,178 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Spells;
using Server.Spells.Fifth;
namespace Server.Spells.Seventh
{
public class PolymorphSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Polymorph", "Vas Ylem Rel",
221,
9002,
Reagent.Bloodmoss,
Reagent.SpidersSilk,
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
private int m_NewBody;
public PolymorphSpell( Mobile caster, Item scroll, int body ) : base( caster, scroll, m_Info )
{
m_NewBody = body;
}
public PolymorphSpell( Mobile caster, Item scroll ) : this(caster,scroll,0)
{
}
public override bool CheckCast()
{
if( TransformationSpellHelper.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1061633 ); // You cannot polymorph while in that form.
return false;
}
else if ( DisguiseTimers.IsDisguised( Caster ) )
{
Caster.SendLocalizedMessage( 502167 ); // You cannot polymorph while disguised.
return false;
}
else if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
return false;
}
else if ( m_NewBody == 0 )
{
Gump gump = new PolymorphGump( Caster, Scroll );
Caster.SendGump( gump );
return false;
}
return true;
}
public override void OnCast()
{
if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if( TransformationSpellHelper.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1061633 ); // You cannot polymorph while in that form.
}
else if ( DisguiseTimers.IsDisguised( Caster ) )
{
Caster.SendLocalizedMessage( 502167 ); // You cannot polymorph while disguised.
}
else if ( Caster.BodyMod == 183 || Caster.BodyMod == 184 )
{
Caster.SendLocalizedMessage( 1042512 ); // You cannot polymorph while wearing body paint
}
else if ( !Caster.CanBeginAction( typeof( IncognitoSpell ) ) || Caster.IsBodyMod )
{
DoFizzle();
}
else if ( CheckSequence() )
{
if ( Caster.BeginAction( typeof( PolymorphSpell ) ) )
{
if ( m_NewBody != 0 )
{
if ( !((Body)m_NewBody).IsHuman )
{
Mobiles.IMount mt = Caster.Mount;
if ( mt != null )
mt.Rider = null;
}
Caster.BodyMod = m_NewBody;
if ( m_NewBody == 400 || m_NewBody == 401 )
Caster.HueMod = Utility.RandomSkinHue();
else
Caster.HueMod = 0;
BaseArmor.ValidateMobile( Caster );
BaseClothing.ValidateMobile( Caster );
StopTimer( Caster );
Timer t = new InternalTimer( Caster );
m_Timers[Caster] = t;
t.Start();
}
}
else
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
}
FinishSequence();
}
private static Hashtable m_Timers = new Hashtable();
public static bool StopTimer( Mobile m )
{
Timer t = (Timer)m_Timers[m];
if ( t != null )
{
t.Stop();
m_Timers.Remove( m );
}
return ( t != null );
}
private static void EndPolymorph( Mobile m )
{
if( !m.CanBeginAction( typeof( PolymorphSpell ) ) )
{
m.BodyMod = 0;
m.HueMod = -1;
m.EndAction( typeof( PolymorphSpell ) );
BaseArmor.ValidateMobile( m );
BaseClothing.ValidateMobile( m );
}
}
private class InternalTimer : Timer
{
private Mobile m_Owner;
public InternalTimer( Mobile owner ) : base( TimeSpan.FromSeconds( 0 ) )
{
m_Owner = owner;
int val = (int)owner.Skills[SkillName.Magery].Value;
if ( val > 120 )
val = 120;
Delay = TimeSpan.FromSeconds( val );
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
EndPolymorph( m_Owner );
}
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class AirElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Air Elemental", "Kal Vas Xen Hur",
269,
9010,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public AirElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 2) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
if ( CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( ((2 * Caster.Skills.Magery.Fixed) / 5) + ((2 * Caster.Skills.Concentration.Value) / 5) );
SpellHelper.Summon( new AirElemental(), Caster, 0x217, duration, false, false );
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class EarthElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Earth Elemental", "Kal Vas Xen Ylem",
269,
9020,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public EarthElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 2) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
if ( CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( ((2 * Caster.Skills.Magery.Fixed) / 5) + ((2 * Caster.Skills.Concentration.Value) / 5) );
SpellHelper.Summon( new EarthElemental(), Caster, 0x217, duration, false, false );
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using Server.Network;
using Server.Items;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class EarthquakeSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Earthquake", "In Vas Por",
233,
9012,
false,
Reagent.Bloodmoss,
Reagent.Ginseng,
Reagent.MandrakeRoot,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public EarthquakeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool DelayedDamage{ get{ return true; } }
public override void OnCast()
{
if ( SpellHelper.CheckTown( Caster, Caster ) && CheckSequence() )
{
List<Mobile> targets = new List<Mobile>();
Map map = Caster.Map;
if ( map != null )
foreach ( Mobile m in Caster.GetMobilesInRange( 1 + (int)(Caster.Skills[SkillName.Magery].Value / 15.0) ) )
if ( Caster != m && SpellHelper.ValidIndirectTarget( Caster, m ) && Caster.CanBeHarmful( m, false ) )
targets.Add( m );
Caster.PlaySound( 0x220 );
for ( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
int damage = (m.Hits * 6) / 10;
damage = (int)(damage * GetDamageScalar( m ) );
if ( !m.Player && damage < 10 )
damage = 10;
else if ( damage > 75 )
damage = 75;
Caster.DoHarmful( m );
SpellHelper.Damage( TimeSpan.Zero, m, Caster, damage );
}
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,98 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class EnergyVortexSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Energy Vortex", "Vas Corp Por",
260,
9032,
false,
Reagent.Bloodmoss,
Reagent.BlackPearl,
Reagent.MandrakeRoot,
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public EnergyVortexSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 1) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
Caster.Target = new InternalTarget( this );
}
public void Target( IPoint3D p )
{
Map map = Caster.Map;
SpellHelper.GetSurfaceTop( ref p );
if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) )
{
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
else if ( SpellHelper.CheckTown( p, Caster ) && CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( Utility.Random( 80, 40 ) + (Caster.Skills.Concentration.Value / 5) );
BaseCreature.Summon( new EnergyVortex(), false, Caster, new Point3D( p ), 0x212, duration );
}
FinishSequence();
}
private class InternalTarget : Target
{
private EnergyVortexSpell m_Owner;
public InternalTarget( EnergyVortexSpell 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 OnTargetOutOfLOS( Mobile from, object o )
{
from.SendLocalizedMessage( 501943 ); // Target cannot be seen. Try again.
from.Target = new InternalTarget( m_Owner );
from.Target.BeginTimeout( from, TimeoutTime - DateTime.Now );
m_Owner = null;
}
protected override void OnTargetFinish( Mobile from )
{
if ( m_Owner != null )
m_Owner.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,55 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class FireElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Fire Elemental", "Kal Vas Xen Flam",
269,
9050,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public FireElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 4) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
if ( CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( ((2 * Caster.Skills.Magery.Fixed) / 5) + ((2 * Caster.Skills.Concentration.Value) / 5) );
SpellHelper.Summon( new FireElemental(), Caster, 0x217, duration, false, false );
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,180 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;
using Server.Network;
using Server.Gumps;
using System.Collections;
using System.Collections.Generic;
namespace Server.Spells.Eighth
{
public class ResurrectionSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Resurrection", "An Corp",
245,
9062,
Reagent.Bloodmoss,
Reagent.Garlic,
Reagent.Ginseng
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public ResurrectionSpell( 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 ( !Caster.Alive )
{
Caster.SendLocalizedMessage( 501040 ); // The resurrecter must be alive.
}
else if ( m == Caster && CheckBSequence( m, true ) )
{
ArrayList targets = new ArrayList();
foreach ( Item item in World.Items.Values )
if ( item is LifeCrystal )
{
LifeCrystal myOrb = (LifeCrystal)item;
if ( myOrb.m_Owner == m )
{
targets.Add( item );
}
}
for ( int i = 0; i < targets.Count; ++i )
{
Item item = ( Item )targets[ i ];
item.Delete();
}
m.PlaySound( 0x214 );
m.FixedEffect( 0x376A, 10, 16, 0, 0 );
m.SendMessage( "You conjure yourself a life crystal." );
LifeCrystal crystal = new LifeCrystal();
crystal.m_Owner = m;
m.AddToBackpack( crystal );
}
else if ( m.Alive )
{
Caster.SendLocalizedMessage( 501041 ); // Target is not dead.
}
else if ( !Caster.InRange( m, 1 ) )
{
Caster.SendLocalizedMessage( 501042 ); // Target is not close enough.
}
else if ( !m.Player )
{
Caster.SendLocalizedMessage( 501043 ); // Target is not a being.
}
else if ( m.Map == null || !m.Map.CanFit( m.Location, 16, false, false ) )
{
Caster.SendLocalizedMessage( 501042 ); // Target can not be resurrected at that location.
m.SendLocalizedMessage( 502391 ); // Thou can not be resurrected there!
}
else if ( CheckBSequence( m, true ) )
{
SpellHelper.Turn( Caster, m );
m.PlaySound( 0x214 );
m.FixedEffect( 0x376A, 10, 16 );
m.CloseGump( typeof( ResurrectGump ) );
m.SendGump( new ResurrectGump( m, Caster ) );
}
FinishSequence();
}
private class InternalTarget : Target
{
private ResurrectionSpell m_Owner;
public InternalTarget( ResurrectionSpell owner ) : base( 1, 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();
}
}
}
}
namespace Server.Items
{
public class LifeCrystal : Item
{
public override bool DisplayLootType{ get{ return false; } }
public Mobile m_Owner;
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Owner
{
get { return m_Owner; }
set { m_Owner = value; InvalidateProperties(); }
}
[Constructable]
public LifeCrystal() : base( 0x023F )
{
Name = "life crystal";
LootType = LootType.Blessed;
Movable = false;
Weight = 1.0;
}
public override void OnDoubleClick( Mobile m )
{
m.SendMessage( "Since you are alive, the crystal vanishes!" );
this.Delete();
}
public override void OnDoubleClickDead( Mobile m )
{
m.Resurrect();
m.FixedEffect( 0x376A, 10, 16, 0, 0 );
this.Delete();
}
public LifeCrystal(Serial serial) : base(serial){}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
writer.Write( (Mobile) m_Owner );
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Owner = reader.ReadMobile();
}
}
}

View file

@ -0,0 +1,57 @@
using System;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class SummonDaemonSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Summon Daemon", "Kal Vas Xen Corp",
269,
9050,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public SummonDaemonSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 5) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
if ( CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( ((2 * Caster.Skills.Magery.Fixed) / 5) + ((2 * Caster.Skills.Concentration.Value) / 5) );
SpellHelper.Summon( new Daemon(), Caster, 0x216, duration, false, false );
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.Eighth
{
public class WaterElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Water Elemental", "Kal Vas Xen An Flam",
269,
9070,
false,
Reagent.Bloodmoss,
Reagent.MandrakeRoot,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public WaterElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
public override bool CheckCast()
{
if ( !base.CheckCast() )
return false;
if ( (Caster.Followers + 3) > Caster.FollowersMax )
{
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
return false;
}
return true;
}
public override void OnCast()
{
if ( CheckSequence() )
{
Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 );
TimeSpan duration = TimeSpan.FromSeconds( ((2 * Caster.Skills.Magery.Fixed) / 5) + ((2 * Caster.Skills.Concentration.Value) / 5) );
SpellHelper.Summon( new WaterElemental(), Caster, 0x217, duration, false, false );
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class BagOfReagents : Bag
{
[Constructable]
public BagOfReagents()
{
Weight = 10.0;
}
public override void Open( Mobile from )
{
int amount = 50;
if ( this.Weight > 2.0 )
{
Item i = null;
i = new BlackPearl( amount ); DropItem( i );
i = new Bloodmoss( amount ); DropItem( i );
i = new Garlic( amount ); DropItem( i );
i = new Ginseng( amount ); DropItem( i );
i = new MandrakeRoot( amount ); DropItem( i );
i = new Nightshade( amount ); DropItem( i );
i = new SulfurousAsh( amount ); DropItem( i );
i = new SpidersSilk( amount ); DropItem( i );
this.Weight = 2.0;
}
base.Open( from );
}
public BagOfReagents( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,15 @@
using System;
using Server;
namespace Server.Spells
{
public enum DisturbType
{
Unspecified,
EquipRequest,
UseRequest,
Hurt,
Kill,
NewCast
}
}

View file

@ -0,0 +1,96 @@
using System;
using Server;
namespace Server.Spells
{
public class Initializer
{
public static void Initialize()
{
// 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 ) );
}
public static void Register( int spellID, Type type )
{
SpellRegistry.Register( spellID, type );
}
}
}

View file

@ -0,0 +1,113 @@
using System;
using Server;
using Server.Items;
namespace Server.Spells
{
public abstract class MagerySpell : Spell
{
public MagerySpell( Mobile caster, Item scroll, SpellInfo info )
: base( caster, scroll, info )
{
}
public abstract SpellCircle Circle { get; }
public override bool ConsumeReagents()
{
if( base.ConsumeReagents() )
return true;
if( ArcaneGem.ConsumeCharges( Caster, 1+(int)Circle ) )
return true;
return false;
}
private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0;
public override void GetCastSkills( out double min, out double max )
{
int circle = (int)Circle;
if( Scroll != null )
circle -= 2;
double avg = ChanceLength * circle;
min = avg - ChanceOffset;
max = avg + ChanceOffset;
}
private static int[] m_ManaTable = new int[] { 4, 6, 9, 11, 14, 20, 40, 50 };
public override int GetMana()
{
if( Scroll is BaseWand )
return 0;
return m_ManaTable[(int)Circle];
}
public override double GetResistSkill( Mobile m )
{
int maxSkill = (1 + (int)Circle) * 10;
maxSkill += (1 + ((int)Circle / 6)) * 25;
if( m.Skills[SkillName.MagicResist].Value < maxSkill )
m.CheckSkill( SkillName.MagicResist, 0.0, m.Skills[SkillName.MagicResist].Cap );
return m.Skills[SkillName.MagicResist].Value;
}
public virtual bool CheckResisted( Mobile target )
{
double n = GetResistPercent( target );
n /= 100.0;
if( n <= 0.0 )
return false;
if( n >= 1.0 )
return true;
int maxSkill = (1 + (int)Circle) * 10;
maxSkill += (1 + ((int)Circle / 6)) * 25;
if( target.Skills[SkillName.MagicResist].Value < maxSkill )
target.CheckSkill( SkillName.MagicResist, 0.0, target.Skills[SkillName.MagicResist].Cap );
return (n >= Utility.RandomDouble());
}
public virtual double GetResistPercentForCircle( Mobile target, SpellCircle circle )
{
double firstPercent = target.Skills[SkillName.MagicResist].Value / 5.0;
double secondPercent = target.Skills[SkillName.MagicResist].Value - (((Caster.Skills[CastSkill].Value - 20.0) / 5.0) + (1 + (int)circle) * 5.0);
return (firstPercent > secondPercent ? firstPercent : secondPercent) / 2.0; // Seems should be about half of what stratics says.
}
public virtual double GetResistPercent( Mobile target )
{
return GetResistPercentForCircle( target, Circle );
}
public override TimeSpan GetCastDelay()
{
if( Scroll is BaseWand )
return TimeSpan.Zero;
return TimeSpan.FromSeconds( 0.5 + (0.25 * (int)Circle) );
}
public override TimeSpan CastDelayBase
{
get
{
return TimeSpan.FromSeconds( (3 + (int)Circle) * CastDelaySecondsPerTick );
}
}
}
}

View file

@ -0,0 +1,732 @@
using System;
using Server.Items;
using Server.Misc;
using Server.Network;
using Server.Targeting;
using Server.Mobiles;
using Server.Spells.Second;
using System.Collections.Generic;
namespace Server.Spells
{
public abstract class Spell : ISpell
{
private Mobile m_Caster;
private Item m_Scroll;
private SpellInfo m_Info;
private SpellState m_State;
private DateTime m_StartCastTime;
public SpellState State{ get{ return m_State; } set{ m_State = value; } }
public Mobile Caster{ get{ return m_Caster; } }
public SpellInfo Info{ get{ return m_Info; } }
public string Name{ get{ return m_Info.Name; } }
public string Mantra{ get{ return m_Info.Mantra; } }
public Type[] Reagents{ get{ return m_Info.Reagents; } }
public Item Scroll{ get{ return m_Scroll; } }
public DateTime StartCastTime { get { return m_StartCastTime; } }
private static TimeSpan NextSpellDelay = TimeSpan.FromSeconds( 0.75 );
private static TimeSpan AnimateDelay = TimeSpan.FromSeconds( 1.5 );
public virtual SkillName CastSkill{ get{ return SkillName.Magery; } }
public virtual SkillName DamageSkill{ get{ return SkillName.Concentration; } }
public virtual bool RevealOnCast{ get{ return true; } }
public virtual bool ClearHandsOnCast{ get{ return Server.Misc.Settings.CastSpellsHoldingThings(); } }
public virtual bool ShowHandMovement{ get{ return true; } }
public virtual bool DelayedDamage{ get{ return false; } }
public virtual bool DelayedDamageStacking { get { return true; } }
//In reality, it's ANY delayed Damage spell that can't stack, but, only
//Expo & Magic Arrow have enough delay and a short enough cast time to bring up
//the possibility of stacking 'em. Note that a MA & an Explosion will stack, but
//of course, two MA's won't.
private static Dictionary<Type, DelayedDamageContextWrapper> m_ContextTable = new Dictionary<Type, DelayedDamageContextWrapper>();
private class DelayedDamageContextWrapper
{
private Dictionary<Mobile, Timer> m_Contexts = new Dictionary<Mobile, Timer>();
public void Add( Mobile m, Timer t )
{
Timer oldTimer;
if( m_Contexts.TryGetValue( m, out oldTimer ) )
{
oldTimer.Stop();
m_Contexts.Remove( m );
}
m_Contexts.Add( m, t );
}
public void Remove( Mobile m )
{
m_Contexts.Remove( m );
}
}
public void StartDelayedDamageContext( Mobile m, Timer t )
{
if( DelayedDamageStacking )
return; //Sanity
DelayedDamageContextWrapper contexts;
if( !m_ContextTable.TryGetValue( GetType(), out contexts ) )
{
contexts = new DelayedDamageContextWrapper();
m_ContextTable.Add( GetType(), contexts );
}
contexts.Add( m, t );
}
public void RemoveDelayedDamageContext( Mobile m )
{
DelayedDamageContextWrapper contexts;
if( !m_ContextTable.TryGetValue( GetType(), out contexts ) )
return;
contexts.Remove( m );
}
public void HarmfulSpell( Mobile m )
{
if ( m is BaseCreature )
((BaseCreature)m).OnHarmfulSpell( m_Caster );
}
public Spell( Mobile caster, Item scroll, SpellInfo info )
{
m_Caster = caster;
m_Scroll = scroll;
m_Info = info;
}
public virtual bool IsCasting{ get{ return m_State == SpellState.Casting; } }
public virtual void OnCasterHurt()
{
//Confirm: Monsters and pets cannot be disturbed.
if ( !Caster.Player )
return;
if ( CheckHandToHand( Caster ) )
return;
if ( IsCasting )
{
object o = ProtectionSpell.Registry[m_Caster];
bool disturb = true;
if ( o != null && o is double )
{
if ( ((double)o) > Utility.RandomDouble()*100.0 )
disturb = false;
}
if ( disturb )
Disturb( DisturbType.Hurt, false, true );
}
}
public virtual void OnCasterKilled()
{
Disturb( DisturbType.Kill );
}
public virtual void OnConnectionChanged()
{
FinishSequence();
}
public virtual bool OnCasterMoving( Direction d )
{
if ( IsCasting && BlocksMovement )
{
m_Caster.SendLocalizedMessage( 500111 ); // You are frozen and can not move.
return false;
}
return true;
}
public virtual bool OnCasterEquiping( Item item )
{
if ( IsCasting )
Disturb( DisturbType.EquipRequest );
return true;
}
public virtual bool OnCasterUsingObject( object o )
{
if ( m_State == SpellState.Sequencing )
Disturb( DisturbType.UseRequest );
return true;
}
public virtual bool OnCastInTown( Region r )
{
return m_Info.AllowTown;
}
public virtual bool ConsumeReagents()
{
if ( m_Scroll != null || !m_Caster.Player )
return true;
Container pack = m_Caster.Backpack;
if ( pack == null )
return false;
if ( pack.ConsumeTotal( m_Info.Reagents, m_Info.Amounts ) == -1 )
return true;
return false;
}
public virtual int GetDamageFixed( Mobile m )
{
return m.Skills[DamageSkill].Fixed;
}
public virtual double GetDamageSkill( Mobile m )
{
return m.Skills[DamageSkill].Value;
}
public virtual double GetResistSkill( Mobile m )
{
return m.Skills[SkillName.MagicResist].Value;
}
public virtual bool CheckHandToHand( Mobile m )
{
return m.CheckSkill( SkillName.HandToHand, 0.0, 100.0 );
}
public virtual double GetDamageScalar( Mobile target )
{
double scalar = 1.0;
double casterEI = m_Caster.Skills[DamageSkill].Value;
double targetRS = target.Skills[SkillName.MagicResist].Value;
if( casterEI > targetRS )
scalar = (1.0 + ((casterEI - targetRS) / 500.0));
else
scalar = (1.0 + ((casterEI - targetRS) / 200.0));
// magery damage bonus, -25% at 0 skill, +0% at 100 skill, +5% at 120 skill
scalar += (m_Caster.Skills[CastSkill].Value - 100.0) / 400.0;
if ( m_Caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ) )
scalar *= ( m_Caster.Skills[SkillName.Concentration].Value / 50 );
if ( target is BaseCreature )
((BaseCreature)target).AlterDamageScalarFrom( m_Caster, ref scalar );
if ( m_Caster is BaseCreature )
((BaseCreature)m_Caster).AlterDamageScalarTo( target, ref scalar );
target.Region.SpellDamageScalar( m_Caster, target, ref scalar );
return scalar;
}
public virtual double GetSlayerDamageScalar( Mobile defender )
{
Spellbook atkBook = Spellbook.FindEquippedSpellbook( m_Caster );
double scalar = 1.0;
if( atkBook != null )
{
SlayerEntry atkSlayer = SlayerGroup.GetEntryByName( atkBook.Slayer );
SlayerEntry atkSlayer2 = SlayerGroup.GetEntryByName( atkBook.Slayer2 );
if( atkSlayer != null && atkSlayer.Slays( defender ) || atkSlayer2 != null && atkSlayer2.Slays( defender ) )
{
defender.FixedEffect( 0x37B9, 10, 5 ); //TODO: Confirm this displays on OSIs
scalar = 2.0;
}
if( scalar != 1.0 )
return scalar;
}
return scalar;
}
public virtual void DoFizzle()
{
m_Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 502632 ); // The spell fizzles.
if ( m_Caster.Player )
{
m_Caster.FixedEffect( 0x3735, 6, 30 );
m_Caster.PlaySound( 0x5C );
}
}
private CastTimer m_CastTimer;
private AnimTimer m_AnimTimer;
public void Disturb( DisturbType type )
{
Disturb( type, true, false );
}
public virtual bool CheckDisturb( DisturbType type, bool firstCircle, bool resistable )
{
if ( resistable && m_Scroll is BaseWand )
return false;
return true;
}
public void Disturb( DisturbType type, bool firstCircle, bool resistable )
{
if ( !CheckDisturb( type, firstCircle, resistable ) )
return;
if ( m_State == SpellState.Casting )
{
if( !firstCircle && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First )
return;
if ( CheckHandToHand( m_Caster ) )
return;
m_State = SpellState.None;
m_Caster.Spell = null;
OnDisturb( type, true );
if ( m_CastTimer != null )
m_CastTimer.Stop();
if ( m_AnimTimer != null )
m_AnimTimer.Stop();
m_Caster.NextSpellTime = DateTime.Now + GetDisturbRecovery();
}
else if ( m_State == SpellState.Sequencing )
{
if( !firstCircle && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First )
return;
if ( CheckHandToHand( m_Caster ) )
return;
m_State = SpellState.None;
m_Caster.Spell = null;
OnDisturb( type, false );
Targeting.Target.Cancel( m_Caster );
}
}
public virtual void DoHurtFizzle()
{
m_Caster.FixedEffect( 0x3735, 6, 30 );
m_Caster.PlaySound( 0x5C );
}
public virtual void OnDisturb( DisturbType type, bool message )
{
if ( message )
m_Caster.SendLocalizedMessage( 500641 ); // Your concentration is disturbed, thus ruining thy spell.
}
public virtual bool CheckCast()
{
return true;
}
public virtual void SayMantra()
{
if ( m_Scroll is BaseWand )
return;
if ( m_Info.Mantra != null && m_Info.Mantra.Length > 0 && m_Caster.Player )
m_Caster.PublicOverheadMessage( MessageType.Spell, m_Caster.SpeechHue, true, m_Info.Mantra, false );
}
public virtual bool BlocksMovement{ get{ return true; } }
public virtual bool CheckNextSpellTime{ get{ return !(m_Scroll is BaseWand); } }
public bool Cast()
{
m_StartCastTime = DateTime.Now;
if ( !m_Caster.CheckAlive() )
{
return false;
}
else if ( m_Caster.Spell != null && m_Caster.Spell.IsCasting )
{
m_Caster.SendLocalizedMessage( 502642 ); // You are already casting a spell.
}
else if ( !(m_Scroll is BaseWand) && (m_Caster.Paralyzed || m_Caster.Frozen) )
{
m_Caster.SendLocalizedMessage( 502643 ); // You can not cast a spell while frozen.
}
else if ( CheckNextSpellTime && DateTime.Now < m_Caster.NextSpellTime )
{
m_Caster.SendLocalizedMessage( 502644 ); // You have not yet recovered from casting a spell.
}
else if ( m_Caster is PlayerMobile && ( (PlayerMobile) m_Caster ).PeacedUntil > DateTime.Now )
{
m_Caster.SendLocalizedMessage( 1072060 ); // You cannot cast a spell while calmed.
}
else if ( m_Caster.Mana >= ScaleMana( GetMana() ) )
{
if ( m_Caster.Spell == null && m_Caster.CheckSpellCast( this ) && CheckCast() && m_Caster.Region.OnBeginSpellCast( m_Caster, this ) )
{
m_State = SpellState.Casting;
m_Caster.Spell = this;
if ( RevealOnCast )
m_Caster.RevealingAction();
SayMantra();
TimeSpan castDelay = this.GetCastDelay();
if ( ShowHandMovement && m_Caster.Body.IsHuman )
{
int count = (int)Math.Ceiling( castDelay.TotalSeconds / AnimateDelay.TotalSeconds );
if ( count != 0 )
{
m_AnimTimer = new AnimTimer( this, count );
m_AnimTimer.Start();
}
if ( m_Info.LeftHandEffect > 0 )
Caster.FixedParticles( 0, 10, 5, m_Info.LeftHandEffect, EffectLayer.LeftHand );
if ( m_Info.RightHandEffect > 0 )
Caster.FixedParticles( 0, 10, 5, m_Info.RightHandEffect, EffectLayer.RightHand );
}
if ( ClearHandsOnCast )
m_Caster.ClearHands();
m_CastTimer = new CastTimer( this, castDelay );
m_CastTimer.Start();
OnBeginCast();
return true;
}
else
{
return false;
}
}
else
{
m_Caster.LocalOverheadMessage( MessageType.Regular, 0x22, 502625 ); // Insufficient mana
}
return false;
}
public abstract void OnCast();
public virtual void OnBeginCast()
{
}
public virtual void GetCastSkills( out double min, out double max )
{
min = max = 0; //Intended but not required for overriding.
}
public virtual bool CheckFizzle()
{
if ( m_Scroll is BaseWand )
return true;
double minSkill, maxSkill;
GetCastSkills( out minSkill, out maxSkill );
if ( DamageSkill != CastSkill )
Caster.CheckSkill( DamageSkill, 0.0, Caster.Skills[ DamageSkill ].Cap );
return Caster.CheckSkill( CastSkill, minSkill, maxSkill );
}
public abstract int GetMana();
public virtual int ScaleMana( int mana )
{
double scalar = 1.0;
// Lower Mana Needed for Concentration is capped at 50%
int lmc = (int)(m_Caster.Skills[SkillName.Concentration].Value/2);
if ( lmc > 50 )
lmc = 50;
scalar -= (double)lmc / 100;
return (int)(mana * scalar);
}
public virtual TimeSpan GetDisturbRecovery()
{
double delay = 1.0 - Math.Sqrt( (DateTime.Now - m_StartCastTime).TotalSeconds / GetCastDelay().TotalSeconds );
if ( delay < 0.2 )
delay = 0.2;
return TimeSpan.FromSeconds( delay );
}
public virtual int CastRecoveryBase{ get{ return 6; } }
public virtual int CastRecoveryFastScalar{ get{ return 1; } }
public virtual int CastRecoveryPerSecond{ get{ return 4; } }
public virtual int CastRecoveryMinimum{ get{ return 0; } }
public virtual TimeSpan GetCastRecovery()
{
int fcr = 0;
if ( m_Caster.CheckSkill( SkillName.HandToHand, 0.0, 100.0 ) )
{
fcr = (int)(m_Caster.Skills[SkillName.HandToHand].Value / 20);
}
int fcrDelay = -(CastRecoveryFastScalar * fcr);
int delay = CastRecoveryBase + fcrDelay;
if ( delay < CastRecoveryMinimum )
delay = CastRecoveryMinimum;
return TimeSpan.FromSeconds( (double)delay / CastRecoveryPerSecond );
}
public abstract TimeSpan CastDelayBase { get; }
public virtual double CastDelayFastScalar { get { return 1; } }
public virtual double CastDelaySecondsPerTick { get { return 0.25; } }
public virtual TimeSpan CastDelayMinimum { get { return TimeSpan.FromSeconds( 0.25 ); } }
public virtual TimeSpan GetCastDelay()
{
if ( m_Scroll is BaseWand )
return TimeSpan.Zero;
// Faster casting cap of 2 (if not using the protection spell)
// Faster casting cap of 0 (if using the protection spell)
int fc = 0;
if ( m_Caster.CheckSkill( SkillName.HandToHand, 0.0, 100.0 ) )
{
if ( m_Caster.Skills[SkillName.HandToHand].Value > 50.0 )
fc = 1;
else
fc = 2;
}
if ( ProtectionSpell.Registry.Contains( m_Caster ) )
fc -= 2;
TimeSpan baseDelay = CastDelayBase;
TimeSpan fcDelay = TimeSpan.FromSeconds( -(CastDelayFastScalar * fc * CastDelaySecondsPerTick) );
//int delay = CastDelayBase + circleDelay + fcDelay;
TimeSpan delay = baseDelay + fcDelay;
if ( delay < CastDelayMinimum )
delay = CastDelayMinimum;
//return TimeSpan.FromSeconds( (double)delay / CastDelayPerSecond );
return delay;
}
public virtual void FinishSequence()
{
m_State = SpellState.None;
if ( m_Caster.Spell == this )
m_Caster.Spell = null;
}
public virtual bool CheckSequence()
{
int mana = ScaleMana( GetMana() );
if ( m_Caster.Deleted || !m_Caster.Alive || m_Caster.Spell != this || m_State != SpellState.Sequencing )
{
DoFizzle();
}
else if ( m_Scroll != null && (m_Scroll.Amount <= 0 || m_Scroll.Deleted || m_Scroll.RootParent != m_Caster || (m_Scroll is BaseWand && (((BaseWand)m_Scroll).Uses <= 0 || m_Scroll.Parent != m_Caster))) )
{
DoFizzle();
}
else if ( !ConsumeReagents() )
{
m_Caster.LocalOverheadMessage( MessageType.Regular, 0x22, 502630 ); // More reagents are needed for this spell.
}
else if ( m_Caster.Mana < mana )
{
m_Caster.LocalOverheadMessage( MessageType.Regular, 0x22, 502625 ); // Insufficient mana for this spell.
}
else if ( m_Caster is PlayerMobile && ((PlayerMobile) m_Caster).PeacedUntil > DateTime.Now )
{
m_Caster.SendLocalizedMessage( 1072060 ); // You cannot cast a spell while calmed.
DoFizzle();
}
else if ( CheckFizzle() )
{
m_Caster.Mana -= mana;
if ( m_Scroll is SpellScroll )
m_Scroll.Consume();
else if ( m_Scroll is BaseWand )
((BaseWand)m_Scroll).ConsumeCharge( m_Caster );
if ( m_Scroll is BaseWand )
{
bool m = m_Scroll.Movable;
m_Scroll.Movable = false;
if ( ClearHandsOnCast )
m_Caster.ClearHands();
m_Scroll.Movable = m;
}
else
{
if ( ClearHandsOnCast )
m_Caster.ClearHands();
}
return true;
}
else
{
DoFizzle();
}
return false;
}
public bool CheckBSequence( Mobile target )
{
return CheckBSequence( target, false );
}
public bool CheckBSequence( Mobile target, bool allowDead )
{
if ( !target.Alive && !allowDead )
{
m_Caster.SendLocalizedMessage( 501857 ); // This spell won't work on that!
return false;
}
else if ( Caster.CanBeBeneficial( target, true, allowDead ) && CheckSequence() )
{
Caster.DoBeneficial( target );
return true;
}
else
{
return false;
}
}
public bool CheckHSequence( Mobile target )
{
if ( !target.Alive )
{
m_Caster.SendLocalizedMessage( 501857 ); // This spell won't work on that!
return false;
}
else if ( Caster.CanBeHarmful( target ) && CheckSequence() )
{
Caster.DoHarmful( target );
return true;
}
else
{
return false;
}
}
private class AnimTimer : Timer
{
private Spell m_Spell;
public AnimTimer( Spell spell, int count ) : base( TimeSpan.Zero, AnimateDelay, count )
{
m_Spell = spell;
Priority = TimerPriority.FiftyMS;
}
protected override void OnTick()
{
if ( m_Spell.State != SpellState.Casting || m_Spell.m_Caster.Spell != m_Spell )
{
Stop();
return;
}
if ( !m_Spell.Caster.Mounted && m_Spell.Caster.Body.IsHuman && m_Spell.m_Info.Action >= 0 )
m_Spell.Caster.Animate( m_Spell.m_Info.Action, 7, 1, true, false, 0 );
if ( !Running )
m_Spell.m_AnimTimer = null;
}
}
private class CastTimer : Timer
{
private Spell m_Spell;
public CastTimer( Spell spell, TimeSpan castDelay ) : base( castDelay )
{
m_Spell = spell;
Priority = TimerPriority.TwentyFiveMS;
}
protected override void OnTick()
{
if ( m_Spell.m_State == SpellState.Casting && m_Spell.m_Caster.Spell == m_Spell )
{
m_Spell.m_State = SpellState.Sequencing;
m_Spell.m_CastTimer = null;
m_Spell.m_Caster.OnSpellCast( m_Spell );
m_Spell.m_Caster.Region.OnSpellCast( m_Spell.m_Caster, m_Spell );
m_Spell.m_Caster.NextSpellTime = DateTime.Now + m_Spell.GetCastRecovery();// Spell.NextSpellDelay;
Target originalTarget = m_Spell.m_Caster.Target;
m_Spell.OnCast();
if ( m_Spell.m_Caster.Player && m_Spell.m_Caster.Target != originalTarget && m_Spell.Caster.Target != null )
m_Spell.m_Caster.Target.BeginTimeout( m_Spell.m_Caster, TimeSpan.FromSeconds( 30.0 ) );
m_Spell.m_CastTimer = null;
}
}
}
}
}

View file

@ -0,0 +1,16 @@
using System;
namespace Server.Spells
{
public enum SpellCircle
{
First,
Second,
Third,
Fourth,
Fifth,
Sixth,
Seventh,
Eighth
}
}

View file

@ -0,0 +1,991 @@
using System;
using Server;
using Server.Items;
using Server.Guilds;
using Server.Multis;
using Server.Regions;
using Server.Mobiles;
using Server.Targeting;
using Server.Engines.PartySystem;
using Server.Misc;
using System.Collections.Generic;
using Server.Spells.Seventh;
using Server.Spells.Fifth;
namespace Server
{
public class DefensiveSpell
{
public static void Nullify( Mobile from )
{
if( !from.CanBeginAction( typeof( DefensiveSpell ) ) )
new InternalTimer( from ).Start();
}
private class InternalTimer : Timer
{
private Mobile m_Mobile;
public InternalTimer( Mobile m )
: base( TimeSpan.FromMinutes( 1.0 ) )
{
m_Mobile = m;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
m_Mobile.EndAction( typeof( DefensiveSpell ) );
}
}
}
}
namespace Server.Spells
{
public enum TravelCheckType
{
RecallFrom,
RecallTo,
GateFrom,
GateTo,
Mark,
TeleportFrom,
TeleportTo
}
public class SpellHelper
{
private static TimeSpan OldDamageDelay = TimeSpan.FromSeconds( 0.5 );
public static TimeSpan GetDamageDelayForSpell( Spell sp )
{
if( !sp.DelayedDamage )
return TimeSpan.Zero;
return (OldDamageDelay);
}
public static bool CheckMulti( Point3D p, Map map )
{
return CheckMulti( p, map, true, 0);
}
public static bool CheckMulti(Point3D p, Map map, bool houses)
{
return CheckMulti(p, map, houses, 0);
}
public static bool CheckMulti( Point3D p, Map map, bool houses, int housingrange )
{
if( map == null || map == Map.Internal )
return false;
Sector sector = map.GetSector( p.X, p.Y );
for( int i = 0; i < sector.Multis.Count; ++i )
{
BaseMulti multi = sector.Multis[i];
if( multi is BaseHouse )
{
BaseHouse bh = (BaseHouse)multi;
if( ( houses && bh.IsInside( p, 16 ) ) || ( housingrange > 0 && bh.InRange( p, housingrange ) ) )
return true;
}
else if( multi.Contains( p ))
{
return true;
}
}
return false;
}
public static void Turn( Mobile from, object to )
{
IPoint3D target = to as IPoint3D;
if( target == null )
return;
if( target is Item )
{
Item item = (Item)target;
if( item.RootParent != from )
from.Direction = from.GetDirectionTo( item.GetWorldLocation() );
}
else if( from != target )
{
from.Direction = from.GetDirectionTo( target );
}
}
private static TimeSpan CombatHeatDelay = TimeSpan.FromSeconds( 30.0 );
private static bool RestrictTravelCombat = true;
public static bool CheckCombat( Mobile m )
{
if( !RestrictTravelCombat )
return false;
for( int i = 0; i < m.Aggressed.Count; ++i )
{
AggressorInfo info = m.Aggressed[i];
if( info.Defender.Player && (DateTime.Now - info.LastCombatTime) < CombatHeatDelay )
return true;
}
return false;
}
public static bool AdjustField( ref Point3D p, Map map, int height, bool mobsBlock )
{
if( map == null )
return false;
for( int offset = 0; offset < 10; ++offset )
{
Point3D loc = new Point3D( p.X, p.Y, p.Z - offset );
if( map.CanFit( loc, height, true, mobsBlock ) )
{
p = loc;
return true;
}
}
return false;
}
public static bool CanRevealCaster( Mobile m )
{
if ( m is BaseCreature )
{
BaseCreature c = (BaseCreature)m;
if ( !c.Controlled )
return true;
}
return false;
}
public static void GetSurfaceTop( ref IPoint3D p )
{
if( p is Item )
{
p = ((Item)p).GetSurfaceTop();
}
else if( p is StaticTarget )
{
StaticTarget t = (StaticTarget)p;
int z = t.Z;
if( (t.Flags & TileFlag.Surface) == 0 )
z -= TileData.ItemTable[t.ItemID & TileData.MaxItemValue].CalcHeight;
p = new Point3D( t.X, t.Y, z );
}
}
public static bool AddStatOffset( Mobile m, StatType type, int offset, TimeSpan duration )
{
if( offset > 0 )
return AddStatBonus( m, m, type, offset, duration );
else if( offset < 0 )
return AddStatCurse( m, m, type, -offset, duration );
return true;
}
public static bool AddStatBonus( Mobile caster, Mobile target, StatType type )
{
return AddStatBonus( caster, target, type, GetOffset( caster, target, type, false ), GetDuration( caster, target ) );
}
public static bool AddStatBonus( Mobile caster, Mobile target, StatType type, int bonus, TimeSpan duration )
{
int offset = bonus;
string name = String.Format( "[Magic] {0} Offset", type );
StatMod mod = target.GetStatMod( name );
if( mod != null && mod.Offset < 0 )
{
target.AddStatMod( new StatMod( type, name, mod.Offset + offset, duration ) );
return true;
}
else if( mod == null || mod.Offset < offset )
{
target.AddStatMod( new StatMod( type, name, offset, duration ) );
return true;
}
return false;
}
public static bool AddStatCurse( Mobile caster, Mobile target, StatType type )
{
return AddStatCurse( caster, target, type, GetOffset( caster, target, type, true ), GetDuration( caster, target ) );
}
public static bool AddStatCurse( Mobile caster, Mobile target, StatType type, int curse, TimeSpan duration )
{
int offset = -curse;
string name = String.Format( "[Magic] {0} Offset", type );
StatMod mod = target.GetStatMod( name );
if( mod != null && mod.Offset > 0 )
{
target.AddStatMod( new StatMod( type, name, mod.Offset + offset, duration ) );
return true;
}
else if( mod == null || mod.Offset > offset )
{
target.AddStatMod( new StatMod( type, name, offset, duration ) );
return true;
}
return false;
}
public static TimeSpan GetDuration( Mobile caster, Mobile target )
{
double time = 0.0;
if ( caster.CheckSkill( SkillName.Concentration, 0.0, 100.0 ) )
time = caster.Skills[SkillName.Concentration].Value / 2;
return TimeSpan.FromSeconds( time + (caster.Skills[SkillName.Magery].Value * 1.2) );
}
private static bool m_DisableSkillCheck;
public static bool DisableSkillCheck
{
get { return m_DisableSkillCheck; }
set { m_DisableSkillCheck = value; }
}
public static double GetOffsetScalar( Mobile caster, Mobile target, bool curse )
{
double percent;
if( curse )
percent = 8 + (caster.Skills.Concentration.Fixed / 100) - (target.Skills.MagicResist.Fixed / 100);
else
percent = 1 + (caster.Skills.Concentration.Fixed / 100);
percent *= 0.01;
if( percent < 0 )
percent = 0;
return percent;
}
public static int GetOffset( Mobile caster, Mobile target, StatType type, bool curse )
{
return 1 + (int)(caster.Skills[SkillName.Magery].Value * 0.1);
}
public static Guild GetGuildFor( Mobile m )
{
Guild g = m.Guild as Guild;
if( g == null && m is BaseCreature )
{
BaseCreature c = (BaseCreature)m;
m = c.ControlMaster;
if( m != null )
g = m.Guild as Guild;
if( g == null )
{
m = c.SummonMaster;
if( m != null )
g = m.Guild as Guild;
}
}
return g;
}
public static bool ValidIndirectTarget( Mobile from, Mobile to )
{
if( from == to )
return true;
if( to.Hidden && to.AccessLevel > from.AccessLevel )
return false;
Guild fromGuild = GetGuildFor( from );
Guild toGuild = GetGuildFor( to );
if( fromGuild != null && toGuild != null && (fromGuild == toGuild || fromGuild.IsAlly( toGuild )) )
return false;
Party p = Party.Get( from );
if( p != null && p.Contains( to ) )
return false;
if( to is BaseCreature )
{
BaseCreature c = (BaseCreature)to;
if( c.Controlled || c.Summoned )
{
if( c.ControlMaster == from || c.SummonMaster == from )
return false;
if( p != null && (p.Contains( c.ControlMaster ) || p.Contains( c.SummonMaster )) )
return false;
}
}
if( from is BaseCreature )
{
BaseCreature c = (BaseCreature)from;
if( c.Controlled || c.Summoned )
{
if( c.ControlMaster == to || c.SummonMaster == to )
return false;
p = Party.Get( to );
if( p != null && (p.Contains( c.ControlMaster ) || p.Contains( c.SummonMaster )) )
return false;
}
}
if( to is BaseCreature && !((BaseCreature)to).Controlled && ((BaseCreature)to).InitialInnocent )
return true;
int noto = Notoriety.Compute( from, to );
return (noto != Notoriety.Innocent || from.Kills >= 5);
}
private static int[] m_Offsets = new int[]
{
-1, -1,
-1, 0,
-1, 1,
0, -1,
0, 1,
1, -1,
1, 0,
1, 1
};
public static void Summon( BaseCreature creature, Mobile caster, int sound, TimeSpan duration, bool scaleDuration, bool scaleStats )
{
Map map = caster.Map;
if( map == null )
return;
double scale = 1.0 + ((caster.Skills[SkillName.Magery].Value - 100.0) / 200.0);
if( scaleDuration )
duration = TimeSpan.FromSeconds( duration.TotalSeconds * scale );
if( scaleStats )
{
creature.RawStr = (int)(creature.RawStr * scale);
creature.Hits = creature.HitsMax;
creature.RawDex = (int)(creature.RawDex * scale);
creature.Stam = creature.StamMax;
creature.RawInt = (int)(creature.RawInt * scale);
creature.Mana = creature.ManaMax;
}
Point3D p = new Point3D( caster );
if( SpellHelper.FindValidSpawnLocation( map, ref p, true ) )
{
BaseCreature.Summon( creature, caster, p, sound, duration );
return;
}
/*
int offset = Utility.Random( 8 ) * 2;
for( int i = 0; i < m_Offsets.Length; i += 2 )
{
int x = caster.X + m_Offsets[(offset + i) % m_Offsets.Length];
int y = caster.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];
if( map.CanSpawnMobile( x, y, caster.Z ) )
{
BaseCreature.Summon( creature, caster, new Point3D( x, y, caster.Z ), sound, duration );
return;
}
else
{
int z = map.GetAverageZ( x, y );
if( map.CanSpawnMobile( x, y, z ) )
{
BaseCreature.Summon( creature, caster, new Point3D( x, y, z ), sound, duration );
return;
}
}
}
* */
creature.Delete();
caster.SendLocalizedMessage( 501942 ); // That location is blocked.
}
public static bool FindValidSpawnLocation( Map map, ref Point3D p, bool surroundingsOnly )
{
if( map == null ) //sanity
return false;
if( !surroundingsOnly )
{
if( map.CanSpawnMobile( p ) ) //p's fine.
{
p = new Point3D( p );
return true;
}
int z = map.GetAverageZ( p.X, p.Y );
if( map.CanSpawnMobile( p.X, p.Y, z ) )
{
p = new Point3D( p.X, p.Y, z );
return true;
}
}
int offset = Utility.Random( 8 ) * 2;
for( int i = 0; i < m_Offsets.Length; i += 2 )
{
int x = p.X + m_Offsets[(offset + i) % m_Offsets.Length];
int y = p.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];
if( map.CanSpawnMobile( x, y, p.Z ) )
{
p = new Point3D( x, y, p.Z );
return true;
}
else
{
int z = map.GetAverageZ( x, y );
if( map.CanSpawnMobile( x, y, z ) )
{
p = new Point3D( x, y, z );
return true;
}
}
}
return false;
}
public static bool IsInvalid( Map map, Point3D loc )
{
if( map == null || map == Map.Internal )
return true;
int x = loc.X, y = loc.Y;
return (x < 0 || y < 0 || x >= map.Width || y >= map.Height);
}
//towns
public static bool IsTown( IPoint3D loc, Mobile caster )
{
if( loc is Item )
loc = ((Item)loc).GetWorldLocation();
return IsTown( new Point3D( loc ), caster );
}
public static bool IsTown( Point3D loc, Mobile caster )
{
Map map = caster.Map;
if( map == null )
return false;
Region reg = Region.Find( loc, map );
if ( reg is TownRegion )
return true;
else if ( reg is HouseRegion )
return true;
else if ( reg is GardenRegion )
return true;
else if ( reg is ShrineRegion )
return true;
return false;
}
public static bool CheckTown( IPoint3D loc, Mobile caster )
{
if( loc is Item )
loc = ((Item)loc).GetWorldLocation();
return CheckTown( new Point3D( loc ), caster );
}
public static bool CheckTown( Point3D loc, Mobile caster )
{
if( IsTown( loc, caster ) )
{
caster.SendLocalizedMessage( 500946 ); // You cannot cast this in town!
return false;
}
return true;
}
//Misc Spell Blockers
public static bool NoRecall( Point3D loc, Mobile caster )
{
Map map = caster.Map;
if( map == null )
return false;
Region reg = Region.Find( loc, map );
if ( reg is InnRegion )
return true;
else if ( reg is GateRegion )
return true;
else if ( reg is GardenRegion )
return true;
else if ( reg is ShrineRegion )
return true;
else if ( reg is BuildingRegion )
return true;
else if ( reg is CaveRegion )
return true;
else if ( reg is DungeonRegion )
return true;
else if ( reg is GraveRegion )
return true;
else if ( reg is PirateRegion )
return true;
else if ( reg is DangerRegion )
return true;
else if ( reg is HouseRegion )
return true;
return false;
}
//magic reflection
public static void CheckReflect( int circle, Mobile caster, ref Mobile target )
{
CheckReflect( circle, ref caster, ref target );
}
public static void CheckReflect( int circle, ref Mobile caster, ref Mobile target )
{
if( target.MagicDamageAbsorb > 0 )
{
++circle;
target.MagicDamageAbsorb -= circle;
// This order isn't very intuitive, but you have to nullify reflect before target gets switched
bool reflect = (target.MagicDamageAbsorb >= 0);
if( target is BaseCreature )
((BaseCreature)target).CheckReflect( caster, ref reflect );
if( target.MagicDamageAbsorb <= 0 )
{
target.MagicDamageAbsorb = 0;
DefensiveSpell.Nullify( target );
}
if( reflect )
{
target.FixedEffect( 0x37B9, 10, 5 );
Mobile temp = caster;
caster = target;
target = temp;
}
}
else if( target is BaseCreature )
{
bool reflect = false;
((BaseCreature)target).CheckReflect( caster, ref reflect );
if( reflect )
{
target.FixedEffect( 0x37B9, 10, 5 );
Mobile temp = caster;
caster = target;
target = temp;
}
}
}
public static void Damage( Spell spell, Mobile target, double damage )
{
TimeSpan ts = GetDamageDelayForSpell( spell );
Damage( spell, ts, target, spell.Caster, damage );
}
public static void Damage( TimeSpan delay, Mobile target, double damage )
{
Damage( delay, target, null, damage );
}
public static void Damage( TimeSpan delay, Mobile target, Mobile from, double damage )
{
Damage( null, delay, target, from, damage );
}
public static void Damage( Spell spell, TimeSpan delay, Mobile target, Mobile from, double damage )
{
int iDamage = (int)damage;
if( delay == TimeSpan.Zero )
{
if( from is BaseCreature )
((BaseCreature)from).AlterSpellDamageTo( target, ref iDamage );
if( target is BaseCreature )
((BaseCreature)target).AlterSpellDamageFrom( from, ref iDamage );
target.Damage( iDamage, from );
}
else
{
new SpellDamageTimer( spell, target, from, iDamage, delay ).Start();
}
if( target is BaseCreature && from != null && delay == TimeSpan.Zero )
{
BaseCreature c = (BaseCreature) target;
c.OnHarmfulSpell( from );
c.OnDamagedBySpell( from );
}
}
/*
public static void Damage( Spell spell, Mobile target, double damage )
{
TimeSpan ts = GetDamageDelayForSpell( spell );
Damage( spell, ts, target, spell.Caster, damage, DFAlgorithm.Standard );
}
*/
public static void Damage( Spell spell, Mobile target, double damage, DFAlgorithm dfa )
{
TimeSpan ts = GetDamageDelayForSpell( spell );
Damage( spell, ts, target, spell.Caster, damage, dfa );
}
/*
public static void Damage( TimeSpan delay, Mobile target, double damage )
{
Damage( delay, target, null, damage );
}
public static void Damage( TimeSpan delay, Mobile target, Mobile from, double damage )
{
Damage( delay, target, from, damage, DFAlgorithm.Standard );
}
*/
public static void Damage( TimeSpan delay, Mobile target, Mobile from, double damage, DFAlgorithm dfa )
{
Damage( null, delay, target, from, damage, dfa );
}
public static void Damage( Spell spell, TimeSpan delay, Mobile target, Mobile from, double damage, DFAlgorithm dfa )
{
int iDamage = (int)damage;
if( from is BaseCreature )
((BaseCreature)from).AlterSpellDamageTo( target, ref iDamage );
if( target is BaseCreature )
((BaseCreature)target).AlterSpellDamageFrom( from, ref iDamage );
WeightOverloading.DFA = dfa;
int damageGiven = Ultima.Damage( target, from, iDamage );
WeightOverloading.DFA = DFAlgorithm.Standard;
if( target is BaseCreature && from != null && delay == TimeSpan.Zero )
{
BaseCreature c = (BaseCreature) target;
c.OnHarmfulSpell( from );
c.OnDamagedBySpell( from );
}
}
public static void Heal( int amount, Mobile target, Mobile from )
{
Heal( amount, target, from, true );
}
public static void Heal( int amount, Mobile target, Mobile from, bool message )
{
if ( from.CheckSkill( SkillName.Concentration, 0.0, 100.0 ) )
amount = amount + (int)( amount * (from.Skills[SkillName.Concentration].Value / 100) );
if ( target is PlayerMobile ){ amount = (int)(amount * Server.Misc.Settings.HitPoints()); }
target.Heal( amount, from, message );
}
private class SpellDamageTimer : Timer
{
private Mobile m_Target, m_From;
private int m_Damage;
private Spell m_Spell;
public SpellDamageTimer( Spell s, Mobile target, Mobile from, int damage, TimeSpan delay )
: base( delay )
{
m_Target = target;
m_From = from;
m_Damage = damage;
m_Spell = s;
if( m_Spell != null && m_Spell.DelayedDamage && !m_Spell.DelayedDamageStacking )
m_Spell.StartDelayedDamageContext( target, this );
Priority = TimerPriority.TwentyFiveMS;
}
protected override void OnTick()
{
if( m_From is BaseCreature )
((BaseCreature)m_From).AlterSpellDamageTo( m_Target, ref m_Damage );
if( m_Target is BaseCreature )
((BaseCreature)m_Target).AlterSpellDamageFrom( m_From, ref m_Damage );
m_Target.Damage( m_Damage );
if( m_Spell != null )
m_Spell.RemoveDelayedDamageContext( m_Target );
}
}
}
public class TransformationSpellHelper
{
#region Context Stuff
private static Dictionary<Mobile, TransformContext> m_Table = new Dictionary<Mobile, TransformContext>();
public static void AddContext( Mobile m, TransformContext context )
{
m_Table[m] = context;
}
public static void RemoveContext( Mobile m, bool resetGraphics )
{
TransformContext context = GetContext( m );
if( context != null )
RemoveContext( m, context, resetGraphics );
}
public static void RemoveContext( Mobile m, TransformContext context, bool resetGraphics )
{
if( m_Table.ContainsKey( m ) )
{
m_Table.Remove( m );
if( resetGraphics )
{
m.HueMod = -1;
m.BodyMod = 0;
}
context.Timer.Stop();
context.Spell.RemoveEffect( m );
}
}
public static TransformContext GetContext( Mobile m )
{
TransformContext context = null;
m_Table.TryGetValue( m, out context );
return context;
}
public static bool UnderTransformation( Mobile m )
{
return (GetContext( m ) != null);
}
public static bool UnderTransformation( Mobile m, Type type )
{
TransformContext context = GetContext( m );
return (context != null && context.Type == type);
}
#endregion
public static bool CheckCast( Mobile caster, Spell spell )
{
if( !caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
return false;
}
return true;
}
public static bool OnCast( Mobile caster, Spell spell )
{
ITransformationSpell transformSpell = spell as ITransformationSpell;
if( transformSpell == null )
return false;
if( !caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
}
else if ( DisguiseTimers.IsDisguised( caster ) )
{
caster.SendLocalizedMessage( 1061631 ); // You can't do that while disguised.
return false;
}
else if( !caster.CanBeginAction( typeof( IncognitoSpell ) ) || (caster.IsBodyMod && GetContext( caster ) == null) )
{
spell.DoFizzle();
}
else if( spell.CheckSequence() )
{
TransformContext context = GetContext( caster );
Type ourType = spell.GetType();
bool wasTransformed = (context != null);
bool ourTransform = (wasTransformed && context.Type == ourType);
if( wasTransformed )
{
RemoveContext( caster, context, ourTransform );
if( ourTransform )
{
caster.PlaySound( 0xFA );
caster.FixedParticles( 0x3728, 1, 13, 5042, EffectLayer.Waist );
}
}
if( !ourTransform )
{
if( !((Body)transformSpell.Body).IsHuman )
{
Mobiles.IMount mt = caster.Mount;
if( mt != null )
mt.Rider = null;
}
caster.BodyMod = transformSpell.Body;
caster.HueMod = transformSpell.Hue;
transformSpell.DoEffect( caster );
Timer timer = new TransformTimer( caster, transformSpell );
timer.Start();
AddContext( caster, new TransformContext( timer, ourType, transformSpell ) );
return true;
}
}
return false;
}
}
public interface ITransformationSpell
{
int Body { get; }
int Hue { get; }
double TickRate { get; }
void OnTick( Mobile m );
void DoEffect( Mobile m );
void RemoveEffect( Mobile m );
}
public class TransformContext
{
private Timer m_Timer;
private Type m_Type;
private ITransformationSpell m_Spell;
public Timer Timer { get { return m_Timer; } }
public Type Type { get { return m_Type; } }
public ITransformationSpell Spell { get { return m_Spell; } }
public TransformContext( Timer timer, Type type, ITransformationSpell spell )
{
m_Timer = timer;
m_Type = type;
m_Spell = spell;
}
}
public class TransformTimer : Timer
{
private Mobile m_Mobile;
private ITransformationSpell m_Spell;
public TransformTimer( Mobile from, ITransformationSpell spell )
: base( TimeSpan.FromSeconds( spell.TickRate ), TimeSpan.FromSeconds( spell.TickRate ) )
{
m_Mobile = from;
m_Spell = spell;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
if( m_Mobile.Deleted || !m_Mobile.Alive || m_Mobile.Body != m_Spell.Body || m_Mobile.Hue != m_Spell.Hue )
{
TransformationSpellHelper.RemoveContext( m_Mobile, true );
Stop();
}
else
{
m_Spell.OnTick( m_Mobile );
}
}
}
}

View file

@ -0,0 +1,66 @@
using System;
using Server;
namespace Server.Spells
{
public class SpellInfo
{
private string m_Name;
private string m_Mantra;
private Type[] m_Reagents;
private int[] m_Amounts;
private int m_Action;
private bool m_AllowTown;
private int m_LeftHandEffect, m_RightHandEffect;
public SpellInfo( string name, string mantra, params Type[] regs ) : this( name, mantra, 16, 0, 0, true, regs )
{
}
public SpellInfo( string name, string mantra, bool allowTown, params Type[] regs ) : this( name, mantra, 16, 0, 0, allowTown, regs )
{
}
public SpellInfo( string name, string mantra, int action, params Type[] regs ) : this( name, mantra, action, 0, 0, true, regs )
{
}
public SpellInfo( string name, string mantra, int action, bool allowTown, params Type[] regs ) : this( name, mantra, action, 0, 0, allowTown, regs )
{
}
public SpellInfo( string name, string mantra, int action, int handEffect, params Type[] regs ) : this( name, mantra, action, handEffect, handEffect, true, regs )
{
}
public SpellInfo( string name, string mantra, int action, int handEffect, bool allowTown, params Type[] regs ) : this( name, mantra, action, handEffect, handEffect, allowTown, regs )
{
}
public SpellInfo( string name, string mantra, int action, int leftHandEffect, int rightHandEffect, bool allowTown, params Type[] regs )
{
m_Name = name;
m_Mantra = mantra;
m_Action = action;
m_Reagents = regs;
m_AllowTown = allowTown;
m_LeftHandEffect = leftHandEffect;
m_RightHandEffect = rightHandEffect;
m_Amounts = new int[regs.Length];
for ( int i = 0; i < regs.Length; ++i )
m_Amounts[i] = 1;
}
public int Action{ get{ return m_Action; } set{ m_Action = value; } }
public bool AllowTown{ get{ return m_AllowTown; } set{ m_AllowTown = value; } }
public int[] Amounts{ get{ return m_Amounts; } set{ m_Amounts = value; } }
public string Mantra{ get{ return m_Mantra; } set{ m_Mantra = value; } }
public string Name{ get{ return m_Name; } set{ m_Name = value; } }
public Type[] Reagents{ get{ return m_Reagents; } set{ m_Reagents = value; } }
public int LeftHandEffect{ get{ return m_LeftHandEffect; } set{ m_LeftHandEffect = value; } }
public int RightHandEffect{ get{ return m_RightHandEffect; } set{ m_RightHandEffect = value; } }
}
}

View file

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server.Items;
namespace Server.Spells
{
public class SpellRegistry
{
private static Type[] m_Types = new Type[700];
private static int m_Count;
public static Type[] Types
{
get
{
m_Count = -1;
return m_Types;
}
}
//What IS this used for anyways.
public static int Count
{
get
{
if ( m_Count == -1 )
{
m_Count = 0;
for ( int i = 0; i < m_Types.Length; ++i )
if ( m_Types[i] != null )
++m_Count;
}
return m_Count;
}
}
private static Dictionary<Type, Int32> m_IDsFromTypes = new Dictionary<Type, Int32>( m_Types.Length );
public static int GetRegistryNumber( ISpell s )
{
return GetRegistryNumber( s.GetType() );
}
public static int GetRegistryNumber( Type type )
{
if( m_IDsFromTypes.ContainsKey( type ) )
return m_IDsFromTypes[type];
return -1;
}
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;
if( !m_IDsFromTypes.ContainsKey( type ) )
m_IDsFromTypes.Add( type, spellID );
}
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 )
{
m_Params[0] = caster;
m_Params[1] = scroll;
try
{
return (Spell)Activator.CreateInstance( t, m_Params );
}
catch
{
}
}
return null;
}
private static string[] m_CircleNames = new string[]
{
"First",
"Second",
"Third",
"Fourth",
"Fifth",
"Sixth",
"Seventh",
"Eighth"
};
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[i], name ) );
if ( t != null )
{
m_Params[0] = caster;
m_Params[1] = scroll;
try
{
return (Spell)Activator.CreateInstance( t, m_Params );
}
catch
{
}
}
}
return null;
}
}
}

View file

@ -0,0 +1,11 @@
using System;
namespace Server.Spells
{
public enum SpellState
{
None = 0,
Casting = 1, // We are in the process of casting (that is, waiting GetCastTime() and doing animations). Spell casting may be interupted in this state.
Sequencing = 2 // Casting completed, but the full spell sequence isn't. Usually waiting for a target response. Some actions are restricted in this state (using skills for example).
}
}

View file

@ -0,0 +1,24 @@
using System;
using Server.Mobiles;
namespace Server.Spells
{
class UnsummonTimer : Timer
{
private BaseCreature m_Creature;
private Mobile m_Caster;
public UnsummonTimer( Mobile caster, BaseCreature creature, TimeSpan delay ) : base( delay )
{
m_Caster = caster;
m_Creature = creature;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
if ( !m_Creature.Deleted )
m_Creature.Delete();
}
}
}

73
Scripts/Spells/Reagent.cs Normal file
View file

@ -0,0 +1,73 @@
using System;
using Server.Items;
namespace Server.Spells
{
public class Reagent
{
private static Type[] m_Types = new Type[8]
{
typeof( BlackPearl ),
typeof( Bloodmoss ),
typeof( Garlic ),
typeof( Ginseng ),
typeof( MandrakeRoot ),
typeof( Nightshade ),
typeof( SulfurousAsh ),
typeof( SpidersSilk )
};
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; }
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class EarthquakeScroll : SpellScroll
{
[Constructable]
public EarthquakeScroll() : this( 1 )
{
}
[Constructable]
public EarthquakeScroll( int amount ) : base( 56, 0x1F65, amount )
{
}
public EarthquakeScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class EnergyVortexScroll : SpellScroll
{
[Constructable]
public EnergyVortexScroll() : this( 1 )
{
}
[Constructable]
public EnergyVortexScroll( int amount ) : base( 57, 0x1F66, amount )
{
}
public EnergyVortexScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class ResurrectionScroll : SpellScroll
{
[Constructable]
public ResurrectionScroll() : this( 1 )
{
}
[Constructable]
public ResurrectionScroll( int amount ) : base( 58, 0x1F67, amount )
{
}
public ResurrectionScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SummonAirElementalScroll : SpellScroll
{
[Constructable]
public SummonAirElementalScroll() : this( 1 )
{
}
[Constructable]
public SummonAirElementalScroll( int amount ) : base( 59, 0x1F68, amount )
{
}
public SummonAirElementalScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SummonDaemonScroll : SpellScroll
{
[Constructable]
public SummonDaemonScroll() : this( 1 )
{
}
[Constructable]
public SummonDaemonScroll( int amount ) : base( 60, 0x1F69, amount )
{
}
public SummonDaemonScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SummonEarthElementalScroll : SpellScroll
{
[Constructable]
public SummonEarthElementalScroll() : this( 1 )
{
}
[Constructable]
public SummonEarthElementalScroll( int amount ) : base( 61, 0x1F6A, amount )
{
}
public SummonEarthElementalScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SummonFireElementalScroll : SpellScroll
{
[Constructable]
public SummonFireElementalScroll() : this( 1 )
{
}
[Constructable]
public SummonFireElementalScroll( int amount ) : base( 62, 0x1F6B, amount )
{
}
public SummonFireElementalScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SummonWaterElementalScroll : SpellScroll
{
[Constructable]
public SummonWaterElementalScroll() : this( 1 )
{
}
[Constructable]
public SummonWaterElementalScroll( int amount ) : base( 63, 0x1F6C, amount )
{
}
public SummonWaterElementalScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class BladeSpiritsScroll : SpellScroll
{
[Constructable]
public BladeSpiritsScroll() : this( 1 )
{
}
[Constructable]
public BladeSpiritsScroll( int amount ) : base( 32, 0x1F4D, amount )
{
}
public BladeSpiritsScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class DispelFieldScroll : SpellScroll
{
[Constructable]
public DispelFieldScroll() : this( 1 )
{
}
[Constructable]
public DispelFieldScroll( int amount ) : base( 33, 0x1F4E, amount )
{
}
public DispelFieldScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class IncognitoScroll : SpellScroll
{
[Constructable]
public IncognitoScroll() : this( 1 )
{
}
[Constructable]
public IncognitoScroll( int amount ) : base( 34, 0x1F4F, amount )
{
}
public IncognitoScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class MagicReflectScroll : SpellScroll
{
[Constructable]
public MagicReflectScroll() : this( 1 )
{
}
[Constructable]
public MagicReflectScroll( int amount ) : base( 35, 0x1F50, amount )
{
}
public MagicReflectScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class MindBlastScroll : SpellScroll
{
[Constructable]
public MindBlastScroll() : this( 1 )
{
}
[Constructable]
public MindBlastScroll( int amount ) : base( 36, 0x1F51, amount )
{
}
public MindBlastScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class ParalyzeScroll : SpellScroll
{
[Constructable]
public ParalyzeScroll() : this( 1 )
{
}
[Constructable]
public ParalyzeScroll( int amount ) : base( 37, 0x1F52, amount )
{
}
public ParalyzeScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class PoisonFieldScroll : SpellScroll
{
[Constructable]
public PoisonFieldScroll() : this( 1 )
{
}
[Constructable]
public PoisonFieldScroll( int amount ) : base( 38, 0x1F53, amount )
{
}
public PoisonFieldScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class SummonCreatureScroll : SpellScroll
{
[Constructable]
public SummonCreatureScroll() : this( 1 )
{
}
[Constructable]
public SummonCreatureScroll( int amount ) : base( 39, 0x1F54, amount )
{
}
public SummonCreatureScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class ClumsyScroll : SpellScroll
{
[Constructable]
public ClumsyScroll() : this( 1 )
{
}
[Constructable]
public ClumsyScroll( int amount ) : base( 0, 0x1F2E, amount )
{
}
public ClumsyScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class CreateFoodScroll : SpellScroll
{
[Constructable]
public CreateFoodScroll() : this( 1 )
{
}
[Constructable]
public CreateFoodScroll( int amount ) : base( 1, 0x1F2F, amount )
{
}
public CreateFoodScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class FeeblemindScroll : SpellScroll
{
[Constructable]
public FeeblemindScroll() : this( 1 )
{
}
[Constructable]
public FeeblemindScroll( int amount ) : base( 2, 0x1F30, amount )
{
}
public FeeblemindScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class HealScroll : SpellScroll
{
[Constructable]
public HealScroll() : this( 1 )
{
}
[Constructable]
public HealScroll( int amount ) : base( 3, 0x1F31, amount )
{
}
public HealScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class MagicArrowScroll : SpellScroll
{
[Constructable]
public MagicArrowScroll() : this( 1 )
{
}
[Constructable]
public MagicArrowScroll( int amount ) : base( 4, 0x1F32, amount )
{
}
public MagicArrowScroll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class NightSightScroll : SpellScroll
{
[Constructable]
public NightSightScroll() : this( 1 )
{
}
[Constructable]
public NightSightScroll( int amount ) : base( 5, 0x1F33, amount )
{
}
public NightSightScroll( Serial ser ) : base(ser)
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class ReactiveArmorScroll : SpellScroll
{
[Constructable]
public ReactiveArmorScroll() : this( 1 )
{
}
[Constructable]
public ReactiveArmorScroll( int amount ) : base( 6, 0x1F2D, amount )
{
}
public ReactiveArmorScroll( Serial ser ) : base(ser)
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class WeakenScroll : SpellScroll
{
[Constructable]
public WeakenScroll() : this( 1 )
{
}
[Constructable]
public WeakenScroll( int amount ) : base( 7, 0x1F34, amount )
{
}
public WeakenScroll( 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();
}
}
}

Some files were not shown because too many files have changed in this diff Show more