Fixes code according to modern code style. Fixes a few expression bugs.
This commit is contained in:
parent
89eea25e5f
commit
970fd563b2
3324 changed files with 441118 additions and 433755 deletions
|
|
@ -1,12 +1,12 @@
|
|||
namespace Server.Spells
|
||||
{
|
||||
public enum DisturbType
|
||||
{
|
||||
Unspecified,
|
||||
EquipRequest,
|
||||
UseRequest,
|
||||
Hurt,
|
||||
Kill,
|
||||
NewCast
|
||||
}
|
||||
public enum DisturbType
|
||||
{
|
||||
Unspecified,
|
||||
EquipRequest,
|
||||
UseRequest,
|
||||
Hurt,
|
||||
Kill,
|
||||
NewCast
|
||||
}
|
||||
}
|
||||
|
|
@ -3,107 +3,109 @@ 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 class MagerySpell : Spell
|
||||
{
|
||||
private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0;
|
||||
|
||||
public abstract SpellCircle Circle { get; }
|
||||
private static int[] m_ManaTable = { 4, 6, 9, 11, 14, 20, 40, 50 };
|
||||
|
||||
public override bool ConsumeReagents()
|
||||
{
|
||||
if ( base.ConsumeReagents() )
|
||||
return true;
|
||||
public MagerySpell(Mobile caster, Item scroll, SpellInfo info)
|
||||
: base(caster, scroll, info)
|
||||
{
|
||||
}
|
||||
|
||||
if ( ArcaneGem.ConsumeCharges( Caster, (Core.SE ? 1 : 1 + (int)Circle) ) )
|
||||
return true;
|
||||
public abstract SpellCircle Circle{ get; }
|
||||
|
||||
return false;
|
||||
}
|
||||
public override TimeSpan CastDelayBase => TimeSpan.FromSeconds((3 + (int)Circle) * CastDelaySecondsPerTick);
|
||||
|
||||
private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0;
|
||||
public override bool ConsumeReagents()
|
||||
{
|
||||
if (base.ConsumeReagents())
|
||||
return true;
|
||||
|
||||
public override void GetCastSkills( out double min, out double max )
|
||||
{
|
||||
int circle = (int)Circle;
|
||||
if (ArcaneGem.ConsumeCharges(Caster, Core.SE ? 1 : 1 + (int)Circle))
|
||||
return true;
|
||||
|
||||
if ( Scroll != null )
|
||||
circle -= 2;
|
||||
return false;
|
||||
}
|
||||
|
||||
double avg = ChanceLength * circle;
|
||||
public override void GetCastSkills(out double min, out double max)
|
||||
{
|
||||
int circle = (int)Circle;
|
||||
|
||||
min = avg - ChanceOffset;
|
||||
max = avg + ChanceOffset;
|
||||
}
|
||||
if (Scroll != null)
|
||||
circle -= 2;
|
||||
|
||||
private static int[] m_ManaTable = { 4, 6, 9, 11, 14, 20, 40, 50 };
|
||||
double avg = ChanceLength * circle;
|
||||
|
||||
public override int GetMana()
|
||||
{
|
||||
if ( Scroll is BaseWand )
|
||||
return 0;
|
||||
min = avg - ChanceOffset;
|
||||
max = avg + ChanceOffset;
|
||||
}
|
||||
|
||||
return m_ManaTable[(int)Circle];
|
||||
}
|
||||
public override int GetMana()
|
||||
{
|
||||
if (Scroll is BaseWand)
|
||||
return 0;
|
||||
|
||||
public override double GetResistSkill( Mobile m )
|
||||
{
|
||||
int maxSkill = (1 + (int)Circle) * 10;
|
||||
maxSkill += (1 + ((int)Circle / 6)) * 25;
|
||||
return m_ManaTable[(int)Circle];
|
||||
}
|
||||
|
||||
if ( m.Skills[SkillName.MagicResist].Value < maxSkill )
|
||||
m.CheckSkill( SkillName.MagicResist, 0.0, m.Skills[SkillName.MagicResist].Cap );
|
||||
public override double GetResistSkill(Mobile m)
|
||||
{
|
||||
int maxSkill = (1 + (int)Circle) * 10;
|
||||
maxSkill += (1 + (int)Circle / 6) * 25;
|
||||
|
||||
return m.Skills[SkillName.MagicResist].Value;
|
||||
}
|
||||
if (m.Skills[SkillName.MagicResist].Value < maxSkill)
|
||||
m.CheckSkill(SkillName.MagicResist, 0.0, m.Skills[SkillName.MagicResist].Cap);
|
||||
|
||||
public virtual bool CheckResisted( Mobile target )
|
||||
{
|
||||
double n = GetResistPercent( target );
|
||||
return m.Skills[SkillName.MagicResist].Value;
|
||||
}
|
||||
|
||||
n /= 100.0;
|
||||
public virtual bool CheckResisted(Mobile target)
|
||||
{
|
||||
double n = GetResistPercent(target);
|
||||
|
||||
if ( n <= 0.0 )
|
||||
return false;
|
||||
n /= 100.0;
|
||||
|
||||
if ( n >= 1.0 )
|
||||
return true;
|
||||
if (n <= 0.0)
|
||||
return false;
|
||||
|
||||
int maxSkill = (1 + (int)Circle) * 10;
|
||||
maxSkill += (1 + ((int)Circle / 6)) * 25;
|
||||
if (n >= 1.0)
|
||||
return true;
|
||||
|
||||
if ( target.Skills[SkillName.MagicResist].Value < maxSkill )
|
||||
target.CheckSkill( SkillName.MagicResist, 0.0, target.Skills[SkillName.MagicResist].Cap );
|
||||
int maxSkill = (1 + (int)Circle) * 10;
|
||||
maxSkill += (1 + (int)Circle / 6) * 25;
|
||||
|
||||
return (n >= Utility.RandomDouble());
|
||||
}
|
||||
if (target.Skills[SkillName.MagicResist].Value < maxSkill)
|
||||
target.CheckSkill(SkillName.MagicResist, 0.0, target.Skills[SkillName.MagicResist].Cap);
|
||||
|
||||
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 n >= Utility.RandomDouble();
|
||||
}
|
||||
|
||||
return (firstPercent > secondPercent ? firstPercent : secondPercent) / 2.0; // Seems should be about half of what stratics says.
|
||||
}
|
||||
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);
|
||||
|
||||
public virtual double GetResistPercent( Mobile target )
|
||||
{
|
||||
return GetResistPercentForCircle( target, Circle );
|
||||
}
|
||||
return (firstPercent > secondPercent ? firstPercent : secondPercent) /
|
||||
2.0; // Seems should be about half of what stratics says.
|
||||
}
|
||||
|
||||
public override TimeSpan GetCastDelay()
|
||||
{
|
||||
if ( !Core.ML && Scroll is BaseWand )
|
||||
return TimeSpan.Zero;
|
||||
public virtual double GetResistPercent(Mobile target)
|
||||
{
|
||||
return GetResistPercentForCircle(target, Circle);
|
||||
}
|
||||
|
||||
if ( !Core.AOS )
|
||||
return TimeSpan.FromSeconds( 0.5 + (0.25 * (int)Circle) );
|
||||
public override TimeSpan GetCastDelay()
|
||||
{
|
||||
if (!Core.ML && Scroll is BaseWand)
|
||||
return TimeSpan.Zero;
|
||||
|
||||
return base.GetCastDelay();
|
||||
}
|
||||
if (!Core.AOS)
|
||||
return TimeSpan.FromSeconds(0.5 + 0.25 * (int)Circle);
|
||||
|
||||
public override TimeSpan CastDelayBase => TimeSpan.FromSeconds( (3 + (int)Circle) * CastDelaySecondsPerTick );
|
||||
}
|
||||
}
|
||||
return base.GetCastDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,353 +1,352 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Spells.Bushido;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Spells.Ninjitsu;
|
||||
|
||||
namespace Server.Spells
|
||||
{
|
||||
public abstract class SpecialMove
|
||||
{
|
||||
public virtual int BaseMana => 0;
|
||||
|
||||
public virtual SkillName MoveSkill => SkillName.Bushido;
|
||||
public virtual double RequiredSkill => 0.0;
|
||||
|
||||
public virtual TextDefinition AbilityMessage => 0;
|
||||
|
||||
public virtual bool BlockedByAnimalForm => true;
|
||||
public virtual bool DelayedContext => false;
|
||||
|
||||
public virtual int GetAccuracyBonus( Mobile attacker )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual double GetDamageScalar( Mobile attacker, Mobile defender )
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// Called before swinging, to make sure the accuracy scalar is to be computed.
|
||||
public virtual bool OnBeforeSwing( Mobile attacker, Mobile defender )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when a hit connects, but before damage is calculated.
|
||||
public virtual bool OnBeforeDamage( Mobile attacker, Mobile defender )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called as soon as the ability is used.
|
||||
public virtual void OnUse( Mobile from )
|
||||
{
|
||||
}
|
||||
|
||||
// Called when a hit connects, at the end of the weapon.OnHit() method.
|
||||
public virtual void OnHit( Mobile attacker, Mobile defender, int damage )
|
||||
{
|
||||
}
|
||||
|
||||
// Called when a hit misses.
|
||||
public virtual void OnMiss( Mobile attacker, Mobile defender )
|
||||
{
|
||||
}
|
||||
|
||||
// Called when the move is cleared.
|
||||
public virtual void OnClearMove( Mobile from )
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool IgnoreArmor( Mobile attacker )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual double GetPropertyBonus( Mobile attacker )
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public virtual bool CheckSkills( Mobile m )
|
||||
{
|
||||
if ( m.Skills[MoveSkill].Value < RequiredSkill )
|
||||
{
|
||||
string args = $"{RequiredSkill.ToString("F1")}\t{MoveSkill.ToString()}\t ";
|
||||
m.SendLocalizedMessage( 1063013, args ); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual int ScaleMana( Mobile m, int mana )
|
||||
{
|
||||
double scalar = 1.0;
|
||||
|
||||
if ( !Necromancy.MindRotSpell.GetMindRotScalar( m, ref scalar ) )
|
||||
scalar = 1.0;
|
||||
|
||||
// Lower Mana Cost = 40%
|
||||
int lmc = Math.Min( AosAttributes.GetValue( m, AosAttribute.LowerManaCost ), 40 );
|
||||
|
||||
scalar -= (double)lmc / 100;
|
||||
|
||||
int total = (int)(mana * scalar);
|
||||
|
||||
if ( m.Skills[MoveSkill].Value < 50.0 && GetContext( m ) != null )
|
||||
total *= 2;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public virtual bool CheckMana( Mobile from, bool consume )
|
||||
{
|
||||
int mana = ScaleMana( from, BaseMana );
|
||||
|
||||
if ( from.Mana < mana )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060181, mana.ToString() ); // You need ~1_MANA_REQUIREMENT~ mana to perform that attack
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( consume )
|
||||
{
|
||||
if ( !DelayedContext )
|
||||
SetContext( from );
|
||||
|
||||
from.Mana -= mana;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void SetContext( Mobile from )
|
||||
{
|
||||
if ( GetContext( from ) == null )
|
||||
{
|
||||
if ( DelayedContext || from.Skills[MoveSkill].Value < 50.0 )
|
||||
{
|
||||
Timer timer = new SpecialMoveTimer( from );
|
||||
timer.Start();
|
||||
|
||||
AddContext( from, new SpecialMoveContext( timer, GetType() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Validate( Mobile from )
|
||||
{
|
||||
if ( !from.Player )
|
||||
return true;
|
||||
|
||||
if ( HonorableExecution.IsUnderPenalty( from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1063024 ); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( AnimalForm.UnderTransformation( from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1063024 ); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Dueling
|
||||
string option = null;
|
||||
|
||||
if ( this is Backstab )
|
||||
option = "Backstab";
|
||||
else if ( this is DeathStrike )
|
||||
option = "Death Strike";
|
||||
else if ( this is FocusAttack )
|
||||
option = "Focus Attack";
|
||||
else if ( this is KiAttack )
|
||||
option = "Ki Attack";
|
||||
else if ( this is SurpriseAttack )
|
||||
option = "Surprise Attack";
|
||||
else if ( this is HonorableExecution )
|
||||
option = "Honorable Execution";
|
||||
else if ( this is LightningStrike )
|
||||
option = "Lightning Strike";
|
||||
else if ( this is MomentumStrike )
|
||||
option = "Momentum Strike";
|
||||
|
||||
if ( option != null && !Engines.ConPVP.DuelContext.AllowSpecialMove( from, option, this ) )
|
||||
return false;
|
||||
#endregion
|
||||
|
||||
return CheckSkills( from ) && CheckMana( from, false );
|
||||
}
|
||||
|
||||
public virtual void CheckGain( Mobile m )
|
||||
{
|
||||
m.CheckSkill( MoveSkill, RequiredSkill, RequiredSkill + 37.5 );
|
||||
}
|
||||
public abstract class SpecialMove
|
||||
{
|
||||
private static Dictionary<Mobile, SpecialMoveContext> m_PlayersTable = new Dictionary<Mobile, SpecialMoveContext>();
|
||||
|
||||
public static Dictionary<Mobile, SpecialMove> Table { get; } = new Dictionary<Mobile, SpecialMove>();
|
||||
public virtual int BaseMana => 0;
|
||||
|
||||
public static void ClearAllMoves( Mobile m )
|
||||
{
|
||||
foreach ( KeyValuePair<int, SpecialMove> kvp in SpellRegistry.SpecialMoves )
|
||||
{
|
||||
int moveID = kvp.Key;
|
||||
|
||||
if ( moveID != -1 )
|
||||
m.Send( new ToggleSpecialAbility( moveID + 1, false ) );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool ValidatesDuringHit => true;
|
||||
|
||||
public static SpecialMove GetCurrentMove( Mobile m )
|
||||
{
|
||||
if ( m == null )
|
||||
return null;
|
||||
|
||||
if ( !Core.SE )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return null;
|
||||
}
|
||||
|
||||
Table.TryGetValue( m, out SpecialMove move );
|
||||
|
||||
if ( move != null && move.ValidatesDuringHit && !move.Validate( m ) )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return null;
|
||||
}
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public static bool SetCurrentMove( Mobile m, SpecialMove move )
|
||||
{
|
||||
if ( !Core.SE )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return false;
|
||||
}
|
||||
public virtual SkillName MoveSkill => SkillName.Bushido;
|
||||
public virtual double RequiredSkill => 0.0;
|
||||
|
||||
if ( move != null && !move.Validate( m ) )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return false;
|
||||
}
|
||||
public virtual TextDefinition AbilityMessage => 0;
|
||||
|
||||
bool sameMove = ( move == GetCurrentMove( m ) );
|
||||
|
||||
ClearCurrentMove( m );
|
||||
public virtual bool BlockedByAnimalForm => true;
|
||||
public virtual bool DelayedContext => false;
|
||||
|
||||
if ( sameMove )
|
||||
return true;
|
||||
public static Dictionary<Mobile, SpecialMove> Table{ get; } = new Dictionary<Mobile, SpecialMove>();
|
||||
|
||||
public virtual bool ValidatesDuringHit => true;
|
||||
|
||||
public virtual int GetAccuracyBonus(Mobile attacker)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( move != null )
|
||||
{
|
||||
WeaponAbility.ClearCurrentAbility( m );
|
||||
public virtual double GetDamageScalar(Mobile attacker, Mobile defender)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// Called before swinging, to make sure the accuracy scalar is to be computed.
|
||||
public virtual bool OnBeforeSwing(Mobile attacker, Mobile defender)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when a hit connects, but before damage is calculated.
|
||||
public virtual bool OnBeforeDamage(Mobile attacker, Mobile defender)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called as soon as the ability is used.
|
||||
public virtual void OnUse(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
// Called when a hit connects, at the end of the weapon.OnHit() method.
|
||||
public virtual void OnHit(Mobile attacker, Mobile defender, int damage)
|
||||
{
|
||||
}
|
||||
|
||||
// Called when a hit misses.
|
||||
public virtual void OnMiss(Mobile attacker, Mobile defender)
|
||||
{
|
||||
}
|
||||
|
||||
// Called when the move is cleared.
|
||||
public virtual void OnClearMove(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool IgnoreArmor(Mobile attacker)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual double GetPropertyBonus(Mobile attacker)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public virtual bool CheckSkills(Mobile m)
|
||||
{
|
||||
if (m.Skills[MoveSkill].Value < RequiredSkill)
|
||||
{
|
||||
string args = $"{RequiredSkill.ToString("F1")}\t{MoveSkill.ToString()}\t ";
|
||||
m.SendLocalizedMessage(1063013,
|
||||
args); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual int ScaleMana(Mobile m, int mana)
|
||||
{
|
||||
double scalar = 1.0;
|
||||
|
||||
if (!MindRotSpell.GetMindRotScalar(m, ref scalar))
|
||||
scalar = 1.0;
|
||||
|
||||
// Lower Mana Cost = 40%
|
||||
int lmc = Math.Min(AosAttributes.GetValue(m, AosAttribute.LowerManaCost), 40);
|
||||
|
||||
scalar -= (double)lmc / 100;
|
||||
|
||||
int total = (int)(mana * scalar);
|
||||
|
||||
if (m.Skills[MoveSkill].Value < 50.0 && GetContext(m) != null)
|
||||
total *= 2;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public virtual bool CheckMana(Mobile from, bool consume)
|
||||
{
|
||||
int mana = ScaleMana(from, BaseMana);
|
||||
|
||||
if (from.Mana < mana)
|
||||
{
|
||||
from.SendLocalizedMessage(1060181,
|
||||
mana.ToString()); // You need ~1_MANA_REQUIREMENT~ mana to perform that attack
|
||||
return false;
|
||||
}
|
||||
|
||||
if (consume)
|
||||
{
|
||||
if (!DelayedContext)
|
||||
SetContext(from);
|
||||
|
||||
from.Mana -= mana;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void SetContext(Mobile from)
|
||||
{
|
||||
if (GetContext(from) == null)
|
||||
if (DelayedContext || from.Skills[MoveSkill].Value < 50.0)
|
||||
{
|
||||
Timer timer = new SpecialMoveTimer(from);
|
||||
timer.Start();
|
||||
|
||||
AddContext(from, new SpecialMoveContext(timer, GetType()));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Validate(Mobile from)
|
||||
{
|
||||
if (!from.Player)
|
||||
return true;
|
||||
|
||||
if (HonorableExecution.IsUnderPenalty(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1063024); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AnimalForm.UnderTransformation(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1063024); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Dueling
|
||||
|
||||
string option = null;
|
||||
|
||||
if (this is Backstab)
|
||||
option = "Backstab";
|
||||
else if (this is DeathStrike)
|
||||
option = "Death Strike";
|
||||
else if (this is FocusAttack)
|
||||
option = "Focus Attack";
|
||||
else if (this is KiAttack)
|
||||
option = "Ki Attack";
|
||||
else if (this is SurpriseAttack)
|
||||
option = "Surprise Attack";
|
||||
else if (this is HonorableExecution)
|
||||
option = "Honorable Execution";
|
||||
else if (this is LightningStrike)
|
||||
option = "Lightning Strike";
|
||||
else if (this is MomentumStrike)
|
||||
option = "Momentum Strike";
|
||||
|
||||
if (option != null && !DuelContext.AllowSpecialMove(from, option, this))
|
||||
return false;
|
||||
|
||||
Table[m] = move;
|
||||
|
||||
move.OnUse( m );
|
||||
#endregion
|
||||
|
||||
int moveID = SpellRegistry.GetRegistryNumber( move );
|
||||
return CheckSkills(from) && CheckMana(from, false);
|
||||
}
|
||||
|
||||
if ( moveID > 0 )
|
||||
m.Send( new ToggleSpecialAbility( moveID + 1, true ) );
|
||||
public virtual void CheckGain(Mobile m)
|
||||
{
|
||||
m.CheckSkill(MoveSkill, RequiredSkill, RequiredSkill + 37.5);
|
||||
}
|
||||
|
||||
public static void ClearAllMoves(Mobile m)
|
||||
{
|
||||
foreach (KeyValuePair<int, SpecialMove> kvp in SpellRegistry.SpecialMoves)
|
||||
{
|
||||
int moveID = kvp.Key;
|
||||
|
||||
if (moveID != -1)
|
||||
m.Send(new ToggleSpecialAbility(moveID + 1, false));
|
||||
}
|
||||
}
|
||||
|
||||
public static SpecialMove GetCurrentMove(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
return null;
|
||||
|
||||
if (!Core.SE)
|
||||
{
|
||||
ClearCurrentMove(m);
|
||||
return null;
|
||||
}
|
||||
|
||||
Table.TryGetValue(m, out SpecialMove move);
|
||||
|
||||
if (move != null && move.ValidatesDuringHit && !move.Validate(m))
|
||||
{
|
||||
ClearCurrentMove(m);
|
||||
return null;
|
||||
}
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public static bool SetCurrentMove(Mobile m, SpecialMove move)
|
||||
{
|
||||
if (!Core.SE)
|
||||
{
|
||||
ClearCurrentMove(m);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (move != null && !move.Validate(m))
|
||||
{
|
||||
ClearCurrentMove(m);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sameMove = move == GetCurrentMove(m);
|
||||
|
||||
ClearCurrentMove(m);
|
||||
|
||||
if (sameMove)
|
||||
return true;
|
||||
|
||||
if (move != null)
|
||||
{
|
||||
WeaponAbility.ClearCurrentAbility(m);
|
||||
|
||||
Table[m] = move;
|
||||
|
||||
move.OnUse(m);
|
||||
|
||||
int moveID = SpellRegistry.GetRegistryNumber(move);
|
||||
|
||||
if (moveID > 0)
|
||||
m.Send(new ToggleSpecialAbility(moveID + 1, true));
|
||||
|
||||
TextDefinition.SendMessageTo(m, move.AbilityMessage);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void ClearCurrentMove(Mobile m)
|
||||
{
|
||||
Table.TryGetValue(m, out SpecialMove move);
|
||||
|
||||
if (move != null)
|
||||
{
|
||||
move.OnClearMove(m);
|
||||
|
||||
TextDefinition.SendMessageTo( m, move.AbilityMessage );
|
||||
}
|
||||
int moveID = SpellRegistry.GetRegistryNumber(move);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (moveID > 0)
|
||||
m.Send(new ToggleSpecialAbility(moveID + 1, false));
|
||||
}
|
||||
|
||||
public static void ClearCurrentMove( Mobile m )
|
||||
{
|
||||
Table.TryGetValue( m, out SpecialMove move );
|
||||
Table.Remove(m);
|
||||
}
|
||||
|
||||
if ( move != null )
|
||||
{
|
||||
move.OnClearMove( m );
|
||||
private static void AddContext(Mobile m, SpecialMoveContext context)
|
||||
{
|
||||
m_PlayersTable[m] = context;
|
||||
}
|
||||
|
||||
int moveID = SpellRegistry.GetRegistryNumber( move );
|
||||
private static void RemoveContext(Mobile m)
|
||||
{
|
||||
SpecialMoveContext context = GetContext(m);
|
||||
|
||||
if ( moveID > 0 )
|
||||
m.Send( new ToggleSpecialAbility( moveID + 1, false ) );
|
||||
}
|
||||
if (context != null)
|
||||
{
|
||||
m_PlayersTable.Remove(m);
|
||||
|
||||
Table.Remove( m );
|
||||
}
|
||||
context.Timer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public SpecialMove()
|
||||
{
|
||||
}
|
||||
private static SpecialMoveContext GetContext(Mobile m)
|
||||
{
|
||||
return m_PlayersTable.ContainsKey(m) ? m_PlayersTable[m] : null;
|
||||
}
|
||||
|
||||
public static bool GetContext(Mobile m, Type type)
|
||||
{
|
||||
m_PlayersTable.TryGetValue(m, out SpecialMoveContext context);
|
||||
|
||||
private static Dictionary<Mobile, SpecialMoveContext> m_PlayersTable = new Dictionary<Mobile, SpecialMoveContext>();
|
||||
if (context == null)
|
||||
return false;
|
||||
|
||||
private static void AddContext( Mobile m, SpecialMoveContext context )
|
||||
{
|
||||
m_PlayersTable[m] = context;
|
||||
}
|
||||
return context.Type == type;
|
||||
}
|
||||
|
||||
private static void RemoveContext( Mobile m )
|
||||
{
|
||||
SpecialMoveContext context = GetContext( m );
|
||||
private class SpecialMoveTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
|
||||
if ( context != null )
|
||||
{
|
||||
m_PlayersTable.Remove( m );
|
||||
public SpecialMoveTimer(Mobile from) : base(TimeSpan.FromSeconds(3.0))
|
||||
{
|
||||
m_Mobile = from;
|
||||
|
||||
context.Timer.Stop();
|
||||
}
|
||||
}
|
||||
Priority = TimerPriority.TwentyFiveMS;
|
||||
}
|
||||
|
||||
private static SpecialMoveContext GetContext( Mobile m )
|
||||
{
|
||||
return ( m_PlayersTable.ContainsKey( m ) ? m_PlayersTable[m] : null );
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
RemoveContext(m_Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetContext( Mobile m, Type type )
|
||||
{
|
||||
m_PlayersTable.TryGetValue( m, out SpecialMoveContext context );
|
||||
public class SpecialMoveContext
|
||||
{
|
||||
public SpecialMoveContext(Timer timer, Type type)
|
||||
{
|
||||
Timer = timer;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
if ( context == null )
|
||||
return false;
|
||||
public Timer Timer{ get; }
|
||||
|
||||
return ( context.Type == type );
|
||||
}
|
||||
|
||||
private class SpecialMoveTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
|
||||
public SpecialMoveTimer( Mobile from ) : base ( TimeSpan.FromSeconds( 3.0 ) )
|
||||
{
|
||||
m_Mobile = from;
|
||||
|
||||
Priority = TimerPriority.TwentyFiveMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
RemoveContext( m_Mobile );
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialMoveContext
|
||||
{
|
||||
public Timer Timer { get; }
|
||||
|
||||
public Type Type { get; }
|
||||
|
||||
public SpecialMoveContext( Timer timer, Type type )
|
||||
{
|
||||
Timer = timer;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public Type Type{ get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,14 +1,14 @@
|
|||
namespace Server.Spells
|
||||
{
|
||||
public enum SpellCircle
|
||||
{
|
||||
First,
|
||||
Second,
|
||||
Third,
|
||||
Fourth,
|
||||
Fifth,
|
||||
Sixth,
|
||||
Seventh,
|
||||
Eighth
|
||||
}
|
||||
public enum SpellCircle
|
||||
{
|
||||
First,
|
||||
Second,
|
||||
Third,
|
||||
Fourth,
|
||||
Fifth,
|
||||
Sixth,
|
||||
Seventh,
|
||||
Eighth
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,63 +2,69 @@ using System;
|
|||
|
||||
namespace Server.Spells
|
||||
{
|
||||
public class SpellInfo
|
||||
{
|
||||
public SpellInfo( string name, string mantra, params Type[] regs ) : this( name, mantra, 16, 0, 0, true, regs )
|
||||
{
|
||||
}
|
||||
public class SpellInfo
|
||||
{
|
||||
public SpellInfo(string name, string mantra, params Type[] regs) : this(name, mantra, 16, 0, 0, true, regs)
|
||||
{
|
||||
}
|
||||
|
||||
public SpellInfo( string name, string mantra, bool allowTown, params Type[] regs ) : this( name, mantra, 16, 0, 0, allowTown, regs )
|
||||
{
|
||||
}
|
||||
public SpellInfo(string name, string mantra, bool allowTown, params Type[] regs) : this(name, mantra, 16, 0, 0,
|
||||
allowTown, regs)
|
||||
{
|
||||
}
|
||||
|
||||
public SpellInfo( string name, string mantra, int action, params Type[] regs ) : this( name, mantra, action, 0, 0, true, regs )
|
||||
{
|
||||
}
|
||||
public SpellInfo(string name, string mantra, int action, params Type[] regs) : this(name, mantra, action, 0, 0, true,
|
||||
regs)
|
||||
{
|
||||
}
|
||||
|
||||
public SpellInfo( string name, string mantra, int action, bool allowTown, params Type[] regs ) : this( name, mantra, action, 0, 0, allowTown, regs )
|
||||
{
|
||||
}
|
||||
public SpellInfo(string name, string mantra, int action, bool allowTown, params Type[] regs) : this(name, mantra,
|
||||
action, 0, 0, allowTown, regs)
|
||||
{
|
||||
}
|
||||
|
||||
public SpellInfo( string name, string mantra, int action, int handEffect, params Type[] regs ) : this( name, mantra, action, handEffect, handEffect, true, regs )
|
||||
{
|
||||
}
|
||||
public SpellInfo(string name, string mantra, int action, int handEffect, params Type[] regs) : this(name, mantra,
|
||||
action, handEffect, handEffect, true, regs)
|
||||
{
|
||||
}
|
||||
|
||||
public SpellInfo( string name, string mantra, int action, int handEffect, bool allowTown, params Type[] regs ) : this( name, mantra, action, handEffect, handEffect, allowTown, regs )
|
||||
{
|
||||
}
|
||||
public SpellInfo(string name, string mantra, int action, int handEffect, bool allowTown, params Type[] regs) : this(
|
||||
name, mantra, action, handEffect, handEffect, allowTown, regs)
|
||||
{
|
||||
}
|
||||
|
||||
public SpellInfo( string name, string mantra, int action, int leftHandEffect, int rightHandEffect, bool allowTown, params Type[] regs )
|
||||
{
|
||||
Name = name;
|
||||
Mantra = mantra;
|
||||
Action = action;
|
||||
Reagents = regs;
|
||||
AllowTown = allowTown;
|
||||
public SpellInfo(string name, string mantra, int action, int leftHandEffect, int rightHandEffect, bool allowTown,
|
||||
params Type[] regs)
|
||||
{
|
||||
Name = name;
|
||||
Mantra = mantra;
|
||||
Action = action;
|
||||
Reagents = regs;
|
||||
AllowTown = allowTown;
|
||||
|
||||
LeftHandEffect = leftHandEffect;
|
||||
RightHandEffect = rightHandEffect;
|
||||
LeftHandEffect = leftHandEffect;
|
||||
RightHandEffect = rightHandEffect;
|
||||
|
||||
Amounts = new int[regs.Length];
|
||||
Amounts = new int[regs.Length];
|
||||
|
||||
for ( int i = 0; i < regs.Length; ++i )
|
||||
Amounts[i] = 1;
|
||||
}
|
||||
for (int i = 0; i < regs.Length; ++i)
|
||||
Amounts[i] = 1;
|
||||
}
|
||||
|
||||
public int Action { get; set; }
|
||||
public int Action{ get; set; }
|
||||
|
||||
public bool AllowTown { get; set; }
|
||||
public bool AllowTown{ get; set; }
|
||||
|
||||
public int[] Amounts { get; set; }
|
||||
public int[] Amounts{ get; set; }
|
||||
|
||||
public string Mantra { get; set; }
|
||||
public string Mantra{ get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Name{ get; set; }
|
||||
|
||||
public Type[] Reagents { get; set; }
|
||||
public Type[] Reagents{ get; set; }
|
||||
|
||||
public int LeftHandEffect { get; set; }
|
||||
public int LeftHandEffect{ get; set; }
|
||||
|
||||
public int RightHandEffect { get; set; }
|
||||
}
|
||||
public int RightHandEffect{ get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -3,167 +3,168 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Server.Spells
|
||||
{
|
||||
public class SpellRegistry
|
||||
{
|
||||
private static Type[] m_Types = new Type[700];
|
||||
private static int m_Count;
|
||||
public class SpellRegistry
|
||||
{
|
||||
private static Type[] m_Types = new Type[700];
|
||||
private static int m_Count;
|
||||
|
||||
public static Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
m_Count = -1;
|
||||
return m_Types;
|
||||
}
|
||||
}
|
||||
private static Dictionary<Type, int> m_IDsFromTypes = new Dictionary<Type, int>(m_Types.Length);
|
||||
|
||||
//What IS this used for anyways.
|
||||
public static int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_Count == -1 )
|
||||
{
|
||||
m_Count = 0;
|
||||
private static object[] m_Params = new object[2];
|
||||
|
||||
for ( int i = 0; i < m_Types.Length; ++i )
|
||||
if ( m_Types[i] != null )
|
||||
++m_Count;
|
||||
}
|
||||
private static string[] m_CircleNames =
|
||||
{
|
||||
"First",
|
||||
"Second",
|
||||
"Third",
|
||||
"Fourth",
|
||||
"Fifth",
|
||||
"Sixth",
|
||||
"Seventh",
|
||||
"Eighth",
|
||||
"Necromancy",
|
||||
"Chivalry",
|
||||
"Bushido",
|
||||
"Ninjitsu",
|
||||
"Spellweaving"
|
||||
};
|
||||
|
||||
return m_Count;
|
||||
}
|
||||
}
|
||||
public static Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
m_Count = -1;
|
||||
return m_Types;
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<Type, int> m_IDsFromTypes = new Dictionary<Type, int>( m_Types.Length );
|
||||
//What IS this used for anyways.
|
||||
public static int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Count == -1)
|
||||
{
|
||||
m_Count = 0;
|
||||
|
||||
public static Dictionary<int, SpecialMove> SpecialMoves { get; } = new Dictionary<int, SpecialMove>();
|
||||
for (int i = 0; i < m_Types.Length; ++i)
|
||||
if (m_Types[i] != null)
|
||||
++m_Count;
|
||||
}
|
||||
|
||||
public static int GetRegistryNumber( ISpell s )
|
||||
{
|
||||
return GetRegistryNumber( s.GetType() );
|
||||
}
|
||||
return m_Count;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetRegistryNumber( SpecialMove s )
|
||||
{
|
||||
return GetRegistryNumber( s.GetType() );
|
||||
}
|
||||
public static Dictionary<int, SpecialMove> SpecialMoves{ get; } = new Dictionary<int, SpecialMove>();
|
||||
|
||||
public static int GetRegistryNumber( Type type )
|
||||
{
|
||||
if ( m_IDsFromTypes.ContainsKey( type ) )
|
||||
return m_IDsFromTypes[type];
|
||||
public static int GetRegistryNumber(ISpell s)
|
||||
{
|
||||
return GetRegistryNumber(s.GetType());
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
public static int GetRegistryNumber(SpecialMove s)
|
||||
{
|
||||
return GetRegistryNumber(s.GetType());
|
||||
}
|
||||
|
||||
public static void Register( int spellID, Type type )
|
||||
{
|
||||
if ( spellID < 0 || spellID >= m_Types.Length )
|
||||
return;
|
||||
public static int GetRegistryNumber(Type type)
|
||||
{
|
||||
if (m_IDsFromTypes.ContainsKey(type))
|
||||
return m_IDsFromTypes[type];
|
||||
|
||||
if ( m_Types[spellID] == null )
|
||||
++m_Count;
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_Types[spellID] = type;
|
||||
public static void Register(int spellID, Type type)
|
||||
{
|
||||
if (spellID < 0 || spellID >= m_Types.Length)
|
||||
return;
|
||||
|
||||
if ( !m_IDsFromTypes.ContainsKey( type ) )
|
||||
m_IDsFromTypes.Add( type, spellID );
|
||||
if (m_Types[spellID] == null)
|
||||
++m_Count;
|
||||
|
||||
if ( type.IsSubclassOf( typeof( SpecialMove ) ) )
|
||||
{
|
||||
SpecialMove spm = null;
|
||||
m_Types[spellID] = type;
|
||||
|
||||
try
|
||||
{
|
||||
spm = Activator.CreateInstance( type ) as SpecialMove;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
if (!m_IDsFromTypes.ContainsKey(type))
|
||||
m_IDsFromTypes.Add(type, spellID);
|
||||
|
||||
if ( spm != null )
|
||||
SpecialMoves.Add( spellID, spm );
|
||||
}
|
||||
}
|
||||
if (type.IsSubclassOf(typeof(SpecialMove)))
|
||||
{
|
||||
SpecialMove spm = null;
|
||||
|
||||
public static SpecialMove GetSpecialMove( int spellID )
|
||||
{
|
||||
if ( spellID < 0 || spellID >= m_Types.Length )
|
||||
return null;
|
||||
try
|
||||
{
|
||||
spm = Activator.CreateInstance(type) as SpecialMove;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
Type t = m_Types[spellID];
|
||||
if (spm != null)
|
||||
SpecialMoves.Add(spellID, spm);
|
||||
}
|
||||
}
|
||||
|
||||
if ( t == null || !t.IsSubclassOf( typeof( SpecialMove ) ) || !SpecialMoves.ContainsKey( spellID ) )
|
||||
return null;
|
||||
public static SpecialMove GetSpecialMove(int spellID)
|
||||
{
|
||||
if (spellID < 0 || spellID >= m_Types.Length)
|
||||
return null;
|
||||
|
||||
return SpecialMoves[spellID];
|
||||
}
|
||||
Type t = m_Types[spellID];
|
||||
|
||||
private static object[] m_Params = new object[2];
|
||||
if (t == null || !t.IsSubclassOf(typeof(SpecialMove)) || !SpecialMoves.ContainsKey(spellID))
|
||||
return null;
|
||||
|
||||
public static Spell NewSpell( int spellID, Mobile caster, Item scroll )
|
||||
{
|
||||
if ( spellID < 0 || spellID >= m_Types.Length )
|
||||
return null;
|
||||
return SpecialMoves[spellID];
|
||||
}
|
||||
|
||||
Type t = m_Types[spellID];
|
||||
public static Spell NewSpell(int spellID, Mobile caster, Item scroll)
|
||||
{
|
||||
if (spellID < 0 || spellID >= m_Types.Length)
|
||||
return null;
|
||||
|
||||
if ( t != null && !t.IsSubclassOf( typeof( SpecialMove ) ) )
|
||||
{
|
||||
m_Params[0] = caster;
|
||||
m_Params[1] = scroll;
|
||||
Type t = m_Types[spellID];
|
||||
|
||||
try
|
||||
{
|
||||
return (Spell)Activator.CreateInstance( t, m_Params );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
if (t != null && !t.IsSubclassOf(typeof(SpecialMove)))
|
||||
{
|
||||
m_Params[0] = caster;
|
||||
m_Params[1] = scroll;
|
||||
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
return (Spell)Activator.CreateInstance(t, m_Params);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] m_CircleNames = {
|
||||
"First",
|
||||
"Second",
|
||||
"Third",
|
||||
"Fourth",
|
||||
"Fifth",
|
||||
"Sixth",
|
||||
"Seventh",
|
||||
"Eighth",
|
||||
"Necromancy",
|
||||
"Chivalry",
|
||||
"Bushido",
|
||||
"Ninjitsu",
|
||||
"Spellweaving"
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Spell NewSpell( string name, Mobile caster, Item scroll )
|
||||
{
|
||||
for ( int i = 0; i < m_CircleNames.Length; ++i )
|
||||
{
|
||||
Type t = ScriptCompiler.FindTypeByFullName($"Server.Spells.{m_CircleNames[i]}.{name}");
|
||||
public static Spell NewSpell(string name, Mobile caster, Item scroll)
|
||||
{
|
||||
for (int i = 0; i < m_CircleNames.Length; ++i)
|
||||
{
|
||||
Type t = ScriptCompiler.FindTypeByFullName($"Server.Spells.{m_CircleNames[i]}.{name}");
|
||||
|
||||
if ( t != null && !t.IsSubclassOf( typeof( SpecialMove ) ) )
|
||||
{
|
||||
m_Params[0] = caster;
|
||||
m_Params[1] = scroll;
|
||||
if (t != null && !t.IsSubclassOf(typeof(SpecialMove)))
|
||||
{
|
||||
m_Params[0] = caster;
|
||||
m_Params[1] = scroll;
|
||||
|
||||
try
|
||||
{
|
||||
return (Spell)Activator.CreateInstance( t, m_Params );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
return (Spell)Activator.CreateInstance(t, m_Params);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
namespace Server.Spells
|
||||
{
|
||||
public enum SpellState
|
||||
{
|
||||
None = 0,
|
||||
Casting = 1, // We are in the process of casting (that is, waiting GetCastTime() and doing animations). Spell casting may be interupted in this state.
|
||||
Sequencing = 2 // Casting completed, but the full spell sequence isn't. Usually waiting for a target response. Some actions are restricted in this state (using skills for example).
|
||||
}
|
||||
public enum SpellState
|
||||
{
|
||||
None = 0,
|
||||
|
||||
Casting =
|
||||
1, // We are in the process of casting (that is, waiting GetCastTime() and doing animations). Spell casting may be interupted in this state.
|
||||
|
||||
Sequencing =
|
||||
2 // Casting completed, but the full spell sequence isn't. Usually waiting for a target response. Some actions are restricted in this state (using skills for example).
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue