Lots of fixes, changes, rewrites of various things, including but not limited to:

Logging of staff crafting items,
Fixes for the OSI client changes
The potion stacking stuff
BaseWeapon fix, so that damage increase things don't multiply themselves.
admin gump fixes for Firewall
Various display tweaks for weight
SoS no longer spawn in Tokuno
Hiryu hues happified to OSI standards
staff now see alliance chat correctly
Play barkeeper text increased per OSI
Various other OSI skill requirement changes
Various unimplemented features of the SE moves
EventSink for when the client version is received from client.
Client validation moved out of the core.
Client version validation now has options to ignore/kick/warn/annoy.  Automagically tries to detect current client.
Reverted the delayeddamagecontext back to OSI standards.
Can no longer use bags of sending in jail.

MagerySpell implemented. Now only Magery spells have a circle, and various other properties of 'em.
TransformationSpellHelper now implemented.  Things moved around for this.
Spells now need a Timespan for the cast delay, instead of arbitrarily based on Circle.  Circle doesn't make sense for non-Magery spells!
Alot of the spellweaving spells added to OSI standards.
This commit is contained in:
asayre 2007-05-26 03:12:41 +00:00
parent f12e9745c6
commit 2ad37d54aa
214 changed files with 4881 additions and 1243 deletions

View file

@ -0,0 +1,116 @@
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, (Core.SE ? 1 : 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, 120.0 );
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, 120.0 );
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;
if( !Core.AOS )
return TimeSpan.FromSeconds( 0.5 + (0.25 * (int)Circle) );
return base.GetCastDelay();
}
public override TimeSpan CastDelayBase
{
get
{
return TimeSpan.FromSeconds( (3 + (int)Circle) * CastDelaySecondsPerTick );
}
}
}
}

View file

@ -7,6 +7,8 @@ using Server.Spells.Second;
using Server.Spells.Necromancy;
using Server.Spells.Ninjitsu;
using System.Collections.Generic;
using Server.Spells.Spellweaving;
using Server.Spells.Bushido;
namespace Server.Spells
{
@ -23,7 +25,6 @@ namespace Server.Spells
public SpellInfo Info{ get{ return m_Info; } }
public string Name{ get{ return m_Info.Name; } }
public string Mantra{ get{ return m_Info.Mantra; } }
public SpellCircle Circle{ get{ return m_Info.Circle; } }
public Type[] Reagents{ get{ return m_Info.Reagents; } }
public Item Scroll{ get{ return m_Scroll; } }
public DateTime StartCastTime { get { return m_StartCastTime; } }
@ -46,65 +47,55 @@ namespace Server.Spells
//the possibility of stacking 'em. Note that a MA & an Explosion will stack, but
//of course, two MA's won't.
private static Dictionary<Mobile, List<DelayedDamageContext>> m_ContextTable = new Dictionary<Mobile, List<DelayedDamageContext>>();
private static Dictionary<Type, DelayedDamageContextWrapper> m_ContextTable = new Dictionary<Type, DelayedDamageContextWrapper>();
private class DelayedDamageContext {
public Mobile Target;
public Type Type;
public Timer Timer;
private class DelayedDamageContextWrapper
{
private Dictionary<Mobile, Timer> m_Contexts = new Dictionary<Mobile, Timer>();
public DelayedDamageContext( Mobile target, Type type, Timer timer ) {
Target = target;
Type = type;
Timer = timer;
}
}
public void StartDelayedDamageContext( Mobile target, Timer timer )
{
if( DelayedDamageStacking )
return; //Sanity
List<DelayedDamageContext> contexts;
Type type = this.GetType();
if( !m_ContextTable.TryGetValue( m_Caster, out contexts ) )
contexts = new List<DelayedDamageContext>();
else {
for ( int i = 0; i < contexts.Count; i++ ) {
DelayedDamageContext ddc = contexts[i];
if ( ddc.Target == target && ddc.Type == type ) {
ddc.Timer.Stop();
contexts.RemoveAt( i );
break;
}
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 );
}
contexts.Add( new DelayedDamageContext( target, type, timer ) );
public void Remove( Mobile m )
{
m_Contexts.Remove( m );
}
}
public void RemoveDelayedDamageContext( Mobile target )
{
List<DelayedDamageContext> contexts;
Type type = this.GetType();
public void StartDelayedDamageContext( Mobile m, Timer t )
{
if( DelayedDamageStacking )
return; //Sanity
if( !m_ContextTable.TryGetValue( m_Caster, out contexts ) )
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;
for ( int i = 0; i < contexts.Count; i++ ) {
DelayedDamageContext ddc = contexts[i];
if ( ddc.Target == target && ddc.Type == type ) {
contexts.RemoveAt( i );
break;
}
}
if ( contexts.Count == 0 )
m_ContextTable.Remove( m_Caster );
}
contexts.Remove( m );
}
public Spell( Mobile caster, Item scroll, SpellInfo info )
{
@ -146,8 +137,14 @@ namespace Server.Spells
// PvP spell damage increase cap of 15% from an items magic property
if ( playerVsPlayer && sdiBonus > 15 )
sdiBonus = 15;
damageBonus += sdiBonus;
TransformContext context = TransformationSpellHelper.GetContext( Caster );
if( context != null && context.Spell is ReaperFormSpell )
damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus;
damage = AOS.Scale( damage, 100 + damageBonus );
int evalSkill = GetDamageFixed( m_Caster );
@ -160,27 +157,6 @@ namespace Server.Spells
return damage / 100;
}
/*
public virtual double GetAosDamage( int min, int random, double div )
{
double scale = 1.0;
scale += GetInscribeSkill( m_Caster ) * 0.001;
if ( Caster.Player )
{
scale += Caster.Int * 0.001;
scale += AosAttributes.GetValue( m_Caster, AosAttribute.SpellDamage ) * 0.01;
}
int baseDamage = min + (int)(GetDamageSkill( m_Caster ) / div);
double damage = Utility.RandomMinMax( baseDamage, baseDamage + random );
return damage * scale;
}
*/
public virtual bool IsCasting{ get{ return m_State == SpellState.Casting; } }
public virtual void OnCasterHurt()
@ -263,36 +239,9 @@ namespace Server.Spells
if ( pack.ConsumeTotal( m_Info.Reagents, m_Info.Amounts ) == -1 )
return true;
if ( GetType().BaseType == typeof( Spell ) )
{
if ( ArcaneGem.ConsumeCharges( m_Caster, ( Core.SE ? 1 : 1 + (int)Circle ) ) )
return true;
}
return false;
}
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, 120.0 );
return ( n >= Utility.RandomDouble() );
}
public virtual double GetInscribeSkill( Mobile m )
{
// There is no chance to gain
@ -323,41 +272,11 @@ namespace Server.Spells
return m.Skills[DamageSkill].Value;
}
public virtual int GetResistFixed( 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, 120.0 );
return m.Skills[SkillName.MagicResist].Fixed;
}
public virtual 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, 120.0 );
return m.Skills[SkillName.MagicResist].Value;
}
public virtual double GetResistPercentForCircle( Mobile target, SpellCircle circle )
{
double firstPercent = target.Skills[SkillName.MagicResist].Value / 5.0;
double secondPercent = target.Skills[SkillName.MagicResist].Value - (((m_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, m_Info.Circle );
}
public virtual double GetDamageScalar( Mobile target )
{
double scalar = 1.0;
@ -397,6 +316,9 @@ namespace Server.Spells
target.Region.SpellDamageScalar( m_Caster, target, ref scalar );
if( Evasion.CheckSpellEvasion( target ) ) //Only single target spells an be evaded
scalar = 0;
return scalar;
}
@ -417,7 +339,7 @@ namespace Server.Spells
}
TransformContext context = TransformationSpell.GetContext( defender );
TransformContext context = TransformationSpellHelper.GetContext( defender );
if( (atkBook.Slayer == SlayerName.Silver || atkBook.Slayer2 == SlayerName.Silver) && context != null && context.Type != typeof( HorrificBeastSpell ) )
scalar +=.25; // Every necromancer transformation other than horrific beast take an additional 25% damage
@ -481,7 +403,7 @@ namespace Server.Spells
if ( m_State == SpellState.Casting )
{
if ( !firstCircle && Circle == SpellCircle.First && !Core.AOS )
if( !firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First )
return;
m_State = SpellState.None;
@ -502,7 +424,7 @@ namespace Server.Spells
}
else if ( m_State == SpellState.Sequencing )
{
if ( !firstCircle && Circle == SpellCircle.First && !Core.AOS )
if( !firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First )
return;
m_State = SpellState.None;
@ -564,7 +486,7 @@ namespace Server.Spells
{
m_Caster.SendLocalizedMessage( 502642 ); // You are already casting a spell.
}
else if ( BlockedByHorrificBeast && TransformationSpell.UnderTransformation( m_Caster, typeof( HorrificBeastSpell ) ) || ( BlockedByAnimalForm && AnimalForm.UnderTransformation( m_Caster ) ))
else if ( BlockedByHorrificBeast && TransformationSpellHelper.UnderTransformation( m_Caster, typeof( HorrificBeastSpell ) ) || ( BlockedByAnimalForm && AnimalForm.UnderTransformation( m_Caster ) ))
{
m_Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
}
@ -636,19 +558,9 @@ namespace Server.Spells
{
}
private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0;
public virtual void GetCastSkills( out double min, out double max )
{
int circle = (int)m_Info.Circle;
if ( m_Scroll != null )
circle -= 2;
double avg = ChanceLength * circle;
min = avg - ChanceOffset;
max = avg + ChanceOffset;
min = max = 0; //Intended but not required for overriding.
}
public virtual bool CheckFizzle()
@ -663,15 +575,7 @@ namespace Server.Spells
return Caster.CheckSkill( CastSkill, minSkill, maxSkill );
}
private static int[] m_ManaTable = new int[]{ 4, 6, 9, 11, 14, 20, 40, 50 };
public virtual int GetMana()
{
if ( m_Scroll is BaseWand )
return 0;
return m_ManaTable[(int)Circle];
}
public abstract int GetMana();
public virtual int ScaleMana( int mana )
{
@ -704,7 +608,6 @@ namespace Server.Spells
}
public virtual int CastRecoveryBase{ get{ return 6; } }
public virtual int CastRecoveryCircleScalar{ get{ return 0; } }
public virtual int CastRecoveryFastScalar{ get{ return 1; } }
public virtual int CastRecoveryPerSecond{ get{ return 4; } }
public virtual int CastRecoveryMinimum{ get{ return 0; } }
@ -716,10 +619,11 @@ namespace Server.Spells
int fcr = AosAttributes.GetValue( m_Caster, AosAttribute.CastRecovery );
int circleDelay = CastRecoveryCircleScalar * (1 + (int)Circle); // Note: Circle is 0-based so we must offset
fcr -= ThunderstormSpell.GetCastRecoveryMalus( m_Caster );
int fcrDelay = -(CastRecoveryFastScalar * fcr);
int delay = CastRecoveryBase + circleDelay + fcrDelay;
int delay = CastRecoveryBase + fcrDelay;
if ( delay < CastRecoveryMinimum )
delay = CastRecoveryMinimum;
@ -727,20 +631,24 @@ namespace Server.Spells
return TimeSpan.FromSeconds( (double)delay / CastRecoveryPerSecond );
}
public virtual int CastDelayBase{ get{ return 3; } }
public virtual int CastDelayCircleScalar{ get{ return 1; } }
public virtual int CastDelayFastScalar{ get{ return 1; } }
public virtual int CastDelayPerSecond{ get{ return 4; } }
public virtual int CastDelayMinimum{ get{ return 1; } }
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 int CastDelayBase{ get{ return 3; } }
//public virtual int CastDelayFastScalar{ get{ return 1; } }
//public virtual int CastDelayPerSecond{ get{ return 4; } }
//public virtual int CastDelayMinimum{ get{ return 1; } }
public virtual TimeSpan GetCastDelay()
{
if ( m_Scroll is BaseWand )
return TimeSpan.Zero;
if ( !Core.AOS )
return TimeSpan.FromSeconds( 0.5 + (0.25 * (int)Circle) );
// Faster casting cap of 2 (if not using the protection spell)
// Faster casting cap of 0 (if using the protection spell)
// Paladin spells are subject to a faster casting cap of 4
@ -758,17 +666,21 @@ namespace Server.Spells
if ( ProtectionSpell.Registry.Contains( m_Caster ) )
fc -= 2;
// Circle is 0-based but we must not offset, first circle spells are cast at base delay.
int circleDelay = CastDelayCircleScalar * (int)Circle;
if( EssenceOfWindSpell.IsDebuffed( m_Caster ) )
fc -= EssenceOfWindSpell.GetFCMalus( m_Caster );
int fcDelay = -(CastDelayFastScalar * fc);
TimeSpan baseDelay = CastDelayBase;
int delay = CastDelayBase + circleDelay + fcDelay;
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 TimeSpan.FromSeconds( (double)delay / CastDelayPerSecond );
return delay;
}
public virtual void FinishSequence()
@ -840,7 +752,7 @@ namespace Server.Spells
if ( karma != 0 )
Misc.Titles.AwardKarma( Caster, karma, true );
if ( TransformationSpell.UnderTransformation( m_Caster, typeof( VampiricEmbraceSpell ) ) )
if( TransformationSpellHelper.UnderTransformation( m_Caster, typeof( VampiricEmbraceSpell ) ) )
{
bool garlic = false;

View file

@ -9,6 +9,10 @@ using Server.Targeting;
using Server.Engines.PartySystem;
using Server.Misc;
using Server.Spells.Bushido;
using Server.Spells.Ninjitsu;
using System.Collections.Generic;
using Server.Spells.Seventh;
using Server.Spells.Fifth;
namespace Server
{
@ -423,6 +427,16 @@ namespace Server.Spells
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 )
@ -446,11 +460,61 @@ namespace Server.Spells
}
}
}
* */
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;
}
private delegate bool TravelValidator( Map map, Point3D loc );
private static TravelValidator[] m_Validators = new TravelValidator[]
@ -789,9 +853,6 @@ namespace Server.Spells
{
int iDamage = (int)damage;
if( Evasion.CheckSpellEvasion( target ) )
iDamage = 0;
if( delay == TimeSpan.Zero )
{
if( from is BaseCreature )
@ -844,9 +905,6 @@ namespace Server.Spells
{
int iDamage = (int)damage;
if( Evasion.CheckSpellEvasion( target ) )
iDamage = 0;
if( delay == TimeSpan.Zero )
{
if( from is BaseCreature )
@ -868,6 +926,16 @@ namespace Server.Spells
((BaseCreature)target).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 )
{
//TODO: All Healing *spells* go through ArcaneEmpowerment
target.Heal( amount, from, message );
}
private class SpellDamageTimer : Timer
{
private Mobile m_Target, m_From;
@ -950,4 +1018,244 @@ namespace Server.Spells
}
}
}
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 );
List<ResistanceMod> mods = context.Mods;
for( int i = 0; i < mods.Count; ++i )
m.RemoveResistanceMod( mods[i] );
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( Factions.Sigil.ExistsOn( caster ) )
{
caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
return false;
}
else if( !caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
return false;
}
else if( AnimalForm.UnderTransformation( caster ) )
{
caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
return false;
}
return true;
}
public static bool OnCast( Mobile caster, Spell spell )
{
ITransformationSpell transformSpell = spell as ITransformationSpell;
if( transformSpell == null )
return false;
if( Factions.Sigil.ExistsOn( caster ) )
{
caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
}
else if( !caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
}
else if( AnimalForm.UnderTransformation( caster ) )
{
caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
}
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 )
{
List<ResistanceMod> mods = new List<ResistanceMod>();
if( transformSpell.PhysResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Physical, transformSpell.PhysResistOffset ) );
if( transformSpell.FireResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Fire, transformSpell.FireResistOffset ) );
if( transformSpell.ColdResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Cold, transformSpell.ColdResistOffset ) );
if( transformSpell.PoisResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Poison, transformSpell.PoisResistOffset ) );
if( transformSpell.NrgyResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Energy, transformSpell.NrgyResistOffset ) );
if( !((Body)transformSpell.Body).IsHuman )
{
Mobiles.IMount mt = caster.Mount;
if( mt != null )
mt.Rider = null;
}
caster.BodyMod = transformSpell.Body;
caster.HueMod = transformSpell.Hue;
for( int i = 0; i < mods.Count; ++i )
caster.AddResistanceMod( mods[i] );
transformSpell.DoEffect( caster );
Timer timer = new TransformTimer( caster, transformSpell );
timer.Start();
AddContext( caster, new TransformContext( timer, mods, ourType, transformSpell ) );
return true;
}
}
return false;
}
}
public interface ITransformationSpell
{
int Body { get; }
int Hue { get; }
int PhysResistOffset { get; }
int FireResistOffset { get; }
int ColdResistOffset { get; }
int PoisResistOffset { get; }
int NrgyResistOffset { get; }
double TickRate { get; }
void OnTick( Mobile m );
void DoEffect( Mobile m );
void RemoveEffect( Mobile m );
}
public class TransformContext
{
private Timer m_Timer;
private List<ResistanceMod> m_Mods;
private Type m_Type;
private ITransformationSpell m_Spell;
public Timer Timer { get { return m_Timer; } }
public List<ResistanceMod> Mods { get { return m_Mods; } }
public Type Type { get { return m_Type; } }
public ITransformationSpell Spell { get { return m_Spell; } }
public TransformContext( Timer timer, List<ResistanceMod> mods, Type type, ITransformationSpell spell )
{
m_Timer = timer;
m_Mods = mods;
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

@ -7,42 +7,40 @@ namespace Server.Spells
{
private string m_Name;
private string m_Mantra;
private SpellCircle m_Circle;
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, SpellCircle circle, params Type[] regs ) : this( name, mantra, circle, 16, 0, 0, true, regs )
public SpellInfo( string name, string mantra, params Type[] regs ) : this( name, mantra, 16, 0, 0, true, regs )
{
}
public SpellInfo( string name, string mantra, SpellCircle circle, bool allowTown, params Type[] regs ) : this( name, mantra, circle, 16, 0, 0, allowTown, 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, SpellCircle circle, int action, params Type[] regs ) : this( name, mantra, circle, action, 0, 0, true, 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, SpellCircle circle, int action, bool allowTown, params Type[] regs ) : this( name, mantra, circle, action, 0, 0, allowTown, 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, SpellCircle circle, int action, int handEffect, params Type[] regs ) : this( name, mantra, circle, action, handEffect, handEffect, true, 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, SpellCircle circle, int action, int handEffect, bool allowTown, params Type[] regs ) : this( name, mantra, circle, action, handEffect, handEffect, allowTown, 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, SpellCircle circle, int action, int leftHandEffect, int rightHandEffect, bool allowTown, params Type[] 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_Circle = circle;
m_Action = action;
m_Reagents = regs;
m_AllowTown = allowTown;
@ -59,7 +57,6 @@ namespace Server.Spells
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 SpellCircle Circle{ get{ return m_Circle; } set{ m_Circle = 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; } }

View file

@ -11,7 +11,7 @@ namespace Server.Spells
{
public class SpellRegistry
{
private static Type[] m_Types = new Type[600];
private static Type[] m_Types = new Type[700];
private static int m_Count;
public static Type[] Types
@ -146,7 +146,8 @@ namespace Server.Spells
"Necromancy",
"Chivalry",
"Bushido",
"Ninjitsu"
"Ninjitsu",
"SpellWeaving"
};
public static Spell NewSpell( string name, Mobile caster, Item scroll )

View file

@ -10,11 +10,12 @@ namespace Server.Spells.Bushido
{
private static SpellInfo m_Info = new SpellInfo(
"Confidence", null,
SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } }
public override double RequiredSkill{ get{ return 25.0; } }
public override int RequiredMana{ get{ return 10; } }

View file

@ -11,11 +11,12 @@ namespace Server.Spells.Bushido
{
private static SpellInfo m_Info = new SpellInfo(
"CounterAttack", null,
SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } }
public override double RequiredSkill{ get{ return 40.0; } }
public override int RequiredMana{ get{ return 5; } }

View file

@ -11,11 +11,12 @@ namespace Server.Spells.Bushido
{
private static SpellInfo m_Info = new SpellInfo(
"Evasion", null,
SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } }
public override double RequiredSkill { get { return 60.0; } }
public override int RequiredMana { get { return 10; } }

View file

@ -6,5 +6,10 @@ namespace Server.Spells
public class SamuraiMove : SpecialMove
{
public override SkillName MoveSkill{ get{ return SkillName.Bushido; } }
public override void CheckGain( Mobile m )
{
m.CheckSkill( MoveSkill, RequiredSkill - 12.5, RequiredSkill + 37.5 ); //Per five on friday 02/16/07
}
}
}

View file

@ -18,8 +18,8 @@ namespace Server.Spells.Bushido
public override bool BlocksMovement{ get{ return false; } }
public override bool ShowHandMovement{ get{ return false; } }
public override int CastDelayBase{ get{ return 1; } }
public override int CastDelayFastScalar{ get{ return 0; } }
//public override int CastDelayBase{ get{ return 1; } }
public override double CastDelayFastScalar{ get{ return 0; } }
public override int CastRecoveryBase{ get{ return 7; } }
@ -35,7 +35,8 @@ namespace Server.Spells.Bushido
if ( from.NetState == null )
return false;
return ( (from.NetState.Flags & 0x10) != 0 );
//return ( (from.NetState.Flags & 0x10) != 0 );
return from.NetState.SupportsExpansion( Expansion.SE );
}
public override bool CheckCast()
@ -89,7 +90,7 @@ namespace Server.Spells.Bushido
public override void GetCastSkills( out double min, out double max )
{
min = RequiredSkill;
min = RequiredSkill - 12.5; //per 5 on friday, 2/16/07
max = RequiredSkill + 37.5;
}

View file

@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Cleanse By Fire", "Expor Flamus",
SpellCircle.Fourth, // 0 + 1.0 = 1s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } }
public override double RequiredSkill{ get{ return 5.0; } }
public override int RequiredMana{ get{ return 10; } }
public override int RequiredTithing{ get{ return 10; } }

View file

@ -11,11 +11,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Close Wounds", "Obsu Vulni",
SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 0.0; } }
public override int RequiredMana{ get{ return 10; } }
public override int RequiredTithing{ get{ return 10; } }
@ -71,7 +72,9 @@ namespace Server.Spells.Chivalry
if ( (m.Hits + toHeal) > m.HitsMax )
toHeal = m.HitsMax - m.Hits;
m.Hits += toHeal;
//m.Hits += toHeal; //Was previosuly due to the message
//m.Heal( toHeal, Caster, false );
SpellHelper.Heal( toHeal, m, Caster, false );
m.SendLocalizedMessage( 1060203, toHeal.ToString() ); // You have had ~1_HEALED_AMOUNT~ hit points of damage healed.

View file

@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Consecrate Weapon", "Consecrus Arma",
SpellCircle.Second, // 0 + 0.5 = 0.5s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.5 ); } }
public override double RequiredSkill{ get{ return 15.0; } }
public override int RequiredMana{ get{ return 10; } }
public override int RequiredTithing{ get{ return 10; } }

View file

@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Dispel Evil", "Dispiro Malas",
SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } }
public override double RequiredSkill{ get{ return 35.0; } }
public override int RequiredMana{ get{ return 10; } }
public override int RequiredTithing{ get{ return 10; } }
@ -93,7 +94,8 @@ namespace Server.Spells.Chivalry
}
}
if ( TransformationSpell.GetContext( m ) != null )
TransformContext context = TransformationSpellHelper.GetContext( m );
if( context != null && context.Spell is NecromancerSpell ) //Trees are not evil! TODO: OSI confirm?
{
// transformed ..

View file

@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Divine Fury", "Divinum Furis",
SpellCircle.Fourth, // 0 + 1.0 = 1s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } }
public override double RequiredSkill{ get{ return 25.0; } }
public override int RequiredMana{ get{ return 15; } }
public override int RequiredTithing{ get{ return 10; } }

View file

@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Enemy of One", "Forul Solum",
SpellCircle.Second, // 0 + 0.5 = 0.5s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.5 ); } }
public override double RequiredSkill{ get{ return 45.0; } }
public override int RequiredMana{ get{ return 20; } }
public override int RequiredTithing{ get{ return 10; } }

View file

@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Holy Light", "Augus Luminos",
SpellCircle.Seventh, // 0 + 1.75 = 1.75s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.75 ); } }
public override double RequiredSkill{ get{ return 55.0; } }
public override int RequiredMana{ get{ return 10; } }
public override int RequiredTithing{ get{ return 10; } }

View file

@ -16,11 +16,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Noble Sacrifice", "Dium Prostra",
SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 65.0; } }
public override int RequiredMana{ get{ return 20; } }
public override int RequiredTithing{ get{ return 30; } }
@ -109,7 +110,7 @@ namespace Server.Spells.Chivalry
toHeal = 24;
Caster.DoBeneficial( m );
m.Heal( toHeal );
m.Heal( toHeal, Caster );
sendEffect = true;
}

View file

@ -16,7 +16,7 @@ namespace Server.Spells.Chivalry
public override bool ClearHandsOnCast{ get{ return false; } }
public override int CastDelayBase{ get{ return 1; } }
//public override int CastDelayBase{ get{ return 1; } }
public override int CastRecoveryBase{ get{ return 7; } }

View file

@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Remove Curse", "Extermo Vomica",
SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 5.0; } }
public override int RequiredMana{ get{ return 20; } }
public override int RequiredTithing{ get{ return 10; } }

View file

@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry
{
private static SpellInfo m_Info = new SpellInfo(
"Sacred Journey", "Sanctum Viatas",
SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 15.0; } }
public override int RequiredMana{ get{ return 10; } }
public override int RequiredTithing{ get{ return 15; } }

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class AirElementalSpell : Spell
public class AirElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Air Elemental", "Kal Vas Xen Hur",
SpellCircle.Eighth,
269,
9010,
false,
@ -18,6 +17,8 @@ namespace Server.Spells.Eighth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public AirElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class EarthElementalSpell : Spell
public class EarthElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Earth Elemental", "Kal Vas Xen Ylem",
SpellCircle.Eighth,
269,
9020,
false,
@ -18,6 +17,8 @@ namespace Server.Spells.Eighth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public EarthElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -6,11 +6,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class EarthquakeSpell : Spell
public class EarthquakeSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Earthquake", "In Vas Por",
SpellCircle.Eighth,
233,
9012,
false,
@ -20,6 +19,8 @@ namespace Server.Spells.Eighth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public EarthquakeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class EnergyVortexSpell : Spell
public class EnergyVortexSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Energy Vortex", "Vas Corp Por",
SpellCircle.Eighth,
260,
9032,
false,
@ -19,6 +18,8 @@ namespace Server.Spells.Eighth
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public EnergyVortexSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class FireElementalSpell : Spell
public class FireElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Fire Elemental", "Kal Vas Xen Flam",
SpellCircle.Eighth,
269,
9050,
false,
@ -19,6 +18,8 @@ namespace Server.Spells.Eighth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public FireElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Gumps;
namespace Server.Spells.Eighth
{
public class ResurrectionSpell : Spell
public class ResurrectionSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Resurrection", "An Corp",
SpellCircle.Eighth,
245,
9062,
Reagent.Bloodmoss,
@ -17,6 +16,8 @@ namespace Server.Spells.Eighth
Reagent.Ginseng
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public ResurrectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class SummonDaemonSpell : Spell
public class SummonDaemonSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Summon Daemon", "Kal Vas Xen Corp",
SpellCircle.Eighth,
269,
9050,
false,
@ -19,6 +18,8 @@ namespace Server.Spells.Eighth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public SummonDaemonSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Eighth
{
public class WaterElementalSpell : Spell
public class WaterElementalSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Water Elemental", "Kal Vas Xen An Flam",
SpellCircle.Eighth,
269,
9070,
false,
@ -18,6 +17,8 @@ namespace Server.Spells.Eighth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
public WaterElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Fifth
{
public class BladeSpiritsSpell : Spell
public class BladeSpiritsSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Blade Spirits", "In Jux Hur Ylem",
SpellCircle.Fifth,
266,
9040,
false,
@ -18,6 +17,8 @@ namespace Server.Spells.Fifth
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public BladeSpiritsSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -6,11 +6,10 @@ using Server.Misc;
namespace Server.Spells.Fifth
{
public class DispelFieldSpell : Spell
public class DispelFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Dispel Field", "An Grav",
SpellCircle.Fifth,
206,
9002,
Reagent.BlackPearl,
@ -19,6 +18,8 @@ namespace Server.Spells.Fifth
Reagent.Garlic
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public DispelFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -10,11 +10,10 @@ using Server.Spells.Seventh;
namespace Server.Spells.Fifth
{
public class IncognitoSpell : Spell
public class IncognitoSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Incognito", "Kal In Ex",
SpellCircle.Fifth,
206,
9002,
Reagent.Bloodmoss,
@ -22,6 +21,8 @@ namespace Server.Spells.Fifth
Reagent.Nightshade
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public IncognitoSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -6,11 +6,10 @@ using Server.Network;
namespace Server.Spells.Fifth
{
public class MagicReflectSpell : Spell
public class MagicReflectSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Reflection", "In Jux Sanct",
SpellCircle.Fifth,
242,
9012,
Reagent.Garlic,
@ -18,6 +17,8 @@ namespace Server.Spells.Fifth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public MagicReflectSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -4,11 +4,10 @@ using Server.Network;
namespace Server.Spells.Fifth
{
public class MindBlastSpell : Spell
public class MindBlastSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mind Blast", "Por Corp Wis",
SpellCircle.Fifth,
218,
Core.AOS ? 9002 : 9032,
Reagent.BlackPearl,
@ -17,6 +16,8 @@ namespace Server.Spells.Fifth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public MindBlastSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
if ( Core.AOS )

View file

@ -4,11 +4,10 @@ using Server.Network;
namespace Server.Spells.Fifth
{
public class ParalyzeSpell : Spell
public class ParalyzeSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Paralyze", "An Ex Por",
SpellCircle.Fifth,
218,
9012,
Reagent.Garlic,
@ -16,6 +15,8 @@ namespace Server.Spells.Fifth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public ParalyzeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
@ -45,7 +46,7 @@ namespace Server.Spells.Fifth
if ( Core.AOS )
{
int secs = (GetDamageFixed( Caster ) / 100) - (GetResistFixed( m ) / 100);
int secs = (int)((GetDamageSkill( Caster ) / 10) - (GetResistSkill( m ) / 10));
if( !Core.SE )
secs += 2;

View file

@ -7,11 +7,10 @@ using Server.Items;
namespace Server.Spells.Fifth
{
public class PoisonFieldSpell : Spell
public class PoisonFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Poison Field", "In Nox Grav",
SpellCircle.Fifth,
230,
9052,
false,
@ -20,6 +19,8 @@ namespace Server.Spells.Fifth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public PoisonFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Fifth
{
public class SummonCreatureSpell : Spell
public class SummonCreatureSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Summon Creature", "Kal Xen",
SpellCircle.Fifth,
266,
9040,
Reagent.Bloodmoss,
@ -17,6 +16,8 @@ namespace Server.Spells.Fifth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
public SummonCreatureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.First
{
public class ClumsySpell : Spell
public class ClumsySpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Clumsy", "Uus Jux",
SpellCircle.First,
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 )
{
}

View file

@ -3,11 +3,10 @@ using Server.Items;
namespace Server.Spells.First
{
public class CreateFoodSpell : Spell
public class CreateFoodSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Create Food", "In Mani Ylem",
SpellCircle.First,
224,
9011,
Reagent.Garlic,
@ -15,6 +14,8 @@ namespace Server.Spells.First
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public CreateFoodSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.First
{
public class FeeblemindSpell : Spell
public class FeeblemindSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Feeblemind", "Rel Wis",
SpellCircle.First,
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 )
{
}

View file

@ -6,11 +6,10 @@ using Server.Mobiles;
namespace Server.Spells.First
{
public class HealSpell : Spell
public class HealSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Heal", "In Mani",
SpellCircle.First,
224,
9061,
Reagent.Garlic,
@ -18,6 +17,8 @@ namespace Server.Spells.First
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public HealSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
@ -69,7 +70,8 @@ namespace Server.Spells.First
toHeal += Utility.Random( 1, 5 );
}
m.Heal( toHeal );
//m.Heal( toHeal, Caster );
SpellHelper.Heal( toHeal, m, Caster );
m.FixedParticles( 0x376A, 9, 32, 5005, EffectLayer.Waist );
m.PlaySound( 0x1F2 );

View file

@ -4,16 +4,17 @@ using Server.Network;
namespace Server.Spells.First
{
public class MagicArrowSpell : Spell
public class MagicArrowSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Arrow", "In Por Ylem",
SpellCircle.First,
212,
9041,
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public MagicArrowSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,17 +5,18 @@ using Server;
namespace Server.Spells.First
{
public class NightSightSpell : Spell
public class NightSightSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Night Sight", "In Lor",
SpellCircle.First,
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 )
{
}

View file

@ -5,11 +5,10 @@ using Server.Network;
namespace Server.Spells.First
{
public class ReactiveArmorSpell : Spell
public class ReactiveArmorSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Reactive Armor", "Flam Sanct",
SpellCircle.First,
236,
9011,
Reagent.Garlic,
@ -17,6 +16,8 @@ namespace Server.Spells.First
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.First; } }
public ReactiveArmorSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.First
{
public class WeakenSpell : Spell
public class WeakenSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Weaken", "Des Mani",
SpellCircle.First,
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 )
{
}

View file

@ -6,11 +6,10 @@ using Server.Targeting;
namespace Server.Spells.Fourth
{
public class ArchCureSpell : Spell
public class ArchCureSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Arch Cure", "Vas An Nox",
SpellCircle.Fourth,
215,
9061,
Reagent.Garlic,
@ -18,6 +17,8 @@ namespace Server.Spells.Fourth
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public ArchCureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
@ -28,7 +29,7 @@ namespace Server.Spells.Fourth
}
// Archcure is now 1/4th of a second faster
public override int CastDelayBase{ get{ return base.CastDelayBase - 1; } }
public override TimeSpan CastDelayBase{ get{ return base.CastDelayBase - TimeSpan.FromSeconds( 0.25 ); } }
public void Target( IPoint3D p )
{

View file

@ -7,11 +7,10 @@ using Server.Engines.PartySystem;
namespace Server.Spells.Fourth
{
public class ArchProtectionSpell : Spell
public class ArchProtectionSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Arch Protection", "Vas Uus Sanct",
SpellCircle.Fourth,
Core.AOS ? 239 : 215,
9011,
Reagent.Garlic,
@ -20,6 +19,8 @@ namespace Server.Spells.Fourth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public ArchProtectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Network;
namespace Server.Spells.Fourth
{
public class CurseSpell : Spell
public class CurseSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Curse", "Des Sanct",
SpellCircle.Fourth,
227,
9031,
Reagent.Nightshade,
@ -17,6 +16,8 @@ namespace Server.Spells.Fourth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public CurseSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -7,11 +7,10 @@ using Server.Items;
namespace Server.Spells.Fourth
{
public class FireFieldSpell : Spell
public class FireFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Fire Field", "In Flam Grav",
SpellCircle.Fourth,
215,
9041,
false,
@ -20,6 +19,8 @@ namespace Server.Spells.Fourth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public FireFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
@ -80,7 +81,7 @@ namespace Server.Spells.Fourth
{
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 );
new FireFieldItem( itemID, loc, Caster, Caster.Map, duration, i );
}
}
@ -88,15 +89,21 @@ namespace Server.Spells.Fourth
}
[DispellableField]
private class InternalItem : Item
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 InternalItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val ) : base( itemID )
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 );
@ -108,6 +115,8 @@ namespace Server.Spells.Fourth
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 );
@ -122,7 +131,7 @@ namespace Server.Spells.Fourth
m_Timer.Stop();
}
public InternalItem( Serial serial ) : base( serial )
public FireFieldItem( Serial serial ) : base( serial )
{
}
@ -130,8 +139,9 @@ namespace Server.Spells.Fourth
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( (int) 2 ); // version
writer.Write( m_Damage );
writer.Write( m_Caster );
writer.WriteDeltaTime( m_End );
}
@ -144,6 +154,11 @@ namespace Server.Spells.Fourth
switch ( version )
{
case 2:
{
m_Damage = reader.ReadInt();
goto case 1;
}
case 1:
{
m_Caster = reader.ReadMobile();
@ -160,6 +175,9 @@ namespace Server.Spells.Fourth
break;
}
}
if( version < 2 )
m_Damage = 2;
}
public override bool OnMoveOver( Mobile m )
@ -168,7 +186,7 @@ namespace Server.Spells.Fourth
{
m_Caster.DoHarmful( m );
int damage = 2;
int damage = m_Damage;
if ( !Core.AOS && m.CheckSkill( SkillName.MagicResist, 0.0, 30.0 ) )
{
@ -186,12 +204,12 @@ namespace Server.Spells.Fourth
private class InternalTimer : Timer
{
private InternalItem m_Item;
private FireFieldItem 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.0 ) )
public InternalTimer( FireFieldItem item, TimeSpan delay, bool inLOS, bool canFit ) : base( delay, TimeSpan.FromSeconds( 1.0 ) )
{
m_Item = item;
m_InLOS = inLOS;
@ -242,7 +260,7 @@ namespace Server.Spells.Fourth
caster.DoHarmful( m );
int damage = 2;
int damage = m_Item.m_Damage;
if ( !Core.AOS && m.CheckSkill( SkillName.MagicResist, 0.0, 30.0 ) )
{

View file

@ -6,11 +6,10 @@ using Server.Mobiles;
namespace Server.Spells.Fourth
{
public class GreaterHealSpell : Spell
public class GreaterHealSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Greater Heal", "In Vas Mani",
SpellCircle.Fourth,
204,
9061,
Reagent.Garlic,
@ -19,6 +18,8 @@ namespace Server.Spells.Fourth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public GreaterHealSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}
@ -59,7 +60,8 @@ namespace Server.Spells.Fourth
int toHeal = (int)(Caster.Skills[SkillName.Magery].Value * 0.4);
toHeal += Utility.Random( 1, 10 );
m.Heal( toHeal );
//m.Heal( toHeal, Caster );
SpellHelper.Heal( toHeal, m, Caster );
m.FixedParticles( 0x376A, 9, 32, 5030, EffectLayer.Waist );
m.PlaySound( 0x202 );

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Fourth
{
public class LightningSpell : Spell
public class LightningSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Lightning", "Por Ort Grav",
SpellCircle.Fourth,
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 )
{
}

View file

@ -5,11 +5,10 @@ using Server.Targeting;
namespace Server.Spells.Fourth
{
public class ManaDrainSpell : Spell
public class ManaDrainSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mana Drain", "Ort Rel",
SpellCircle.Fourth,
215,
9031,
Reagent.BlackPearl,
@ -17,6 +16,8 @@ namespace Server.Spells.Fourth
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
public ManaDrainSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -9,11 +9,10 @@ using Server.Spells.Necromancy;
namespace Server.Spells.Fourth
{
public class RecallSpell : Spell
public class RecallSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Recall", "Kal Ort Por",
SpellCircle.Fourth,
239,
9031,
Reagent.BlackPearl,
@ -21,6 +20,8 @@ namespace Server.Spells.Fourth
Reagent.MandrakeRoot
);
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
private RunebookEntry m_Entry;
private Runebook m_Book;
@ -36,7 +37,7 @@ namespace Server.Spells.Fourth
public override void GetCastSkills( out double min, out double max )
{
if ( TransformationSpell.UnderTransformation( Caster, typeof( WraithFormSpell ) ) )
if ( TransformationSpellHelper.UnderTransformation( Caster, typeof( WraithFormSpell ) ) )
min = max = 0;
else if( Core.SE && m_Book != null ) //recall using Runebook charge
min = max = 0;

View file

@ -142,6 +142,26 @@ namespace Server.Spells
Register( 506, typeof( Ninjitsu.Shadowjump ) );
Register( 507, typeof( Ninjitsu.MirrorImage ) );
}
if( Core.ML )
{
Register( 600, typeof( Spellweaving.ArcaneCircleSpell ) );
Register( 601, typeof( Spellweaving.GiftOfRenewalSpell ) );
//Register( 602, typeof( Spellweaving.ImmolatingWeaponSpell ) );
Register( 603, typeof( Spellweaving.AttuneWeaponSpell ) );
Register( 604, typeof( Spellweaving.ThunderstormSpell ) );
Register( 605, typeof( Spellweaving.NatureFurySpell ) );
Register( 606, typeof( Spellweaving.SummonFeySpell ) );
Register( 607, typeof( Spellweaving.SummonFiendSpell ) );
Register( 608, typeof( Spellweaving.ReaperFormSpell ) );
//Register( 609, typeof( Spellweaving.WildfireSpell ) );
Register( 610, typeof( Spellweaving.EssenceOfWindSpell ) );
//Register( 611, typeof( Spellweaving.DryadAllureSpell ) );
Register( 612, typeof( Spellweaving.EtherealVoyageSpell ) );
Register( 613, typeof( Spellweaving.WordOfDeathSpell ) );
Register( 614, typeof( Spellweaving.GiftOfLifeSpell ) );
//Register( 615, typeof( Spellweaving.ArcaneEmpowermentSpell ) );
}
}
}

View file

@ -13,13 +13,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Animate Dead", "Uus Corp",
SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay
203,
9031,
Reagent.GraveDust,
Reagent.DaemonBlood
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 40.0; } }
public override int RequiredMana{ get{ return 23; } }

View file

@ -10,12 +10,13 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Blood Oath", "In Jux Mani Xen",
SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay
203,
9031,
Reagent.DaemonBlood
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 20.0; } }
public override int RequiredMana{ get{ return 13; } }
@ -69,6 +70,7 @@ namespace Server.Spells.Necromancy
m.FixedParticles( 0x3728, 1, 13, 9502, 33, 7, (EffectLayer)255 );
TimeSpan duration = TimeSpan.FromSeconds( ((GetDamageSkill( Caster ) - GetResistSkill( m )) / 8) + 8 );
m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain
new ExpireTimer( Caster, m, duration ).Start();
}

View file

@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Corpse Skin", "In Agle Corp Ylem",
SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay
203,
9051,
Reagent.BatWing,
Reagent.GraveDust
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 20.0; } }
public override int RequiredMana{ get{ return 11; } }
@ -59,6 +60,7 @@ namespace Server.Spells.Necromancy
double ss = GetDamageSkill( Caster );
double mr = ( Caster == m ? 0.0 : GetResistSkill( m ) );
m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain
TimeSpan duration = TimeSpan.FromSeconds( ((ss - mr) / 2.5) + 40.0 );

View file

@ -10,12 +10,13 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Curse Weapon", "An Sanct Gra Char",
SpellCircle.First, // 0.5 + 0.25 = 0.75s base cast delay
203,
9031,
Reagent.PigIron
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.75 ); } }
public override double RequiredSkill{ get{ return 0.0; } }
public override int RequiredMana{ get{ return 7; } }

View file

@ -11,13 +11,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Evil Omen", "Pas Tym An Sanct",
SpellCircle.First, // 0.5 + 0.25 = 0.75s base cast delay
203,
9031,
Reagent.BatWing,
Reagent.NoxCrystal
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.75 ); } }
public override double RequiredSkill{ get{ return 20.0; } }
public override int RequiredMana{ get{ return 11; } }

View file

@ -14,13 +14,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Exorcism", "Ort Corp Grav",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.NoxCrystal,
Reagent.GraveDust
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill { get { return 80.0; } }
public override int RequiredMana { get { return 40; } }
@ -42,7 +43,7 @@ namespace Server.Spells.Necromancy
public override bool DelayedDamage { get { return false; } }
private const int Range = 18;
private static readonly int Range = (Core.ML ? 48 : 18);
public override int ComputeKarmaAward()
{
@ -59,10 +60,6 @@ namespace Server.Spells.Necromancy
}
else if( CheckSequence() )
{
/* Creates a withering frost around the Caster,
* which deals Cold Damage to all valid targets in a radius of 5 tiles.
*/
Map map = Caster.Map;
if( map != null )
@ -73,17 +70,11 @@ namespace Server.Spells.Necromancy
if( IsValidTarget( m ) )
targets.Add( m );
//Effects.PlaySound( Caster.Location, map, 0x1FB );
//Effects.PlaySound( Caster.Location, map, 0x10B );
//Effects.SendLocationParticles( EffectItem.Create( Caster.Location, map, EffectItem.DefaultDuration ), 0x37CC, 1, 40, 97, 3, 9917, 0 );
for( int i = 0; i < targets.Count; ++i )
{
Mobile m = targets[i];
//m.FixedParticles( 0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255 );
//Suprisingly, no effects
//Suprisingly, no sparkle type effects
m.Location = GetNearestShrine( m );
}
@ -97,10 +88,6 @@ namespace Server.Spells.Necromancy
{
if( !m.Player || m.Alive )
return false;
/*
if( m.Corpse != null && m.Corpse.Map == m.Map )
return false;
* */
Corpse c = m.Corpse as Corpse;
Map map = m.Map;

View file

@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Horrific Beast", "Rel Xen Vas Bal",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.BatWing,
Reagent.DaemonBlood
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 40.0; } }
public override int RequiredMana{ get{ return 11; } }
@ -26,10 +27,17 @@ namespace Server.Spells.Necromancy
{
}
public override void PlayEffect( Mobile m )
public override void DoEffect( Mobile m )
{
m.PlaySound( 0x165 );
m.FixedParticles( 0x3728, 1, 13, 9918, 92, 3, EffectLayer.Head );
m.Delta( MobileDelta.WeaponDamage );
}
public override void RemoveEffect( Mobile m )
{
m.Delta( MobileDelta.WeaponDamage );
}
}
}

