Modernization Fixes & Updates to Default Values (#3)

This commit is contained in:
Kamron Batman 2018-10-28 00:33:16 -07:00 • committed by GitHub
parent 445eddff68
commit dcf64091b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
768 changed files with 10507 additions and 14196 deletions

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Network;
using Server.Spells;
@ -14,7 +15,7 @@ namespace Server.Items
/// </summary>
public class BleedAttack : WeaponAbility
{
private static Hashtable m_Table = new Hashtable();
private static Dictionary<Mobile, Timer> m_Table = new Dictionary<Mobile, Timer>();
public override int BaseMana => 30;
@ -53,17 +54,15 @@ namespace Server.Items
public static bool IsBleeding(Mobile m)
{
return m_Table.Contains(m);
return m_Table.ContainsKey(m);
}
public static void BeginBleed(Mobile m, Mobile from)
{
Timer t = (Timer)m_Table[m];
Timer t = m_Table[m];
t?.Stop();
t = new InternalTimer(from, m);
m_Table[m] = t;
m_Table[m] = t = new InternalTimer(from, m);
t.Start();
}
@ -80,10 +79,7 @@ namespace Server.Items
m.PlaySound(0x133);
m.Damage(damage, from);
Blood blood = new Blood();
blood.ItemID = Utility.Random(0x122A, 5);
Blood blood = new Blood { ItemID = Utility.Random(0x122A, 5) };
blood.MoveToWorld(m.Location, m.Map);
}
else
@ -94,7 +90,7 @@ namespace Server.Items
public static void EndBleed(Mobile m, bool message)
{
Timer t = (Timer)m_Table[m];
Timer t = m_Table[m];
if (t == null)
return;
@ -128,4 +124,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -8,7 +9,7 @@ namespace Server.Items
/// </summary>
public class Block : WeaponAbility
{
private static Hashtable m_Table = new Hashtable();
private static Dictionary<Mobile, BlockInfo> m_Table = new Dictionary<Mobile, BlockInfo>();
public override int BaseMana => 30;
@ -36,15 +37,16 @@ namespace Server.Items
attacker.FixedParticles(0x37C4, 1, 16, 0x251D, 0x39D, 0x3, EffectLayer.RightHand);
int bonus = (int)(10.0 * ((Math.Max(attacker.Skills[SkillName.Bushido].Value,
attacker.Skills[SkillName.Ninjitsu].Value) - 50.0) / 70.0 + 5));
int bonus = (int)(10.0 * ((Math.Max(attacker.Skills.Bushido.Value,
attacker.Skills.Ninjitsu.Value) - 50.0) / 70.0 + 5));
BeginBlock(attacker, bonus);
}
public static bool GetBonus(Mobile targ, ref int bonus)
{
if (!(m_Table[targ] is BlockInfo info))
BlockInfo info = m_Table[targ];
if (info == null)
return false;
bonus = info.m_Bonus;
@ -54,33 +56,29 @@ namespace Server.Items
public static void BeginBlock(Mobile m, int bonus)
{
EndBlock(m);
BlockInfo info = new BlockInfo(m, bonus);
info.m_Timer = new InternalTimer(m);
m_Table[m] = info;
m_Table[m] = new BlockInfo(m, bonus);
}
public static void EndBlock(Mobile m)
{
if (m_Table[m] is BlockInfo info)
{
info.m_Timer?.Stop();
BlockInfo info = m_Table[m];
m_Table.Remove(m);
}
if (info == null)
return;
info.m_Timer?.Stop();
m_Table.Remove(m);
}
private class BlockInfo
{
public int m_Bonus;
public Mobile m_Target;
public Timer m_Timer;
public BlockInfo(Mobile target, int bonus)
{
m_Target = target;
m_Bonus = bonus;
m_Timer = new InternalTimer(target);
}
}
@ -100,4 +98,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -9,7 +9,7 @@ namespace Server.Items
/// </summary>
public class DefenseMastery : WeaponAbility
{
private static Hashtable m_Table = new Hashtable();
private static Dictionary<Mobile, DefenseMasteryInfo> m_Table = new Dictionary<Mobile, DefenseMasteryInfo>();
public override int BaseMana => 30;
@ -38,17 +38,19 @@ namespace Server.Items
int modifier =
(int)(30.0 *
((Math.Max(attacker.Skills[SkillName.Bushido].Value, attacker.Skills[SkillName.Ninjitsu].Value) -
((Math.Max(attacker.Skills.Bushido.Value, attacker.Skills.Ninjitsu.Value) -
50.0) / 70.0));
if (m_Table[attacker] is DefenseMasteryInfo info)
DefenseMasteryInfo info = m_Table[attacker];
if (info != null)
EndDefense(info);
ResistanceMod mod = new ResistanceMod(ResistanceType.Physical, 50 + modifier);
attacker.AddResistanceMod(mod);
info = new DefenseMasteryInfo(attacker, 80 - modifier, mod);
info.m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(3.0), new TimerStateCallback(EndDefense), info);
info.m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(3.0), EndDefense, info);
m_Table[attacker] = info;
@ -57,17 +59,17 @@ namespace Server.Items
public static bool GetMalus(Mobile targ, ref int damageMalus)
{
if (!(m_Table[targ] is DefenseMasteryInfo info))
DefenseMasteryInfo info = m_Table[targ];
if (info == null)
return false;
damageMalus = info.m_DamageMalus;
return true;
}
private static void EndDefense(object state)
private static void EndDefense(DefenseMasteryInfo info)
{
DefenseMasteryInfo info = (DefenseMasteryInfo)state;
if (info.m_Mod != null)
info.m_From.RemoveResistanceMod(info.m_Mod);
@ -95,4 +97,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -21,7 +21,7 @@ namespace Server.Items
if ( !(from.Weapon is Fists) )
return true;
Skill skill = from.Skills[SkillName.ArmsLore];
Skill skill = from.Skills.ArmsLore;
if ( skill != null && skill.Base >= 80.0 )
return true;

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -8,7 +9,7 @@ namespace Server.Items
/// </summary>
public class DualWield : WeaponAbility
{
public static Hashtable Registry{ get; } = new Hashtable();
public static Dictionary<Mobile, DualWieldTimer> Registry{ get; } = new Dictionary<Mobile, DualWieldTimer>();
public override int BaseMana => 30;
@ -29,24 +30,23 @@ namespace Server.Items
if (!Validate(attacker) || !CheckMana(attacker, true))
return;
if (Registry.Contains(attacker))
DualWieldTimer timer = Registry[attacker];
if (timer != null)
{
DualWieldTimer existingtimer = (DualWieldTimer)Registry[attacker];
existingtimer.Stop();
timer.Stop();
Registry.Remove(attacker);
}
ClearCurrentAbility(attacker);
attacker.SendLocalizedMessage(1063362); // You dually wield for increased speed!
attacker.FixedParticles(0x3779, 1, 15, 0x7F6, 0x3E8, 3, EffectLayer.LeftHand);
Timer t = new DualWieldTimer(attacker,
(int)(20.0 + 3.0 * (attacker.Skills[SkillName.Ninjitsu].Value - 50.0) / 7.0)); //20-50 % increase
timer = new DualWieldTimer(attacker,
(int)(20.0 + 3.0 * (attacker.Skills.Ninjitsu.Value - 50.0) / 7.0)); //20-50 % increase
t.Start();
Registry.Add(attacker, t);
timer.Start();
Registry.Add(attacker, timer);
}
public class DualWieldTimer : Timer
@ -69,4 +69,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -8,7 +9,7 @@ namespace Server.Items
/// </summary>
public class Feint : WeaponAbility
{
public static Hashtable Registry{ get; } = new Hashtable();
public static Dictionary<Mobile, FeintTimer> Registry{ get; } = new Dictionary<Mobile, FeintTimer>();
public override int BaseMana => 30;
@ -29,10 +30,10 @@ namespace Server.Items
if (!Validate(attacker) || !CheckMana(attacker, true))
return;
if (Registry.Contains(defender))
FeintTimer timer = Registry[defender];
if (timer != null)
{
FeintTimer existingtimer = (FeintTimer)Registry[defender];
existingtimer.Stop();
timer.Stop();
Registry.Remove(defender);
}
@ -43,12 +44,12 @@ namespace Server.Items
attacker.FixedParticles(0x3728, 1, 13, 0x7F3, 0x962, 0, EffectLayer.Waist);
Timer t = new FeintTimer(defender,
(int)(20.0 + 3.0 * (Math.Max(attacker.Skills[SkillName.Ninjitsu].Value,
attacker.Skills[SkillName.Bushido].Value) - 50.0) / 7.0)); //20-50 % decrease
timer = new FeintTimer(defender,
(int)(20.0 + 3.0 * (Math.Max(attacker.Skills.Ninjitsu.Value,
attacker.Skills.Bushido.Value) - 50.0) / 7.0)); //20-50 % decrease
t.Start();
Registry.Add(defender, t);
timer.Start();
Registry.Add(defender, timer);
}
public class FeintTimer : Timer
@ -71,4 +72,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Spells;
namespace Server.Items
@ -11,7 +12,7 @@ namespace Server.Items
{
public override int BaseMana => 30;
public static Hashtable Registry{ get; } = new Hashtable();
public static Dictionary<Mobile, FrenziedWirlwindTimer> Registry{ get; } = new Dictionary<Mobile, FrenziedWirlwindTimer>();
public override bool CheckSkills(Mobile from)
{
@ -34,22 +35,19 @@ namespace Server.Items
Map map = attacker.Map;
if (map == null)
if (!(map != null && attacker.Weapon is BaseWeapon weapon))
return;
if (!(attacker.Weapon is BaseWeapon weapon))
return;
ArrayList list = new ArrayList();
List<Mobile> list = new List<Mobile>();
foreach (Mobile m in attacker.GetMobilesInRange(1))
list.Add(m);
ArrayList targets = new ArrayList();
List<Mobile> targets = new List<Mobile>();
for (int i = 0; i < list.Count; ++i)
{
Mobile m = (Mobile)list[i];
Mobile m = list[i];
if (m != defender && m != attacker && SpellHelper.ValidIndirectTarget(attacker, m))
{
@ -65,47 +63,44 @@ namespace Server.Items
}
}
if (targets.Count > 0)
if (targets.Count == 0 || !CheckMana(attacker, true))
return;
attacker.FixedEffect(0x3728, 10, 15);
attacker.PlaySound(0x2A1);
// 5-15 damage
int amount = (int)(10.0 * ((Math.Max(attacker.Skills.Bushido.Value,
attacker.Skills.Ninjitsu.Value) - 50.0) / 70.0 + 5));
for (int i = 0; i < targets.Count; ++i)
{
if (!CheckMana(attacker, true))
return;
Mobile m = targets[i];
attacker.DoHarmful(m, true);
attacker.FixedEffect(0x3728, 10, 15);
attacker.PlaySound(0x2A1);
FrenziedWirlwindTimer timer = Registry[m];
// 5-15 damage
int amount = (int)(10.0 * ((Math.Max(attacker.Skills[SkillName.Bushido].Value,
attacker.Skills[SkillName.Ninjitsu].Value) - 50.0) / 70.0 + 5));
for (int i = 0; i < targets.Count; ++i)
if (timer != null)
{
Mobile m = (Mobile)targets[i];
attacker.DoHarmful(m, true);
if (Registry[m] is Timer t)
{
t.Stop();
Registry.Remove(m);
}
t = new InternalTimer(attacker, m, amount);
t.Start();
Registry.Add(m, t);
timer.Stop();
Registry.Remove(m);
}
Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerStateCallback(RepeatEffect), attacker);
timer = new FrenziedWirlwindTimer(attacker, m, amount);
timer.Start();
Registry.Add(m, timer);
}
Timer.DelayCall(TimeSpan.FromSeconds(2.0), RepeatEffect, attacker);
}
private void RepeatEffect(object state)
private void RepeatEffect(Mobile attacker)
{
Mobile attacker = (Mobile)state;
attacker.FixedEffect(0x3728, 10, 15);
attacker.PlaySound(0x2A1);
}
private class InternalTimer : Timer
public class FrenziedWirlwindTimer : Timer
{
private readonly double DamagePerTick;
private Mobile m_Attacker;
@ -113,9 +108,9 @@ namespace Server.Items
private double m_DamageToDo;
private Mobile m_Defender;
public InternalTimer(Mobile attacker, Mobile defender, int totalDamage)
public FrenziedWirlwindTimer(Mobile attacker, Mobile defender, int totalDamage)
: base(TimeSpan.Zero, TimeSpan.FromSeconds(0.25),
12) // 3 seconds at .25 seconds apart = 12. Confirm delay inbetween of .25 each.
12) // 3 seconds at .25 seconds apart = 12. Confirm delay in between of .25 each.
{
m_Attacker = attacker;
m_Defender = defender;
@ -157,4 +152,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -47,11 +47,11 @@ namespace Server.Items
--weapon.PoisonCharges;
// Infectious strike special move now uses poisoning skill to help determine potency
int maxLevel = attacker.Skills[SkillName.Poisoning].Fixed / 200;
int maxLevel = attacker.Skills.Poisoning.Fixed / 200;
if (maxLevel < 0) maxLevel = 0;
if (p.Level > maxLevel) p = Poison.GetPoison(maxLevel);
if (attacker.Skills[SkillName.Poisoning].Value / 100.0 > Utility.RandomDouble())
if (attacker.Skills.Poisoning.Value / 100.0 > Utility.RandomDouble())
{
int level = p.Level + 1;
Poison newPoison = Poison.GetPoison(level);

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -13,7 +13,7 @@ namespace Server.Items
public static readonly TimeSpan PlayerDuration = TimeSpan.FromSeconds(6.0);
public static readonly TimeSpan NPCDuration = TimeSpan.FromSeconds(12.0);
private static Hashtable m_Table = new Hashtable();
private static Dictionary<Mobile, InternalTimer> m_Table = new Dictionary<Mobile, InternalTimer>();
public override int BaseMana => 30;
@ -36,33 +36,29 @@ namespace Server.Items
public static bool IsWounded(Mobile m)
{
return m_Table.Contains(m);
return m_Table.ContainsKey(m);
}
public static void BeginWound(Mobile m, TimeSpan duration)
{
Timer t = (Timer)m_Table[m];
InternalTimer timer = m_Table[m];
timer?.Stop();
t?.Stop();
t = new InternalTimer(m, duration);
m_Table[m] = t;
t.Start();
m_Table[m] = timer = new InternalTimer(m, duration);
timer.Start();
m.YellowHealthbar = true;
}
public static void EndWound(Mobile m)
{
if (!IsWounded(m))
return;
Timer timer = m_Table[m];
Timer t = (Timer)m_Table[m];
t?.Stop();
m_Table.Remove(m);
if (timer != null)
{
timer.Stop();
m_Table.Remove(m);
}
m.YellowHealthbar = false;
m.SendLocalizedMessage(1060208); // You are no longer mortally wounded.
@ -84,4 +80,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -59,10 +59,10 @@ namespace Server.Items
if (Core.ML)
{
AOS.Damage(defender, attacker,
(int)(15.0 * (attacker.Skills[SkillName.Bushido].Value - 50.0) / 70.0 + Utility.Random(10)), true, 100,
(int)(15.0 * (attacker.Skills.Bushido.Value - 50.0) / 70.0 + Utility.Random(10)), true, 100,
0, 0, 0, 0); //0-25
if (!cantpara && (150.0 / 7.0 + 4.0 * attacker.Skills[SkillName.Bushido].Value / 7.0) / 100.0 >
if (!cantpara && (150.0 / 7.0 + 4.0 * attacker.Skills.Bushido.Value / 7.0) / 100.0 >
Utility.RandomDouble())
{
defender.Paralyze(TimeSpan.FromSeconds(2.0));
@ -71,7 +71,7 @@ namespace Server.Items
}
else if (!cantpara)
{
AOS.Damage(defender, attacker, (int)(15.0 * (attacker.Skills[SkillName.Bushido].Value - 50.0) / 70.0 + 10),
AOS.Damage(defender, attacker, (int)(15.0 * (attacker.Skills.Bushido.Value - 50.0) / 70.0 + 10),
true, 100, 0, 0, 0, 0); //10-25
defender.Freeze(TimeSpan.FromSeconds(2.0));
Items.ParalyzingBlow.BeginImmunity(defender, Items.ParalyzingBlow.FreezeDelayDuration);

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -13,7 +14,7 @@ namespace Server.Items
public static readonly TimeSpan FreezeDelayDuration = TimeSpan.FromSeconds(8.0);
private static Hashtable m_Table = new Hashtable();
private static Dictionary<Mobile, InternalTimer> m_Table = new Dictionary<Mobile, InternalTimer>();
public override int BaseMana => 30;
@ -26,7 +27,7 @@ namespace Server.Items
if ( !(from.Weapon is Fists) )
return true;
Skill skill = from.Skills[SkillName.Anatomy];
Skill skill = from.Skills.Anatomy;
if ( skill != null && skill.Base >= 80.0 )
return true;
@ -38,10 +39,7 @@ namespace Server.Items
public override bool RequiresTactics(Mobile from)
{
if (!(from.Weapon is BaseWeapon weapon))
return true;
return weapon.Skill != SkillName.Wrestling;
return !(from.Weapon is BaseWeapon weapon && weapon.Skill == SkillName.Wrestling);
}
public override bool OnBeforeSwing(Mobile attacker, Mobile defender)
@ -85,27 +83,22 @@ namespace Server.Items
public static bool IsImmune(Mobile m)
{
return m_Table.Contains(m);
return m_Table.ContainsKey(m);
}
public static void BeginImmunity(Mobile m, TimeSpan duration)
{
Timer t = (Timer)m_Table[m];
InternalTimer timer = m_Table[m];
t?.Stop();
t = new InternalTimer(m, duration);
m_Table[m] = t;
t.Start();
timer?.Stop();
m_Table[m] = timer = new InternalTimer(m, duration);
timer.Start();
}
public static void EndImmunity(Mobile m)
{
Timer t = (Timer)m_Table[m];
t?.Stop();
InternalTimer timer = m_Table[m];
timer?.Stop();
m_Table.Remove(m);
}
@ -125,4 +118,4 @@ namespace Server.Items
}
}
}
}
}

View file

@ -47,7 +47,7 @@ namespace Server.Items
if (mount != null) //Ethy mounts don't take damage
{
int amount = 10 + (int)(10.0 * (attacker.Skills[SkillName.Bushido].Value - 50.0) / 70.0 + 5);
int amount = 10 + (int)(10.0 * (attacker.Skills.Bushido.Value - 50.0) / 70.0 + 5);
AOS.Damage(mount, null, amount, 100, 0, 0, 0,
0); //The mount just takes damage, there's no flagging as if it was attacking the mount directly
@ -57,7 +57,7 @@ namespace Server.Items
}
else
{
int amount = 10 + (int)(10.0 * (attacker.Skills[SkillName.Bushido].Value - 50.0) / 70.0 + 5);
int amount = 10 + (int)(10.0 * (attacker.Skills.Bushido.Value - 50.0) / 70.0 + 5);
AOS.Damage(defender, attacker, amount, 100, 0, 0, 0, 0);

View file

@ -20,7 +20,7 @@ namespace Server.Items
if (!base.CheckSkills(from))
return false;
Skill skill = from.Skills[SkillName.Stealth];
Skill skill = from.Skills.Stealth;
if (skill != null && skill.Value >= 80.0)
return true;

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
@ -8,7 +8,7 @@ namespace Server.Items
/// </summary>
public class TalonStrike : WeaponAbility
{
public static Hashtable Registry{ get; } = new Hashtable();
private static Dictionary<Mobile, InternalTimer> m_Table = new Dictionary<Mobile, InternalTimer>();
public override int BaseMana => 30;
public override double DamageScalar => 1.2;
@ -27,7 +27,7 @@ namespace Server.Items
public override void OnHit(Mobile attacker, Mobile defender, int damage)
{
if (Registry.Contains(defender) || !Validate(attacker) || !CheckMana(attacker, true))
if (m_Table.ContainsKey(defender) || !Validate(attacker) || !CheckMana(attacker, true))
return;
ClearCurrentAbility(attacker);
@ -37,23 +37,22 @@ namespace Server.Items
defender.FixedParticles(0x373A, 1, 17, 0x26BC, 0x662, 0, EffectLayer.Waist);
Timer t = new InternalTimer(defender,
(int)(10.0 * (attacker.Skills[SkillName.Ninjitsu].Value - 50.0) / 70.0 + 5), attacker); //5 - 15 damage
InternalTimer timer = new InternalTimer(defender,
(int)(10.0 * (attacker.Skills.Ninjitsu.Value - 50.0) / 70.0 + 5)); //5 - 15 damage
t.Start();
timer.Start();
Registry.Add(defender, t);
m_Table.Add(defender, timer);
}
private class InternalTimer : Timer
{
private readonly double DamagePerTick;
private Mobile m_Attacker;
private double m_DamageRemaining;
private double m_DamageToDo;
private Mobile m_Defender;
public InternalTimer(Mobile defender, int totalDamage, Mobile attacker)
public InternalTimer(Mobile defender, int totalDamage)
: base(TimeSpan.Zero, TimeSpan.FromSeconds(0.25),
12) // 3 seconds at .25 seconds apart = 12. Confirm delay inbetween of .25 each.
{
@ -61,8 +60,6 @@ namespace Server.Items
m_DamageRemaining = totalDamage;
Priority = TimerPriority.TwentyFiveMS;
m_Attacker = attacker;
DamagePerTick = (double)totalDamage / 12 + .01;
}
@ -71,7 +68,7 @@ namespace Server.Items
if (!m_Defender.Alive || m_DamageRemaining <= 0)
{
Stop();
Registry.Remove(m_Defender);
m_Table.Remove(m_Defender);
return;
}
@ -93,9 +90,9 @@ namespace Server.Items
if (!m_Defender.Alive || m_DamageRemaining <= 0)
{
Stop();
Registry.Remove(m_Defender);
m_Table.Remove(m_Defender);
}
}
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Engines.ConPVP;
using Server.Mobiles;
using Server.Network;
@ -12,52 +13,7 @@ namespace Server.Items
{
public abstract class WeaponAbility
{
public static readonly WeaponAbility ArmorIgnore = Abilities[1];
public static readonly WeaponAbility BleedAttack = Abilities[2];
public static readonly WeaponAbility ConcussionBlow = Abilities[3];
public static readonly WeaponAbility CrushingBlow = Abilities[4];
public static readonly WeaponAbility Disarm = Abilities[5];
public static readonly WeaponAbility Dismount = Abilities[6];
public static readonly WeaponAbility DoubleStrike = Abilities[7];
public static readonly WeaponAbility InfectiousStrike = Abilities[8];
public static readonly WeaponAbility MortalStrike = Abilities[9];
public static readonly WeaponAbility MovingShot = Abilities[10];
public static readonly WeaponAbility ParalyzingBlow = Abilities[11];
public static readonly WeaponAbility ShadowStrike = Abilities[12];
public static readonly WeaponAbility WhirlwindAttack = Abilities[13];
public static readonly WeaponAbility RidingSwipe = Abilities[14];
public static readonly WeaponAbility FrenziedWhirlwind = Abilities[15];
public static readonly WeaponAbility Block = Abilities[16];
public static readonly WeaponAbility DefenseMastery = Abilities[17];
public static readonly WeaponAbility NerveStrike = Abilities[18];
public static readonly WeaponAbility TalonStrike = Abilities[19];
public static readonly WeaponAbility Feint = Abilities[20];
public static readonly WeaponAbility DualWield = Abilities[21];
public static readonly WeaponAbility DoubleShot = Abilities[22];
public static readonly WeaponAbility ArmorPierce = Abilities[23];
public static readonly WeaponAbility Bladeweave = Abilities[24];
public static readonly WeaponAbility ForceArrow = Abilities[25];
public static readonly WeaponAbility LightningArrow = Abilities[26];
public static readonly WeaponAbility PsychicAttack = Abilities[27];
public static readonly WeaponAbility SerpentArrow = Abilities[28];
public static readonly WeaponAbility ForceOfNature = Abilities[29];
public static readonly WeaponAbility Disrobe = Abilities[30];
private static Hashtable m_PlayersTable = new Hashtable();
public virtual int BaseMana => 0;
public virtual int AccuracyBonus => 0;
public virtual double DamageScalar => 1.0;
public virtual bool RequiresSE => false;
public static WeaponAbility[] Abilities{ get; } = new WeaponAbility[31]
{
public static WeaponAbility[] Abilities{ get; } = {
null,
new ArmorIgnore(),
new BleedAttack(),
@ -92,7 +48,50 @@ namespace Server.Items
new Disrobe()
};
public static Hashtable Table{ get; } = new Hashtable();
public static readonly WeaponAbility ArmorIgnore = Abilities[1];
public static readonly WeaponAbility BleedAttack = Abilities[2];
public static readonly WeaponAbility ConcussionBlow = Abilities[3];
public static readonly WeaponAbility CrushingBlow = Abilities[4];
public static readonly WeaponAbility Disarm = Abilities[5];
public static readonly WeaponAbility Dismount = Abilities[6];
public static readonly WeaponAbility DoubleStrike = Abilities[7];
public static readonly WeaponAbility InfectiousStrike = Abilities[8];
public static readonly WeaponAbility MortalStrike = Abilities[9];
public static readonly WeaponAbility MovingShot = Abilities[10];
public static readonly WeaponAbility ParalyzingBlow = Abilities[11];
public static readonly WeaponAbility ShadowStrike = Abilities[12];
public static readonly WeaponAbility WhirlwindAttack = Abilities[13];
public static readonly WeaponAbility RidingSwipe = Abilities[14];
public static readonly WeaponAbility FrenziedWhirlwind = Abilities[15];
public static readonly WeaponAbility Block = Abilities[16];
public static readonly WeaponAbility DefenseMastery = Abilities[17];
public static readonly WeaponAbility NerveStrike = Abilities[18];
public static readonly WeaponAbility TalonStrike = Abilities[19];
public static readonly WeaponAbility Feint = Abilities[20];
public static readonly WeaponAbility DualWield = Abilities[21];
public static readonly WeaponAbility DoubleShot = Abilities[22];
public static readonly WeaponAbility ArmorPierce = Abilities[23];
public static readonly WeaponAbility Bladeweave = Abilities[24];
public static readonly WeaponAbility ForceArrow = Abilities[25];
public static readonly WeaponAbility LightningArrow = Abilities[26];
public static readonly WeaponAbility PsychicAttack = Abilities[27];
public static readonly WeaponAbility SerpentArrow = Abilities[28];
public static readonly WeaponAbility ForceOfNature = Abilities[29];
public static readonly WeaponAbility Disrobe = Abilities[30];
private static Dictionary<Mobile, WeaponAbilityContext> m_PlayersTable = new Dictionary<Mobile, WeaponAbilityContext>();
public virtual int BaseMana => 0;
public virtual int AccuracyBonus => 0;
public virtual double DamageScalar => 1.0;
public virtual bool RequiresSE => false;
public static Dictionary<Mobile, WeaponAbility> Table{ get; } = new Dictionary<Mobile, WeaponAbility>();
public virtual bool ValidatesDuringHit => true;
@ -122,12 +121,13 @@ namespace Server.Items
public virtual double GetRequiredSkill(Mobile from)
{
BaseWeapon weapon = from.Weapon as BaseWeapon;
if (weapon != null && weapon.PrimaryAbility == this)
return 70.0;
if (weapon != null && weapon.SecondaryAbility == this)
return 90.0;
if (from.Weapon is BaseWeapon weapon)
{
if (weapon.PrimaryAbility == this)
return 70.0;
if (weapon.SecondaryAbility == this)
return 90.0;
}
return 200.0;
}
@ -177,7 +177,7 @@ namespace Server.Items
double reqSkill = GetRequiredSkill(from);
bool reqTactics = Core.ML && RequiresTactics(from);
if (Core.ML && reqTactics && from.Skills[SkillName.Tactics].Base < reqSkill)
if (Core.ML && reqTactics && from.Skills.Tactics.Base < reqSkill)
{
from.SendLocalizedMessage(1079308,
reqSkill.ToString()); // You need ~1_SKILL_REQUIREMENT~ weapon and tactics skill to perform that attack
@ -188,9 +188,9 @@ namespace Server.Items
return true;
/* <UBWS> */
if (weapon.WeaponAttributes.UseBestSkill > 0 && (from.Skills[SkillName.Swords].Base >= reqSkill ||
from.Skills[SkillName.Macing].Base >= reqSkill ||
from.Skills[SkillName.Fencing].Base >= reqSkill))
if (weapon.WeaponAttributes.UseBestSkill > 0 && (from.Skills.Swords.Base >= reqSkill ||
from.Skills.Macing.Base >= reqSkill ||
from.Skills.Fencing.Base >= reqSkill))
return true;
/* </UBWS> */
@ -338,13 +338,8 @@ namespace Server.Items
public static bool IsWeaponAbility(Mobile m, WeaponAbility a)
{
if (a == null)
return true;
if (!m.Player)
return true;
return m.Weapon is BaseWeapon weapon && (weapon.PrimaryAbility == a || weapon.SecondaryAbility == a);
return a == null || !m.Player || m.Weapon is BaseWeapon weapon &&
(weapon.PrimaryAbility == a || weapon.SecondaryAbility == a);
}
public static WeaponAbility GetCurrentAbility(Mobile m)
@ -355,7 +350,7 @@ namespace Server.Items
return null;
}
WeaponAbility a = (WeaponAbility)Table[m];
WeaponAbility a = Table[m];
if (!IsWeaponAbility(m, a))
{
@ -363,7 +358,7 @@ namespace Server.Items
return null;
}
if (a != null && a.ValidatesDuringHit && !a.Validate(m))
if (a?.ValidatesDuringHit == true && !a.Validate(m))
{
ClearCurrentAbility(m);
return null;
@ -451,7 +446,7 @@ namespace Server.Items
private static WeaponAbilityContext GetContext(Mobile m)
{
return m_PlayersTable[m] as WeaponAbilityContext;
return m_PlayersTable[m];
}
private class WeaponAbilityTimer : Timer
@ -481,4 +476,4 @@ namespace Server.Items
public Timer Timer{ get; }
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Spells;
namespace Server.Items
@ -33,16 +34,16 @@ namespace Server.Items
attacker.FixedEffect(0x3728, 10, 15);
attacker.PlaySound(0x2A1);
ArrayList list = new ArrayList();
List<Mobile> list = new List<Mobile>();
foreach (Mobile m in attacker.GetMobilesInRange(1))
list.Add(m);
ArrayList targets = new ArrayList();
List<Mobile> targets = new List<Mobile>();
for (int i = 0; i < list.Count; ++i)
{
Mobile m = (Mobile)list[i];
Mobile m = list[i];
if (m != defender && m != attacker && SpellHelper.ValidIndirectTarget(attacker, m))
{
@ -70,7 +71,7 @@ namespace Server.Items
for (int i = 0; i < targets.Count; ++i)
{
Mobile m = (Mobile)targets[i];
Mobile m = targets[i];
attacker.SendLocalizedMessage(1060161); // The whirling attack strikes a target!
m.SendLocalizedMessage(1060162); // You are struck by the whirling attack and take damage!