Formats UO Content (#201)

This commit is contained in:
Kamron Batman 2020-08-27 18:30:38 -07:00 • committed by GitHub
parent 86b7b3aed1
commit ad3775c4d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3249 changed files with 431083 additions and 440981 deletions

View file

@ -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
}
}

View file

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

View file

@ -9,305 +9,311 @@ using Server.Spells.Ninjitsu;
namespace Server.Spells
{
public abstract class SpecialMove
{
private static readonly Dictionary<Mobile, SpecialMoveContext> m_PlayersTable = new Dictionary<Mobile, SpecialMoveContext>();
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 static Dictionary<Mobile, SpecialMove> Table { get; } = new Dictionary<Mobile, SpecialMove>();
public virtual bool ValidatesDuringHit => true;
public virtual int GetAccuracyBonus(Mobile attacker) => 0;
public virtual double GetDamageScalar(Mobile attacker, Mobile defender) => 1.0;
// Called before swinging, to make sure the accuracy scalar is to be computed.
public virtual bool OnBeforeSwing(Mobile attacker, Mobile defender) => true;
// Called when a hit connects, but before damage is calculated.
public virtual bool OnBeforeDamage(Mobile attacker, Mobile defender) => true;
// Called as soon as the ability is used.
public virtual void OnUse(Mobile from)
public abstract class SpecialMove
{
}
private static readonly Dictionary<Mobile, SpecialMoveContext> m_PlayersTable =
new Dictionary<Mobile, SpecialMoveContext>();
// Called when a hit connects, at the end of the weapon.OnHit() method.
public virtual void OnHit(Mobile attacker, Mobile defender, int damage)
{
}
public virtual int BaseMana => 0;
// Called when a hit misses.
public virtual void OnMiss(Mobile attacker, Mobile defender)
{
}
public virtual SkillName MoveSkill => SkillName.Bushido;
public virtual double RequiredSkill => 0.0;
// Called when the move is cleared.
public virtual void OnClearMove(Mobile from)
{
}
public virtual TextDefinition AbilityMessage => 0;
public virtual bool IgnoreArmor(Mobile attacker) => false;
public virtual bool BlockedByAnimalForm => true;
public virtual bool DelayedContext => false;
public virtual double GetPropertyBonus(Mobile attacker) => 1.0;
public static Dictionary<Mobile, SpecialMove> Table { get; } = new Dictionary<Mobile, SpecialMove>();
public virtual bool CheckSkills(Mobile m)
{
if (m.Skills[MoveSkill].Value < RequiredSkill)
{
string args = $"{RequiredSkill: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;
}
public virtual bool ValidatesDuringHit => true;
return true;
}
public virtual int GetAccuracyBonus(Mobile attacker) => 0;
public virtual int ScaleMana(Mobile m, int mana)
{
double scalar = 1.0;
public virtual double GetDamageScalar(Mobile attacker, Mobile defender) => 1.0;
if (!MindRotSpell.GetMindRotScalar(m, ref scalar))
scalar = 1.0;
// Called before swinging, to make sure the accuracy scalar is to be computed.
public virtual bool OnBeforeSwing(Mobile attacker, Mobile defender) => true;
// Lower Mana Cost = 40%
int lmc = Math.Min(AosAttributes.GetValue(m, AosAttribute.LowerManaCost), 40);
// Called when a hit connects, but before damage is calculated.
public virtual bool OnBeforeDamage(Mobile attacker, Mobile defender) => true;
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)
// Called as soon as the ability is used.
public virtual void OnUse(Mobile from)
{
Timer timer = new SpecialMoveTimer(from);
timer.Start();
}
AddContext(from, new SpecialMoveContext(timer, GetType()));
// 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) => false;
public virtual double GetPropertyBonus(Mobile attacker) => 1.0;
public virtual bool CheckSkills(Mobile m)
{
if (m.Skills[MoveSkill].Value < RequiredSkill)
{
var args = $"{RequiredSkill: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)
{
var scalar = 1.0;
if (!MindRotSpell.GetMindRotScalar(m, ref scalar))
scalar = 1.0;
// Lower Mana Cost = 40%
var lmc = Math.Min(AosAttributes.GetValue(m, AosAttribute.LowerManaCost), 40);
scalar -= (double)lmc / 100;
var 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)
{
var 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;
}
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;
return CheckSkills(from) && CheckMana(from, false);
}
public virtual void CheckGain(Mobile m)
{
m.CheckSkill(MoveSkill, RequiredSkill, RequiredSkill + 37.5);
}
public static void ClearAllMoves(Mobile m)
{
foreach (var kvp in SpellRegistry.SpecialMoves)
{
var 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;
}
if (Table.TryGetValue(m, out var move) && 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?.Validate(m) == false)
{
ClearCurrentMove(m);
return false;
}
var sameMove = move == GetCurrentMove(m);
ClearCurrentMove(m);
if (sameMove)
return true;
if (move != null)
{
WeaponAbility.ClearCurrentAbility(m);
Table[m] = move;
move.OnUse(m);
var 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)
{
if (Table.TryGetValue(m, out var move))
{
move.OnClearMove(m);
var moveID = SpellRegistry.GetRegistryNumber(move);
if (moveID > 0)
m.Send(new ToggleSpecialAbility(moveID + 1, false));
}
Table.Remove(m);
}
private static void AddContext(Mobile m, SpecialMoveContext context)
{
m_PlayersTable[m] = context;
}
private static void RemoveContext(Mobile m)
{
var context = GetContext(m);
if (context != null)
{
m_PlayersTable.Remove(m);
context.Timer.Stop();
}
}
private static SpecialMoveContext GetContext(Mobile m) =>
m_PlayersTable.TryGetValue(m, out var context) ? context : null;
private class SpecialMoveTimer : Timer
{
private readonly 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 SpecialMoveContext(Timer timer, Type type)
{
Timer = timer;
Type = type;
}
public Timer Timer { get; }
public Type Type { get; }
}
}
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;
}
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;
return CheckSkills(from) && CheckMana(from, false);
}
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;
}
if (Table.TryGetValue(m, out SpecialMove move) && 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?.Validate(m) == false)
{
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)
{
if (Table.TryGetValue(m, out SpecialMove move))
{
move.OnClearMove(m);
int moveID = SpellRegistry.GetRegistryNumber(move);
if (moveID > 0)
m.Send(new ToggleSpecialAbility(moveID + 1, false));
}
Table.Remove(m);
}
private static void AddContext(Mobile m, SpecialMoveContext context)
{
m_PlayersTable[m] = context;
}
private static void RemoveContext(Mobile m)
{
SpecialMoveContext context = GetContext(m);
if (context != null)
{
m_PlayersTable.Remove(m);
context.Timer.Stop();
}
}
private static SpecialMoveContext GetContext(Mobile m) => m_PlayersTable.TryGetValue(m, out SpecialMoveContext context) ? context : null;
private class SpecialMoveTimer : Timer
{
private readonly 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 SpecialMoveContext(Timer timer, Type type)
{
Timer = timer;
Type = type;
}
public Timer Timer { get; }
public Type Type { get; }
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -2,69 +2,106 @@ 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, int action, params Type[] regs) : this(
name,
mantra,
action,
0,
0,
true,
regs
)
{
}
public SpellInfo(string name, string mantra, int action, bool allowTown, params Type[] regs) : this(
name,
mantra,
action,
0,
0,
allowTown,
regs
)
{
}
public SpellInfo(string name, string mantra, int action, int handEffect, params Type[] regs) : this(
name,
mantra,
action,
handEffect,
handEffect,
true,
regs
)
{
}
public SpellInfo(string name, string mantra, int action, int handEffect, bool allowTown, params Type[] regs) : this(
name,
mantra,
action,
handEffect,
handEffect,
allowTown,
regs
)
{
}
public SpellInfo(
string name, string mantra, int action, int leftHandEffect, int rightHandEffect, bool allowTown,
params Type[] regs
)
{
Name = name;
Mantra = mantra;
Action = action;
Reagents = regs;
AllowTown = allowTown;
LeftHandEffect = leftHandEffect;
RightHandEffect = rightHandEffect;
Amounts = new int[regs.Length];
for (var i = 0; i < regs.Length; ++i)
Amounts[i] = 1;
}
public int Action { get; set; }
public bool AllowTown { get; set; }
public int[] Amounts { get; set; }
public string Mantra { get; set; }
public string Name { get; set; }
public Type[] Reagents { get; set; }
public int LeftHandEffect { get; set; }
public int RightHandEffect { get; set; }
}
public SpellInfo(string name, string mantra, bool allowTown, params Type[] regs) : this(name, mantra, 16, 0, 0,
allowTown, regs)
{
}
public SpellInfo(string name, string mantra, int action, params Type[] regs) : this(name, mantra, action, 0, 0, true,
regs)
{
}
public SpellInfo(string name, string mantra, int action, bool allowTown, params Type[] regs) : this(name, mantra,
action, 0, 0, allowTown, regs)
{
}
public SpellInfo(string name, string mantra, int action, int handEffect, params Type[] regs) : this(name, mantra,
action, handEffect, handEffect, true, regs)
{
}
public SpellInfo(string name, string mantra, int action, int handEffect, bool allowTown, params Type[] regs) : this(
name, mantra, action, handEffect, handEffect, allowTown, regs)
{
}
public SpellInfo(string name, string mantra, int action, int leftHandEffect, int rightHandEffect, bool allowTown,
params Type[] regs)
{
Name = name;
Mantra = mantra;
Action = action;
Reagents = regs;
AllowTown = allowTown;
LeftHandEffect = leftHandEffect;
RightHandEffect = rightHandEffect;
Amounts = new int[regs.Length];
for (int i = 0; i < regs.Length; ++i)
Amounts[i] = 1;
}
public int Action { get; set; }
public bool AllowTown { get; set; }
public int[] Amounts { get; set; }
public string Mantra { get; set; }
public string Name { get; set; }
public Type[] Reagents { get; set; }
public int LeftHandEffect { get; set; }
public int RightHandEffect { get; set; }
}
}
}

View file

@ -4,160 +4,160 @@ using Server.Utilities;
namespace Server.Spells
{
public class SpellRegistry
{
private static readonly Type[] m_Types = new Type[700];
private static int m_Count;
private static readonly Dictionary<Type, int> m_IDsFromTypes = new Dictionary<Type, int>(m_Types.Length);
private static readonly object[] m_Params = new object[2];
private static readonly string[] m_CircleNames =
public class SpellRegistry
{
"First",
"Second",
"Third",
"Fourth",
"Fifth",
"Sixth",
"Seventh",
"Eighth",
"Necromancy",
"Chivalry",
"Bushido",
"Ninjitsu",
"Spellweaving"
};
private static readonly Type[] m_Types = new Type[700];
private static int m_Count;
public static Type[] Types
{
get
{
m_Count = -1;
return m_Types;
}
}
private static readonly 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)
private static readonly object[] m_Params = new object[2];
private static readonly string[] m_CircleNames =
{
m_Count = 0;
"First",
"Second",
"Third",
"Fourth",
"Fifth",
"Sixth",
"Seventh",
"Eighth",
"Necromancy",
"Chivalry",
"Bushido",
"Ninjitsu",
"Spellweaving"
};
for (int i = 0; i < m_Types.Length; ++i)
if (m_Types[i] != null)
++m_Count;
public static Type[] Types
{
get
{
m_Count = -1;
return m_Types;
}
}
return m_Count;
}
}
public static Dictionary<int, SpecialMove> SpecialMoves { get; } = new Dictionary<int, SpecialMove>();
public static int GetRegistryNumber(ISpell s) => GetRegistryNumber(s.GetType());
public static int GetRegistryNumber(SpecialMove s) => GetRegistryNumber(s.GetType());
public static int GetRegistryNumber(Type type) => m_IDsFromTypes.TryGetValue(type, out int value) ? value : -1;
public static void Register(int spellID, Type type)
{
if (spellID < 0 || spellID >= m_Types.Length)
return;
if (m_Types[spellID] == null)
++m_Count;
m_Types[spellID] = type;
if (!m_IDsFromTypes.ContainsKey(type))
m_IDsFromTypes.Add(type, spellID);
if (type.IsSubclassOf(typeof(SpecialMove)))
{
SpecialMove spm = null;
try
// What IS this used for anyways.
public static int Count
{
spm = ActivatorUtil.CreateInstance(type) as SpecialMove;
}
catch
{
// ignored
get
{
if (m_Count == -1)
{
m_Count = 0;
for (var i = 0; i < m_Types.Length; ++i)
if (m_Types[i] != null)
++m_Count;
}
return m_Count;
}
}
if (spm != null)
SpecialMoves.Add(spellID, spm);
}
}
public static Dictionary<int, SpecialMove> SpecialMoves { get; } = new Dictionary<int, SpecialMove>();
public static SpecialMove GetSpecialMove(int spellID)
{
if (spellID < 0 || spellID >= m_Types.Length)
return null;
public static int GetRegistryNumber(ISpell s) => GetRegistryNumber(s.GetType());
Type t = m_Types[spellID];
public static int GetRegistryNumber(SpecialMove s) => GetRegistryNumber(s.GetType());
if (t == null || !t.IsSubclassOf(typeof(SpecialMove)))
return null;
public static int GetRegistryNumber(Type type) => m_IDsFromTypes.TryGetValue(type, out var value) ? value : -1;
SpecialMoves.TryGetValue(spellID, out SpecialMove move);
return move;
}
public static Spell NewSpell(int spellID, Mobile caster, Item scroll)
{
if (spellID < 0 || spellID >= m_Types.Length)
return null;
Type t = m_Types[spellID];
if (t?.IsSubclassOf(typeof(SpecialMove)) == false)
{
m_Params[0] = caster;
m_Params[1] = scroll;
try
public static void Register(int spellID, Type type)
{
return (Spell)ActivatorUtil.CreateInstance(t, m_Params);
if (spellID < 0 || spellID >= m_Types.Length)
return;
if (m_Types[spellID] == null)
++m_Count;
m_Types[spellID] = type;
if (!m_IDsFromTypes.ContainsKey(type))
m_IDsFromTypes.Add(type, spellID);
if (type.IsSubclassOf(typeof(SpecialMove)))
{
SpecialMove spm = null;
try
{
spm = ActivatorUtil.CreateInstance(type) as SpecialMove;
}
catch
{
// ignored
}
if (spm != null)
SpecialMoves.Add(spellID, spm);
}
}
catch
public static SpecialMove GetSpecialMove(int spellID)
{
// ignored
if (spellID < 0 || spellID >= m_Types.Length)
return null;
var t = m_Types[spellID];
if (t == null || !t.IsSubclassOf(typeof(SpecialMove)))
return null;
SpecialMoves.TryGetValue(spellID, out var move);
return move;
}
}
return null;
}
public static Spell NewSpell(string name, Mobile caster, Item scroll)
{
for (int i = 0; i < m_CircleNames.Length; ++i)
{
Type t = AssemblyHandler.FindFirstTypeForName($"Server.Spells.{m_CircleNames[i]}.{name}");
if (t?.IsSubclassOf(typeof(SpecialMove)) == false)
public static Spell NewSpell(int spellID, Mobile caster, Item scroll)
{
m_Params[0] = caster;
m_Params[1] = scroll;
if (spellID < 0 || spellID >= m_Types.Length)
return null;
try
{
return (Spell)ActivatorUtil.CreateInstance(t, m_Params);
}
catch
{
// ignored
}
var t = m_Types[spellID];
if (t?.IsSubclassOf(typeof(SpecialMove)) == false)
{
m_Params[0] = caster;
m_Params[1] = scroll;
try
{
return (Spell)ActivatorUtil.CreateInstance(t, m_Params);
}
catch
{
// ignored
}
}
return null;
}
}
return null;
public static Spell NewSpell(string name, Mobile caster, Item scroll)
{
for (var i = 0; i < m_CircleNames.Length; ++i)
{
var t = AssemblyHandler.FindFirstTypeForName($"Server.Spells.{m_CircleNames[i]}.{name}");
if (t?.IsSubclassOf(typeof(SpecialMove)) == false)
{
m_Params[0] = caster;
m_Params[1] = scroll;
try
{
return (Spell)ActivatorUtil.CreateInstance(t, m_Params);
}
catch
{
// ignored
}
}
}
return null;
}
}
}
}

View file

@ -1,13 +1,13 @@
namespace Server.Spells
{
public enum SpellState
{
None = 0,
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.
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).
}
}
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).
}
}