View file

@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Lich Form", "Rel Xen Corp Ort",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.GraveDust,
@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy
Reagent.NoxCrystal
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 70.0; } }
public override int RequiredMana{ get{ return 23; } }
@ -33,7 +34,7 @@ namespace Server.Spells.Necromancy
{
}
public override void PlayEffect( Mobile m )
public override void DoEffect( Mobile m )
{
m.PlaySound( 0x19C );
m.FixedParticles( 0x3709, 1, 30, 9904, 1108, 6, EffectLayer.RightFoot );

View file

@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Mind Rot", "Wis An Ben",
SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay
203,
9031,
Reagent.BatWing,
@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy
Reagent.DaemonBlood
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return 30.0; } }
public override int RequiredMana{ get{ return 17; } }
@ -50,6 +51,7 @@ namespace Server.Spells.Necromancy
m.FixedParticles( 0x373A, 1, 17, 9903, 15, 4, EffectLayer.Head );
TimeSpan duration = TimeSpan.FromSeconds( (((GetDamageSkill( Caster ) - GetResistSkill( m )) / 5.0) + 20.0) * (m.Player ? 1.0 : 2.0 ) );
m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain
if ( m.Player )
SetMindRotScalar( Caster, m, 1.25, duration );

View file

@ -11,9 +11,11 @@ namespace Server.Spells.Necromancy
public override SkillName CastSkill{ get{ return SkillName.Necromancy; } }
public override SkillName DamageSkill{ get{ return SkillName.SpiritSpeak; } }
//public override int CastDelayBase{ get{ return base.CastDelayBase; } } // Reference, 3
public override bool ClearHandsOnCast{ get{ return false; } }
public override int CastDelayFastScalar{ get{ return (Core.SE? base.CastDelayFastScalar : 0); } } // Necromancer spells are not effected by fast cast items, though they are by fast cast recovery
public override double CastDelayFastScalar{ get{ return (Core.SE? base.CastDelayFastScalar : 0); } } // Necromancer spells are not affected by fast cast items, though they are by fast cast recovery
public NecromancerSpell( Mobile caster, Item scroll, SpellInfo info ) : base( caster, scroll, info )
{
@ -21,7 +23,11 @@ namespace Server.Spells.Necromancy
public override int ComputeKarmaAward()
{
return -(70 + (10 * (int)Circle));
//TODO: Verify this formula being that Necro spells don't HAVE a circle.
//return -(70 + (10 * (int)Circle));
return -(40 + (int)(10 * (CastDelayBase.TotalSeconds / CastDelaySecondsPerTick)));
}
public override void GetCastSkills( out double min, out double max )

View file

@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Pain Spike", "In Sar",
SpellCircle.Second, // 0.5 + 0.5 = 1s base cast delay
203,
9031,
Reagent.GraveDust,
Reagent.PigIron
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } }
public override double RequiredSkill{ get{ return 20.0; } }
public override int RequiredMana{ get{ return 5; } }
@ -37,7 +38,7 @@ namespace Server.Spells.Necromancy
{
SpellHelper.Turn( Caster, m );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
//SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); //Irrelevent asfter AoS
/* Temporarily causes intense physical pain to the target, dealing direct damage.
* After 10 seconds the spell wears off, and if the target is still alive,
@ -49,6 +50,7 @@ namespace Server.Spells.Necromancy
m.PlaySound( 0x210 );
double damage = ((GetDamageSkill( Caster ) - GetResistSkill( m )) / 10) + (m.Player ? 18 : 30);
m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain
if ( damage < 1 )
damage = 1;

View file

@ -10,17 +10,18 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Poison Strike", "In Vas Nox",
(Core.ML ? SpellCircle.Fifth : // 0.5 + 1.25 = 1.75s base cast delay
SpellCircle.Fourth), // 0.5 + 1.0 = 1.5s base cast delay
203,
9031,
Reagent.NoxCrystal
);
public override double RequiredSkill{ get{ return 50.0; } }
public override int RequiredMana{ get{ return 17; } }
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( (Core.ML ? 1.75 : 1.5) ); } }
public PoisonStrikeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
public override double RequiredSkill { get { return 50.0; } }
public override int RequiredMana { get { return 17; } }
public PoisonStrikeSpell( Mobile caster, Item scroll )
: base( caster, scroll, m_Info )
{
}
@ -29,11 +30,11 @@ namespace Server.Spells.Necromancy
Caster.Target = new InternalTarget( this );
}
public override bool DelayedDamage{ get{ return false; } }
public override bool DelayedDamage { get { return false; } }
public void Target( Mobile m )
{
if ( CheckHSequence( m ) )
if( CheckHSequence( m ) )
{
SpellHelper.Turn( Caster, m );
@ -42,7 +43,7 @@ namespace Server.Spells.Necromancy
* One tile from main target receives 50% damage, two tiles from target receives 33% damage.
*/
CheckResisted( m ); // Check magic resist for skill, but do not use return value
//CheckResisted( m ); // Check magic resist for skill, but do not use return value //reports from OSI: Necro spells don't give Resist gain
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 63, 7, 9915, 0 );
Effects.PlaySound( m.Location, m.Map, 0x229 );
@ -51,23 +52,23 @@ namespace Server.Spells.Necromancy
Map map = m.Map;
if ( map != null )
if( map != null )
{
List<Mobile> targets = new List<Mobile>();
foreach ( Mobile targ in m.GetMobilesInRange( 2 ) )
if ( (Caster == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) )
foreach( Mobile targ in m.GetMobilesInRange( 2 ) )
if( (Caster == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) )
targets.Add( targ );
for ( int i = 0; i < targets.Count; ++i )
for( int i = 0; i < targets.Count; ++i )
{
Mobile targ = targets[i];
int num;
if ( targ.InRange( m.Location, 0 ) )
if( targ.InRange( m.Location, 0 ) )
num = 1;
else if ( targ.InRange( m.Location, 1 ) )
else if( targ.InRange( m.Location, 1 ) )
num = 2;
else
num = 3;
@ -85,15 +86,16 @@ namespace Server.Spells.Necromancy
{
private PoisonStrikeSpell m_Owner;
public InternalTarget( PoisonStrikeSpell owner ) : base( 12, false, TargetFlags.Harmful )
public InternalTarget( PoisonStrikeSpell 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 );
if( o is Mobile )
m_Owner.Target( (Mobile)o );
}
protected override void OnTargetFinish( Mobile from )

View file

@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Strangle", "In Bal Nox",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
209,
9031,
Reagent.DaemonBlood,
Reagent.NoxCrystal
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 65.0; } }
public override int RequiredMana{ get{ return 29; } }
@ -35,7 +36,7 @@ namespace Server.Spells.Necromancy
{
SpellHelper.Turn( Caster, m );
SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m );
//SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); //Irrelevent after AoS
/* Temporarily chokes off the air suply of the target with poisonous fumes.
* The target is inflicted with poison damage over time.

View file

@ -12,7 +12,6 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Summon Familiar", "Kal Xen Bal",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.BatWing,
@ -20,6 +19,8 @@ namespace Server.Spells.Necromancy
Reagent.DaemonBlood
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 30.0; } }
public override int RequiredMana{ get{ return 17; } }

View file

@ -7,7 +7,7 @@ using Server.Spells.Seventh;
namespace Server.Spells.Necromancy
{
public abstract class TransformationSpell : NecromancerSpell
public abstract class TransformationSpell : NecromancerSpell, ITransformationSpell
{
public abstract int Body{ get; }
public virtual int Hue{ get{ return 0; } }
@ -26,116 +26,15 @@ namespace Server.Spells.Necromancy
public override bool CheckCast()
{
/*if ( Caster.Mounted )
{
Caster.SendLocalizedMessage( 1042561 ); // Please dismount first.
if( !TransformationSpellHelper.CheckCast( Caster, this ) )
return false;
}
else */
if ( Factions.Sigil.ExistsOn( Caster ) )
{
Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
return false;
}
else if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
return false;
}
else if ( Spells.Ninjitsu.AnimalForm.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
return false;
}
return base.CheckCast();
}
public override void OnCast()
{
Mobile caster = this.Caster;
/*if ( caster.Mounted )
{
caster.SendLocalizedMessage( 1042561 ); // Please dismount first.
}
else */
if ( Factions.Sigil.ExistsOn( Caster ) )
{
Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
}
else if ( !caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
}
else if ( Spells.Ninjitsu.AnimalForm.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
}
else if ( !caster.CanBeginAction( typeof( IncognitoSpell ) ) || (caster.IsBodyMod && GetContext( caster ) == null) )
{
DoFizzle();
}
else if ( CheckSequence() )
{
TransformContext context = GetContext( caster );
Type ourType = this.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 )
{
List<ResistanceMod> mods = new List<ResistanceMod>();
if ( PhysResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Physical, PhysResistOffset ) );
if ( FireResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Fire, FireResistOffset ) );
if ( ColdResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Cold, ColdResistOffset ) );
if ( PoisResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Poison, PoisResistOffset ) );
if ( NrgyResistOffset != 0 )
mods.Add( new ResistanceMod( ResistanceType.Energy, NrgyResistOffset ) );
if ( !((Body)this.Body).IsHuman )
{
Mobiles.IMount mt = Caster.Mount;
if ( mt != null )
mt.Rider = null;
}
caster.BodyMod = this.Body;
caster.HueMod = this.Hue;
for ( int i = 0; i < mods.Count; ++i )
caster.AddResistanceMod( mods[i] );
PlayEffect( caster );
Timer timer = new TransformTimer( caster, this );
timer.Start();
AddContext( caster, new TransformContext( timer, mods, ourType ) );
}
}
TransformationSpellHelper.OnCast( Caster, this );
FinishSequence();
}
@ -146,109 +45,12 @@ namespace Server.Spells.Necromancy
{
}
public virtual void PlayEffect( Mobile m )
public virtual void DoEffect( Mobile m )
{
}
private static Hashtable m_Table = new Hashtable();
public static void AddContext( Mobile m, TransformContext context )
public virtual void RemoveEffect( Mobile m )
{
m_Table[m] = context;
if ( context.Type == typeof( HorrificBeastSpell ) )
m.Delta( MobileDelta.WeaponDamage );
}
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 )
{
m_Table.Remove( m );
List<ResistanceMod> mods = context.Mods;
for ( int i = 0; i < mods.Count; ++i )
m.RemoveResistanceMod( mods[i] );
if ( resetGraphics )
{
m.HueMod = -1;
m.BodyMod = 0;
}
context.Timer.Stop();
if ( context.Type == typeof( HorrificBeastSpell ) )
m.Delta( MobileDelta.WeaponDamage );
}
public static TransformContext GetContext( Mobile m )
{
return ( m_Table[m] as TransformContext );
}
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 );
}
}
public class TransformContext
{
private Timer m_Timer;
private List<ResistanceMod> m_Mods;
private Type m_Type;
public Timer Timer{ get{ return m_Timer; } }
public List<ResistanceMod> Mods{ get{ return m_Mods; } }
public Type Type{ get{ return m_Type; } }
public TransformContext( Timer timer, List<ResistanceMod> mods, Type type )
{
m_Timer = timer;
m_Mods = mods;
m_Type = type;
}
}
public class TransformTimer : Timer
{
private Mobile m_Mobile;
private TransformationSpell m_Spell;
public TransformTimer( Mobile from, TransformationSpell 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 )
{
TransformationSpell.RemoveContext( m_Mobile, true );
Stop();
}
else
{
m_Spell.OnTick( m_Mobile );
}
}
}
}

View file

@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Vampiric Embrace", "Rel Xen An Sanct",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.BatWing,
@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy
Reagent.PigIron
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 99.0; } }
public override int RequiredMana{ get{ return 23; } }
@ -43,7 +44,7 @@ namespace Server.Spells.Necromancy
}
}
public override void PlayEffect( Mobile m )
public override void DoEffect( Mobile m )
{
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x373A, 1, 17, 1108, 7, 9914, 0 );
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x376A, 1, 22, 67, 7, 9502, 0 );

View file

@ -11,7 +11,6 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Vengeful Spirit", "Kal Xen Bal Beh",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.BatWing,
@ -19,6 +18,8 @@ namespace Server.Spells.Necromancy
Reagent.PigIron
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 80.0; } }
public override int RequiredMana{ get{ return 41; } }

View file

@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Wither", "Kal Vas An Flam",
SpellCircle.Third, // 0.5 + 0.75 = 1.25s base cast delay
203,
9031,
Reagent.NoxCrystal,
@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy
Reagent.PigIron
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.25 ); } }
public override double RequiredSkill{ get{ return 60.0; } }
public override int RequiredMana{ get{ return 23; } }

View file

@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Wraith Form", "Rel Xen Um",
SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay
203,
9031,
Reagent.NoxCrystal,
Reagent.PigIron
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
public override double RequiredSkill{ get{ return 20.0; } }
public override int RequiredMana{ get{ return 17; } }
@ -33,7 +34,7 @@ namespace Server.Spells.Necromancy
{
}
public override void PlayEffect( Mobile m )
public override void DoEffect( Mobile m )
{
m.PlaySound( 0x17F );
m.FixedParticles( 0x374A, 1, 15, 9902, 1108, 4, EffectLayer.Waist );

View file

@ -22,16 +22,17 @@ namespace Server.Spells.Ninjitsu
AnimalFormContext context = AnimalForm.GetContext( e.Mobile );
if( context != null && context.SpeedBoost )
e.Mobile.Send( SpeedBoost.Enabled );
e.Mobile.Send( SpeedControl.MountSpeed );
}
private static SpellInfo m_Info = new SpellInfo(
"Animal Form", null,
SpellCircle.Fourth, // 1.0s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } }
public override double RequiredSkill{ get{ return 0.0; } }
public override int RequiredMana{ get{ return (Core.ML ? 10 : 0); } }
public override int CastRecoveryBase{ get { return (Core.ML ? 10 : base.CastRecoveryBase); } }
@ -49,7 +50,7 @@ namespace Server.Spells.Ninjitsu
Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
return false;
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) )
else if ( TransformationSpellHelper.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1063219 ); // You cannot mimic an animal while in that form.
return false;
@ -82,7 +83,7 @@ namespace Server.Spells.Ninjitsu
{
Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed.
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) )
else if( TransformationSpellHelper.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1063219 ); // You cannot mimic an animal while in that form.
}
@ -154,6 +155,13 @@ namespace Server.Spells.Ninjitsu
return MorphResult.NoSkill;
}
/*
if( !m.CheckSkill( SkillName.Ninjitsu, entry.ReqSkill, entry.ReqSkill + 37.5 ) )
return MorphResult.Fail;
*
* On OSI,it seems you can only gain starting at '0' using Animal form.
*/
double ninjitsu = m.Skills.Ninjitsu.Value;
if ( ninjitsu < entry.ReqSkill + 37.5 )
@ -174,7 +182,7 @@ namespace Server.Spells.Ninjitsu
m.HueMod = entry.HueMod;
if ( entry.SpeedBoost )
m.Send( SpeedBoost.Instantiate( true ) );
m.Send( SpeedControl.MountSpeed );
SkillMod mod = null;
@ -216,7 +224,7 @@ namespace Server.Spells.Ninjitsu
m_Table.Remove( m );
if ( context.SpeedBoost )
m.Send( SpeedBoost.Instantiate( false ) );
m.Send( SpeedControl.Disable );
SkillMod mod = context.Mod;

View file

@ -10,14 +10,12 @@ namespace Server.Spells.Ninjitsu
{
public class Backstab : NinjaMove
{
// TODO: Cannot hide for 5s
public Backstab()
{
}
public override int BaseMana{ get{ return 30; } }
public override double RequiredSkill{ get{ return 20.0; } }
public override double RequiredSkill{ get{ return Core.ML ? 40.0 : 20.0; } }
public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063089 ); } } // You prepare to Backstab your opponent.
@ -41,7 +39,16 @@ namespace Server.Spells.Ninjitsu
public override bool OnBeforeSwing( Mobile attacker, Mobile defender )
{
return Validate( attacker ) && CheckMana( attacker, true );
bool valid = Validate( attacker ) && CheckMana( attacker, true );
if( valid )
{
attacker.BeginAction( typeof( Stealth ) );
Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), delegate { attacker.EndAction( typeof( Stealth ) ); } );
}
return valid;
}
public override bool ValidatesDuringHit { get { return false; } }

View file

@ -9,14 +9,12 @@ namespace Server.Spells.Ninjitsu
{
public class FocusAttack : NinjaMove
{
// TODO: Display property bonus on equipped weapons.
public FocusAttack()
{
}
public override int BaseMana{ get{ return 20; } }
public override double RequiredSkill{ get{ return 60.0; } }
public override int BaseMana{ get{ return Core.ML ? 10 : 20; } }
public override double RequiredSkill{ get{ return Core.ML? 30.0 : 60 ; } }
public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063095 ); } } // You prepare to focus all of your abilities into your next strike.

View file

@ -11,7 +11,7 @@ namespace Server.Spells.Ninjitsu
{
public class MirrorImage : NinjaSpell
{
private static Dictionary<Mobile, Int32> m_CloneCount = new Dictionary<Mobile, Int32>();
private static Dictionary<Mobile, int> m_CloneCount = new Dictionary<Mobile, int>();
public static bool HasClone( Mobile m )
{
@ -45,12 +45,13 @@ namespace Server.Spells.Ninjitsu
private static SpellInfo m_Info = new SpellInfo(
"Mirror Image", null,
SpellCircle.Sixth, // 1.5s base cast delay
-1,
9002
);
public override double RequiredSkill{ get{ return 40.0; } }
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } }
public override double RequiredSkill{ get{ return Core.ML ? 20.0 : 40.0; } }
public override int RequiredMana{ get{ return 10; } }
public override bool BlockedByAnimalForm{ get{ return false; } }
@ -71,7 +72,7 @@ namespace Server.Spells.Ninjitsu
Caster.SendLocalizedMessage( 1063133 ); // You cannot summon a mirror image because you have too many followers.
return false;
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) )
else if( TransformationSpellHelper.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) )
{
Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
return false;
@ -102,7 +103,7 @@ namespace Server.Spells.Ninjitsu
{
Caster.SendLocalizedMessage( 1063133 ); // You cannot summon a mirror image because you have too many followers.
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) )
else if( TransformationSpellHelper.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) )
{
Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
}

View file

@ -10,5 +10,10 @@ namespace Server.Spells
public class NinjaMove : SpecialMove
{
public override SkillName MoveSkill{ get{ return SkillName.Ninjitsu; } }
public override void CheckGain( Mobile m )
{
m.CheckSkill( MoveSkill, RequiredSkill - 12.5, RequiredSkill + 37.5 ); //Per five on friday 02/16/07
}
}
}

View file

@ -20,7 +20,8 @@ namespace Server.Spells.Ninjitsu
public override bool BlocksMovement{ get{ return false; } }
public override int CastDelayBase{ get{ return 1; } }
//public override int CastDelayBase{ get{ return 1; } }
public override double CastDelayFastScalar { get { return 0; } }
public override int CastRecoveryBase{ get{ return 7; } }
@ -36,7 +37,8 @@ namespace Server.Spells.Ninjitsu
if ( from.NetState == null )
return false;
return ( (from.NetState.Flags & 0x10) != 0 );
//return ( (from.NetState.Flags & 0x10) != 0 );
return from.NetState.SupportsExpansion( Expansion.SE );
}
public override bool CheckCast()
@ -90,7 +92,7 @@ namespace Server.Spells.Ninjitsu
public override void GetCastSkills( out double min, out double max )
{
min = RequiredSkill;
min = RequiredSkill - 12.5; //Per 5 on friday 2/16/07
max = RequiredSkill + 37.5;
}

View file

@ -11,11 +11,12 @@ namespace Server.Spells.Ninjitsu
{
private static SpellInfo m_Info = new SpellInfo(
"Shadowjump", null,
SpellCircle.Fourth, // 1.0s base cast delay
-1,
9002
);
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } }
public override double RequiredSkill{ get{ return 50.0; } }
public override int RequiredMana{ get{ return 15; } }

View file

@ -10,14 +10,12 @@ namespace Server.Spells.Ninjitsu
{
public class SurpriseAttack : NinjaMove
{
// TODO: Cannot hide for 5s
public SurpriseAttack()
{
}
public override int BaseMana{ get{ return 20; } }
public override double RequiredSkill{ get{ return 30.0; } }
public override double RequiredSkill{ get{ return Core.ML ? 60.0 : 30.0; } }
public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063128 ); } } // You prepare to surprise your prey.
@ -34,7 +32,16 @@ namespace Server.Spells.Ninjitsu
public override bool OnBeforeSwing( Mobile attacker, Mobile defender )
{
return Validate( attacker ) && CheckMana( attacker, true );
bool valid = Validate( attacker ) && CheckMana( attacker, true );
if( valid )
{
attacker.BeginAction( typeof( Stealth ) );
Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), delegate { attacker.EndAction( typeof( Stealth ) ); } );
}
return valid;
}
public override bool ValidatesDuringHit { get { return false; } }

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Second
{
public class AgilitySpell : Spell
public class AgilitySpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Agility", "Ex Uus",
SpellCircle.Second,
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 )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Second
{
public class CunningSpell : Spell
public class CunningSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Cunning", "Uus Wis",
SpellCircle.Second,
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 )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Second
{
public class CureSpell : Spell
public class CureSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Cure", "An Nox",
SpellCircle.Second,
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 )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Second
{
public class HarmSpell : Spell
public class HarmSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Harm", "An Mani",
SpellCircle.Second,
212,
Core.AOS ? 9001 : 9041,
Reagent.Nightshade,
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public HarmSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,11 +5,10 @@ using Server.Items;
namespace Server.Spells.Second
{
public class MagicTrapSpell : Spell
public class MagicTrapSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Trap", "In Jux",
SpellCircle.Second,
212,
9001,
Reagent.Garlic,
@ -17,6 +16,8 @@ namespace Server.Spells.Second
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public MagicTrapSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,14 +5,13 @@ using Server.Network;
namespace Server.Spells.Second
{
public class ProtectionSpell : Spell
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",
SpellCircle.Second,
236,
9011,
Reagent.Garlic,
@ -20,6 +19,8 @@ namespace Server.Spells.Second
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Second; } }
public ProtectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -5,17 +5,18 @@ using Server.Items;
namespace Server.Spells.Second
{
public class RemoveTrapSpell : Spell
public class RemoveTrapSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Remove Trap", "An Jux",
SpellCircle.Second,
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 )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Second
{
public class StrengthSpell : Spell
public class StrengthSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Strength", "Uus Mani",
SpellCircle.Second,
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 )
{
}

View file

@ -6,11 +6,10 @@ using Server.Targeting;
namespace Server.Spells.Seventh
{
public class ChainLightningSpell : Spell
public class ChainLightningSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Chain Lightning", "Vas Ort Grav",
SpellCircle.Seventh,
209,
9022,
false,
@ -20,6 +19,8 @@ namespace Server.Spells.Seventh
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public ChainLightningSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -6,11 +6,10 @@ using Server.Items;
namespace Server.Spells.Seventh
{
public class EnergyFieldSpell : Spell
public class EnergyFieldSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Energy Field", "In Sanct Grav",
SpellCircle.Seventh,
221,
9022,
false,
@ -20,6 +19,8 @@ namespace Server.Spells.Seventh
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public EnergyFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Seventh
{
public class FlameStrikeSpell : Spell
public class FlameStrikeSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Flame Strike", "Kal Vas Flam",
SpellCircle.Seventh,
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 )
{
}

View file

@ -9,11 +9,10 @@ using Server.Mobiles;
namespace Server.Spells.Seventh
{
public class GateTravelSpell : Spell
public class GateTravelSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Gate Travel", "Vas Rel Por",
SpellCircle.Seventh,
263,
9032,
Reagent.BlackPearl,
@ -21,6 +20,8 @@ namespace Server.Spells.Seventh
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
private RunebookEntry m_Entry;
public GateTravelSpell( Mobile caster, Item scroll ) : this( caster, scroll, null )

View file

@ -4,11 +4,10 @@ using Server.Network;
namespace Server.Spells.Seventh
{
public class ManaVampireSpell : Spell
public class ManaVampireSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mana Vampire", "Ort Sanct",
SpellCircle.Seventh,
221,
9032,
Reagent.BlackPearl,
@ -17,6 +16,8 @@ namespace Server.Spells.Seventh
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public ManaVampireSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -8,11 +8,10 @@ using Server.Mobiles;
namespace Server.Spells.Seventh
{
public class MassDispelSpell : Spell
public class MassDispelSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Mass Dispel", "Vas An Ort",
SpellCircle.Seventh,
263,
9002,
Reagent.Garlic,
@ -21,6 +20,8 @@ namespace Server.Spells.Seventh
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public MassDispelSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -6,11 +6,10 @@ using Server.Targeting;
namespace Server.Spells.Seventh
{
public class MeteorSwarmSpell : Spell
public class MeteorSwarmSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Meteor Swarm", "Flam Kal Des Ylem",
SpellCircle.Seventh,
233,
9042,
false,
@ -20,6 +19,8 @@ namespace Server.Spells.Seventh
Reagent.SpidersSilk
);
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
public MeteorSwarmSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -8,11 +8,10 @@ using Server.Spells.Fifth;
namespace Server.Spells.Seventh
{
public class PolymorphSpell : Spell
public class PolymorphSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Polymorph", "Vas Ylem Rel",
SpellCircle.Seventh,
221,
9002,
Reagent.Bloodmoss,
@ -20,6 +19,8 @@ namespace Server.Spells.Seventh
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 )
@ -44,7 +45,7 @@ namespace Server.Spells.Seventh
Caster.SendLocalizedMessage( 1010521 ); // You cannot polymorph while you have a Town Sigil
return false;
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) )
else if( TransformationSpellHelper.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1061633 ); // You cannot polymorph while in that form.
return false;
@ -100,7 +101,7 @@ namespace Server.Spells.Seventh
else
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) )
else if( TransformationSpellHelper.UnderTransformation( Caster ) )
{
Caster.SendLocalizedMessage( 1061633 ); // You cannot polymorph while in that form.
}

View file

@ -7,11 +7,10 @@ using Server.Mobiles;
namespace Server.Spells.Sixth
{
public class DispelSpell : Spell
public class DispelSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Dispel", "An Ort",
SpellCircle.Sixth,
218,
9002,
Reagent.Garlic,
@ -19,6 +18,8 @@ namespace Server.Spells.Sixth
Reagent.SulfurousAsh
);
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
public DispelSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Sixth
{
public class EnergyBoltSpell : Spell
public class EnergyBoltSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Energy Bolt", "Corp Por",
SpellCircle.Sixth,
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 )
{
}

View file

@ -4,17 +4,18 @@ using Server.Network;
namespace Server.Spells.Sixth
{
public class ExplosionSpell : Spell
public class ExplosionSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Explosion", "Vas Ort Flam",
SpellCircle.Sixth,
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 )
{
@ -52,11 +53,11 @@ namespace Server.Spells.Sixth
private class InternalTimer : Timer
{
private Spell m_Spell;
private MagerySpell m_Spell;
private Mobile m_Target;
private Mobile m_Attacker, m_Defender;
public InternalTimer( Spell spell, Mobile attacker, Mobile defender, Mobile target )
public InternalTimer( MagerySpell spell, Mobile attacker, Mobile defender, Mobile target )
: base( TimeSpan.FromSeconds( Core.AOS ? 3.0 : 2.5 ) )
{
m_Spell = spell;

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