fix: Weapons cleanup (#857)
* Removes linq * Removes list allocation for area effect * Removes redundant swing overload * Cleans up code
This commit is contained in:
parent
09613e2536
commit
43db0d09c9
4 changed files with 173 additions and 215 deletions
|
|
@ -22,8 +22,7 @@ namespace Server
|
||||||
{
|
{
|
||||||
int MaxRange { get; }
|
int MaxRange { get; }
|
||||||
void OnBeforeSwing(Mobile attacker, Mobile defender);
|
void OnBeforeSwing(Mobile attacker, Mobile defender);
|
||||||
TimeSpan OnSwing(Mobile attacker, Mobile defender);
|
TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0);
|
||||||
TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus);
|
|
||||||
void GetStatusDamage(Mobile from, out int min, out int max);
|
void GetStatusDamage(Mobile from, out int min, out int max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using Server.Collections;
|
||||||
using Server.Engines.Craft;
|
using Server.Engines.Craft;
|
||||||
using Server.Ethics;
|
using Server.Ethics;
|
||||||
using Server.Factions;
|
using Server.Factions;
|
||||||
|
|
@ -695,8 +695,6 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender) => OnSwing(attacker, defender, 1.0);
|
|
||||||
|
|
||||||
public virtual void GetStatusDamage(Mobile from, out int min, out int max)
|
public virtual void GetStatusDamage(Mobile from, out int min, out int max)
|
||||||
{
|
{
|
||||||
GetBaseDamageRange(from, out var baseMin, out var baseMax);
|
GetBaseDamageRange(from, out var baseMin, out var baseMax);
|
||||||
|
|
@ -713,7 +711,7 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus)
|
public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0)
|
||||||
{
|
{
|
||||||
var canSwing = true;
|
var canSwing = true;
|
||||||
|
|
||||||
|
|
@ -723,12 +721,12 @@ namespace Server.Items
|
||||||
|
|
||||||
if (canSwing)
|
if (canSwing)
|
||||||
{
|
{
|
||||||
canSwing = !(attacker.Spell is Spell sp) || !sp.IsCasting || !sp.BlocksMovement;
|
canSwing = attacker.Spell is not Spell sp || !sp.IsCasting || !sp.BlocksMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSwing)
|
if (canSwing)
|
||||||
{
|
{
|
||||||
canSwing = !(attacker is PlayerMobile p) || p.PeacedUntil <= Core.Now;
|
canSwing = attacker is not PlayerMobile p || p.PeacedUntil <= Core.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -786,7 +784,7 @@ namespace Server.Items
|
||||||
|
|
||||||
public override void OnAfterDuped(Item newItem)
|
public override void OnAfterDuped(Item newItem)
|
||||||
{
|
{
|
||||||
if (!(newItem is BaseWeapon weap))
|
if (newItem is not BaseWeapon weap)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -877,8 +875,8 @@ namespace Server.Items
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) &&
|
if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && item is not BaseShield &&
|
||||||
!(item is BaseEquipableLight))
|
item is not BaseEquipableLight)
|
||||||
{
|
{
|
||||||
m.SendLocalizedMessage(500215); // You can only wield one weapon at a time.
|
m.SendLocalizedMessage(500215); // You can only wield one weapon at a time.
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1096,7 +1094,6 @@ namespace Server.Items
|
||||||
var defWeapon = defender.Weapon as BaseWeapon;
|
var defWeapon = defender.Weapon as BaseWeapon;
|
||||||
|
|
||||||
var atkSkill = attacker.Skills[atkWeapon?.Skill ?? SkillName.Wrestling];
|
var atkSkill = attacker.Skills[atkWeapon?.Skill ?? SkillName.Wrestling];
|
||||||
// Skill defSkill = defender.Skills[defWeapon.Skill];
|
|
||||||
|
|
||||||
var atkValue = atkWeapon?.GetAttackSkillValue(attacker, defender) ?? 0.0;
|
var atkValue = atkWeapon?.GetAttackSkillValue(attacker, defender) ?? 0.0;
|
||||||
var defValue = defWeapon?.GetDefendSkillValue(attacker, defender) ?? 0.0;
|
var defValue = defWeapon?.GetDefendSkillValue(attacker, defender) ?? 0.0;
|
||||||
|
|
@ -1209,23 +1206,11 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (atkValue <= -50.0)
|
ourValue = Math.Max(0.1, atkValue + 50.0);
|
||||||
{
|
theirValue = Math.Max(0.1, defValue + 50.0);
|
||||||
atkValue = -49.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defValue <= -50.0)
|
|
||||||
{
|
|
||||||
defValue = -49.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
ourValue = atkValue + 50.0;
|
|
||||||
theirValue = defValue + 50.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var chance = ourValue / (theirValue * 2.0);
|
var chance = ourValue / (theirValue * 2.0) * 1.0 + (double)bonus / 100;
|
||||||
|
|
||||||
chance *= 1.0 + (double)bonus / 100;
|
|
||||||
|
|
||||||
if (Core.AOS && chance < 0.02)
|
if (Core.AOS && chance < 0.02)
|
||||||
{
|
{
|
||||||
|
|
@ -1418,7 +1403,7 @@ namespace Server.Items
|
||||||
return defender.CheckSkill(SkillName.Parry, chance);
|
return defender.CheckSkill(SkillName.Parry, chance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defender.Weapon is Fists || defender.Weapon is BaseRanged)
|
if (defender.Weapon is Server.Items.Fists or BaseRanged)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1459,9 +1444,8 @@ namespace Server.Items
|
||||||
return defender.CheckSkill(SkillName.Parry, chance);
|
return defender.CheckSkill(SkillName.Parry, chance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
// Only skillcheck if wielding a shield & there's no effect from Bushido
|
||||||
aosChance > Utility
|
return aosChance > Utility.RandomDouble();
|
||||||
.RandomDouble(); // Only skillcheck if wielding a shield & there's no effect from Bushido
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int AbsorbDamageAOS(Mobile attacker, Mobile defender, int damage)
|
public virtual int AbsorbDamageAOS(Mobile attacker, Mobile defender, int damage)
|
||||||
|
|
@ -1493,9 +1477,8 @@ namespace Server.Items
|
||||||
|
|
||||||
if (Confidence.IsConfident(defender))
|
if (Confidence.IsConfident(defender))
|
||||||
{
|
{
|
||||||
defender.SendLocalizedMessage(
|
// Your confidence reassures you as you successfully block your opponent's blow.
|
||||||
1063117
|
defender.SendLocalizedMessage(1063117);
|
||||||
); // Your confidence reassures you as you successfully block your opponent's blow.
|
|
||||||
|
|
||||||
var bushido = defender.Skills.Bushido.Value;
|
var bushido = defender.Skills.Bushido.Value;
|
||||||
|
|
||||||
|
|
@ -1590,7 +1573,7 @@ namespace Server.Items
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(attacker is BaseCreature bc) || bc.PackInstinct == PackInstinct.None || !bc.Controlled && !bc.Summoned)
|
if (attacker is not BaseCreature bc || bc.PackInstinct == PackInstinct.None || !bc.Controlled && !bc.Summoned)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1603,16 +1586,26 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
|
|
||||||
var eable = defender.GetMobilesInRange<BaseCreature>(1);
|
var eable = defender.GetMobilesInRange<BaseCreature>(1);
|
||||||
var inPack = 1 + eable
|
var inPack = 1;
|
||||||
.Where(m => m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned))
|
foreach (var m in eable)
|
||||||
.Count(m => master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender);
|
{
|
||||||
|
if (m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned) &&
|
||||||
|
master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender)
|
||||||
|
{
|
||||||
|
inPack++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
|
|
||||||
return inPack >= 5 ? 100 :
|
return inPack switch
|
||||||
inPack >= 4 ? 75 :
|
{
|
||||||
inPack >= 3 ? 50 :
|
>= 5 => 100,
|
||||||
inPack >= 2 ? 25 : 0;
|
4 => 75,
|
||||||
|
3 => 50,
|
||||||
|
2 => 25,
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus = 1.0)
|
public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus = 1.0)
|
||||||
|
|
@ -1688,12 +1681,9 @@ namespace Server.Items
|
||||||
|
|
||||||
if (!attacker.Player)
|
if (!attacker.Player)
|
||||||
{
|
{
|
||||||
if (defender is PlayerMobile pm)
|
if (defender is PlayerMobile pm && pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType())
|
||||||
{
|
{
|
||||||
if (pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType())
|
percentageBonus += 100;
|
||||||
{
|
|
||||||
percentageBonus += 100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!defender.Player)
|
else if (!defender.Player)
|
||||||
|
|
@ -1769,16 +1759,14 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
damage = 1;
|
damage = 1;
|
||||||
}
|
}
|
||||||
else if (Core.AOS && damage == 0) // parried
|
// Parried
|
||||||
|
else if (Core.AOS && damage == 0 && a?.Validate(attacker) == true)
|
||||||
{
|
{
|
||||||
if (a?.Validate(attacker) == true) /*&& a.CheckMana( attacker, true )*/
|
/*&& a.CheckMana( attacker, true )*/
|
||||||
// Parried special moves have no mana cost
|
// Parried special moves have no mana cost
|
||||||
{
|
a = null;
|
||||||
a = null;
|
WeaponAbility.ClearCurrentAbility(attacker);
|
||||||
WeaponAbility.ClearCurrentAbility(attacker);
|
attacker.SendLocalizedMessage(1061140); // Your attack was parried!
|
||||||
|
|
||||||
attacker.SendLocalizedMessage(1061140); // Your attack was parried!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AddBlood(attacker, defender, damage);
|
AddBlood(attacker, defender, damage);
|
||||||
|
|
@ -1936,9 +1924,8 @@ namespace Server.Items
|
||||||
|
|
||||||
if (context?.Type == typeof(WraithFormSpell))
|
if (context?.Type == typeof(WraithFormSpell))
|
||||||
{
|
{
|
||||||
wraithLeech =
|
// Wraith form gives an additional 5-20% mana leech
|
||||||
5 + (int)(15 * attacker.Skills.SpiritSpeak.Value /
|
wraithLeech = 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value / 100);
|
||||||
100); // Wraith form gives an additional 5-20% mana leech
|
|
||||||
|
|
||||||
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
|
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
|
||||||
defender.Mana -= AOS.Scale(damageGiven, wraithLeech);
|
defender.Mana -= AOS.Scale(damageGiven, wraithLeech);
|
||||||
|
|
@ -1967,10 +1954,10 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_MaxHits > 0 && (MaxRange <= 1 && (defender is Slime || defender is AcidElemental) ||
|
// Stratics says 50% chance, seems more like 4%..
|
||||||
Utility.RandomDouble() < .04)) // Stratics says 50% chance, seems more like 4%..
|
if (m_MaxHits > 0 && MaxRange <= 1 && defender is Slime or AcidElemental |Utility.RandomDouble() < .04)
|
||||||
{
|
{
|
||||||
if (MaxRange <= 1 && (defender is Slime || defender is AcidElemental))
|
if (MaxRange <= 1 && defender is Slime or AcidElemental)
|
||||||
{
|
{
|
||||||
attacker.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500263); // *Acid blood scars your weapon!*
|
attacker.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500263); // *Acid blood scars your weapon!*
|
||||||
}
|
}
|
||||||
|
|
@ -1979,29 +1966,23 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
HitPoints += 2;
|
HitPoints += 2;
|
||||||
}
|
}
|
||||||
|
else if (m_Hits > 0)
|
||||||
|
{
|
||||||
|
--HitPoints;
|
||||||
|
}
|
||||||
|
else if (m_MaxHits > 1)
|
||||||
|
{
|
||||||
|
--MaxHitPoints;
|
||||||
|
|
||||||
|
if (Parent is Mobile mobile)
|
||||||
|
{
|
||||||
|
// Your equipment is severely damaged.
|
||||||
|
mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061121);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_Hits > 0)
|
Delete();
|
||||||
{
|
|
||||||
--HitPoints;
|
|
||||||
}
|
|
||||||
else if (m_MaxHits > 1)
|
|
||||||
{
|
|
||||||
--MaxHitPoints;
|
|
||||||
|
|
||||||
if (Parent is Mobile mobile)
|
|
||||||
{
|
|
||||||
mobile.LocalOverheadMessage(
|
|
||||||
MessageType.Regular,
|
|
||||||
0x3B2,
|
|
||||||
1061121 // Your equipment is severely damaged.
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2021,16 +2002,20 @@ namespace Server.Items
|
||||||
|
|
||||||
if (Core.AOS)
|
if (Core.AOS)
|
||||||
{
|
{
|
||||||
var physChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) *
|
var physChance =
|
||||||
propertyBonus);
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) * propertyBonus);
|
||||||
|
|
||||||
var fireChance =
|
var fireChance =
|
||||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitFireArea) * propertyBonus);
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitFireArea) * propertyBonus);
|
||||||
|
|
||||||
var coldChance =
|
var coldChance =
|
||||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitColdArea) * propertyBonus);
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitColdArea) * propertyBonus);
|
||||||
var poisChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) *
|
|
||||||
propertyBonus);
|
var poisChance =
|
||||||
var nrgyChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) *
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) * propertyBonus);
|
||||||
propertyBonus);
|
|
||||||
|
var nrgyChance =
|
||||||
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) * propertyBonus);
|
||||||
|
|
||||||
if (physChance != 0 && physChance > Utility.Random(100))
|
if (physChance != 0 && physChance > Utility.Random(100))
|
||||||
{
|
{
|
||||||
|
|
@ -2092,10 +2077,10 @@ namespace Server.Items
|
||||||
DoDispel(attacker, defender);
|
DoDispel(attacker, defender);
|
||||||
}
|
}
|
||||||
|
|
||||||
var laChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) *
|
var laChance =
|
||||||
propertyBonus);
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) * propertyBonus);
|
||||||
var ldChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) *
|
var ldChance =
|
||||||
propertyBonus);
|
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) * propertyBonus);
|
||||||
|
|
||||||
if (laChance != 0 && laChance > Utility.Random(100))
|
if (laChance != 0 && laChance > Utility.Random(100))
|
||||||
{
|
{
|
||||||
|
|
@ -2121,7 +2106,7 @@ namespace Server.Items
|
||||||
it.ReceivedHonorContext?.OnTargetHit(attacker);
|
it.ReceivedHonorContext?.OnTargetHit(attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(this is BaseRanged))
|
if (this is not BaseRanged)
|
||||||
{
|
{
|
||||||
if (AnimalForm.UnderTransformation(attacker, typeof(GiantSerpent)))
|
if (AnimalForm.UnderTransformation(attacker, typeof(GiantSerpent)))
|
||||||
{
|
{
|
||||||
|
|
@ -2157,7 +2142,7 @@ namespace Server.Items
|
||||||
// SDI bonus
|
// SDI bonus
|
||||||
damageBonus += AosAttributes.GetValue(attacker, AosAttribute.SpellDamage);
|
damageBonus += AosAttributes.GetValue(attacker, AosAttribute.SpellDamage);
|
||||||
|
|
||||||
if(PsychicAttack.Registry.TryGetValue(attacker,out var timer))
|
if (PsychicAttack.Registry.TryGetValue(attacker,out var timer))
|
||||||
{
|
{
|
||||||
damageBonus -= timer.SpellDamageMalus;
|
damageBonus -= timer.SpellDamageMalus;
|
||||||
}
|
}
|
||||||
|
|
@ -2319,13 +2304,8 @@ namespace Server.Items
|
||||||
attacker.PlaySound(GetMissAttackSound(attacker, defender));
|
attacker.PlaySound(GetMissAttackSound(attacker, defender));
|
||||||
defender.PlaySound(GetMissDefendSound(attacker, defender));
|
defender.PlaySound(GetMissDefendSound(attacker, defender));
|
||||||
|
|
||||||
var ability = WeaponAbility.GetCurrentAbility(attacker);
|
WeaponAbility.GetCurrentAbility(attacker)?.OnMiss(attacker, defender);
|
||||||
|
SpecialMove.GetCurrentMove(attacker)?.OnMiss(attacker, defender);
|
||||||
ability?.OnMiss(attacker, defender);
|
|
||||||
|
|
||||||
var move = SpecialMove.GetCurrentMove(attacker);
|
|
||||||
|
|
||||||
move?.OnMiss(attacker, defender);
|
|
||||||
|
|
||||||
if (defender is IHonorTarget target)
|
if (defender is IHonorTarget target)
|
||||||
{
|
{
|
||||||
|
|
@ -2417,56 +2397,38 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
var bonus = VirtualDamageBonus;
|
var bonus = VirtualDamageBonus;
|
||||||
|
|
||||||
switch (m_Quality)
|
bonus += m_Quality switch
|
||||||
{
|
{
|
||||||
case WeaponQuality.Low:
|
WeaponQuality.Low => -20,
|
||||||
bonus -= 20;
|
WeaponQuality.Exceptional => 20,
|
||||||
break;
|
_ => 0
|
||||||
case WeaponQuality.Exceptional:
|
};
|
||||||
bonus += 20;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_DamageLevel)
|
return bonus + m_DamageLevel switch
|
||||||
{
|
{
|
||||||
case WeaponDamageLevel.Ruin:
|
WeaponDamageLevel.Ruin => 15,
|
||||||
bonus += 15;
|
WeaponDamageLevel.Might => 20,
|
||||||
break;
|
WeaponDamageLevel.Force => 25,
|
||||||
case WeaponDamageLevel.Might:
|
WeaponDamageLevel.Power => 30,
|
||||||
bonus += 20;
|
WeaponDamageLevel.Vanq => 35,
|
||||||
break;
|
_ => bonus
|
||||||
case WeaponDamageLevel.Force:
|
};
|
||||||
bonus += 25;
|
|
||||||
break;
|
|
||||||
case WeaponDamageLevel.Power:
|
|
||||||
bonus += 30;
|
|
||||||
break;
|
|
||||||
case WeaponDamageLevel.Vanq:
|
|
||||||
bonus += 35;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bonus;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills)
|
public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills)
|
||||||
{
|
{
|
||||||
if (checkSkills)
|
if (checkSkills)
|
||||||
{
|
{
|
||||||
attacker.CheckSkill(
|
// Passively check tactics for gain
|
||||||
SkillName.Tactics,
|
attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap);
|
||||||
0.0,
|
|
||||||
attacker.Skills.Tactics.Cap
|
// Passively check Anatomy for gain
|
||||||
); // Passively check tactics for gain
|
attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap);
|
||||||
attacker.CheckSkill(
|
|
||||||
SkillName.Anatomy,
|
|
||||||
0.0,
|
|
||||||
attacker.Skills.Anatomy.Cap
|
|
||||||
); // Passively check Anatomy for gain
|
|
||||||
|
|
||||||
if (Type == WeaponType.Axe)
|
if (Type == WeaponType.Axe)
|
||||||
{
|
{
|
||||||
attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); // Passively check Lumberjacking for gain
|
// Passively check Lumberjacking for gain
|
||||||
|
attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2536,20 +2498,16 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
if (checkSkills)
|
if (checkSkills)
|
||||||
{
|
{
|
||||||
attacker.CheckSkill(
|
// Passively check tactics for gain
|
||||||
SkillName.Tactics,
|
attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap);
|
||||||
0.0,
|
|
||||||
attacker.Skills.Tactics.Cap
|
// Passively check Anatomy for gain
|
||||||
); // Passively check tactics for gain
|
attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap);
|
||||||
attacker.CheckSkill(
|
|
||||||
SkillName.Anatomy,
|
|
||||||
0.0,
|
|
||||||
attacker.Skills.Anatomy.Cap
|
|
||||||
); // Passively check Anatomy for gain
|
|
||||||
|
|
||||||
if (Type == WeaponType.Axe)
|
if (Type == WeaponType.Axe)
|
||||||
{
|
{
|
||||||
attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); // Passively check Lumberjacking for gain
|
// Passively check Lumberjacking for gain
|
||||||
|
attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2633,9 +2591,9 @@ namespace Server.Items
|
||||||
var damage = (int)ScaleDamageOld(attacker, GetBaseDamage(attacker), true);
|
var damage = (int)ScaleDamageOld(attacker, GetBaseDamage(attacker), true);
|
||||||
|
|
||||||
// pre-AOS, halve damage if the defender is a player or the attacker is not a player
|
// pre-AOS, halve damage if the defender is a player or the attacker is not a player
|
||||||
if (defender is PlayerMobile || !(attacker is PlayerMobile))
|
if (defender is PlayerMobile || attacker is not PlayerMobile)
|
||||||
{
|
{
|
||||||
damage = (int)(damage / 2.0);
|
damage /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
|
|
@ -2643,6 +2601,11 @@ namespace Server.Items
|
||||||
|
|
||||||
public virtual void PlayHurtAnimation(Mobile from)
|
public virtual void PlayHurtAnimation(Mobile from)
|
||||||
{
|
{
|
||||||
|
if (from.Mounted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int action;
|
int action;
|
||||||
int frames;
|
int frames;
|
||||||
|
|
||||||
|
|
@ -2667,12 +2630,10 @@ namespace Server.Items
|
||||||
frames = 5;
|
frames = 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: return;
|
default:
|
||||||
}
|
{
|
||||||
|
return;
|
||||||
if (from.Mounted)
|
}
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
from.Animate(action, frames, 1, true, false, 0);
|
from.Animate(action, frames, 1, true, false, 0);
|
||||||
|
|
@ -2695,10 +2656,18 @@ namespace Server.Items
|
||||||
switch (Animation)
|
switch (Animation)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
action = Utility.Random(4, 3);
|
{
|
||||||
break;
|
action = Utility.Random(4, 3);
|
||||||
case WeaponAnimation.ShootBow: return; // 7
|
break;
|
||||||
case WeaponAnimation.ShootXBow: return; // 8
|
}
|
||||||
|
case WeaponAnimation.ShootBow:
|
||||||
|
{
|
||||||
|
return; // 7
|
||||||
|
}
|
||||||
|
case WeaponAnimation.ShootXBow:
|
||||||
|
{
|
||||||
|
return; // 8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -2728,7 +2697,10 @@ namespace Server.Items
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: return;
|
default:
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
from.Animate(action, 7, 1, true, false, 0);
|
from.Animate(action, 7, 1, true, false, 0);
|
||||||
|
|
@ -2739,11 +2711,11 @@ namespace Server.Items
|
||||||
public int GetElementalDamageHue()
|
public int GetElementalDamageHue()
|
||||||
{
|
{
|
||||||
GetDamageTypes(null, out _, out var fire, out var cold, out var pois, out var nrgy, out _, out _);
|
GetDamageTypes(null, out _, out var fire, out var cold, out var pois, out var nrgy, out _, out _);
|
||||||
// Order is Cold, Energy, Fire, Poison, Physical left
|
|
||||||
|
|
||||||
var currentMax = 50;
|
var currentMax = 50;
|
||||||
var hue = 0;
|
var hue = 0;
|
||||||
|
|
||||||
|
// Order is Cold, Energy, Fire, Poison, Physical
|
||||||
if (pois >= currentMax)
|
if (pois >= currentMax)
|
||||||
{
|
{
|
||||||
hue = 1267 + (pois - 50) / 10;
|
hue = 1267 + (pois - 50) / 10;
|
||||||
|
|
@ -2812,7 +2784,7 @@ namespace Server.Items
|
||||||
* formatting show, and remove CLILOCs embedded: more like OSI
|
* formatting show, and remove CLILOCs embedded: more like OSI
|
||||||
* did with the books that had markup, etc.
|
* did with the books that had markup, etc.
|
||||||
*
|
*
|
||||||
* This will have a negative effect on a few event things imgame
|
* This will have a negative effect on a few event things in-game
|
||||||
* as is.
|
* as is.
|
||||||
*
|
*
|
||||||
* If we cant find a more OSI-ish way to clean it up, we can
|
* If we cant find a more OSI-ish way to clean it up, we can
|
||||||
|
|
@ -2828,29 +2800,10 @@ namespace Server.Items
|
||||||
/* list.Add( 1062613, Utility.FixHtml( m_EngravedText ) ); */
|
/* list.Add( 1062613, Utility.FixHtml( m_EngravedText ) ); */
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool AllowEquippedCast(Mobile from)
|
public override bool AllowEquippedCast(Mobile from) =>
|
||||||
{
|
base.AllowEquippedCast(from) || Attributes.SpellChanneling != 0;
|
||||||
if (base.AllowEquippedCast(from))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Attributes.SpellChanneling != 0;
|
public virtual int GetLuckBonus() => CraftResources.GetInfo(m_Resource)?.AttributeInfo?.WeaponLuck ?? 0;
|
||||||
}
|
|
||||||
|
|
||||||
public virtual int GetLuckBonus()
|
|
||||||
{
|
|
||||||
var resInfo = CraftResources.GetInfo(m_Resource);
|
|
||||||
|
|
||||||
var attrInfo = resInfo?.AttributeInfo;
|
|
||||||
|
|
||||||
if (attrInfo == null)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return attrInfo.WeaponLuck;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetProperties(ObjectPropertyList list)
|
public override void GetProperties(ObjectPropertyList list)
|
||||||
{
|
{
|
||||||
|
|
@ -3235,17 +3188,25 @@ namespace Server.Items
|
||||||
switch (Skill)
|
switch (Skill)
|
||||||
{
|
{
|
||||||
case SkillName.Swords:
|
case SkillName.Swords:
|
||||||
list.Add(1061172);
|
{
|
||||||
break; // skill required: swordsmanship
|
list.Add(1061172); // skill required: swordsmanship
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SkillName.Macing:
|
case SkillName.Macing:
|
||||||
list.Add(1061173);
|
{
|
||||||
break; // skill required: mace fighting
|
list.Add(1061173); // skill required: mace fighting
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SkillName.Fencing:
|
case SkillName.Fencing:
|
||||||
list.Add(1061174);
|
{
|
||||||
break; // skill required: fencing
|
list.Add(1061174); // skill required: fencing
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SkillName.Archery:
|
case SkillName.Archery:
|
||||||
list.Add(1061175);
|
{
|
||||||
break; // skill required: archery
|
list.Add(1061175); // skill required: archery
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3351,13 +3312,7 @@ namespace Server.Items
|
||||||
public virtual int GetHitAttackSound(Mobile attacker, Mobile defender)
|
public virtual int GetHitAttackSound(Mobile attacker, Mobile defender)
|
||||||
{
|
{
|
||||||
var sound = attacker.GetAttackSound();
|
var sound = attacker.GetAttackSound();
|
||||||
|
return sound == -1 ? HitSound : sound;
|
||||||
if (sound == -1)
|
|
||||||
{
|
|
||||||
sound = HitSound;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sound;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int GetHitDefendSound(Mobile attacker, Mobile defender) => defender.GetHurtSound();
|
public virtual int GetHitDefendSound(Mobile attacker, Mobile defender) => defender.GetHurtSound();
|
||||||
|
|
@ -3518,33 +3473,37 @@ namespace Server.Items
|
||||||
var range = Core.ML ? 5 : 10;
|
var range = Core.ML ? 5 : 10;
|
||||||
|
|
||||||
var eable = from.GetMobilesInRange(range);
|
var eable = from.GetMobilesInRange(range);
|
||||||
var list = eable.Where(
|
using var queue = PooledRefQueue<Mobile>.Create();
|
||||||
m =>
|
foreach (var m in eable)
|
||||||
from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m)
|
{
|
||||||
&& from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m))
|
if (from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m)
|
||||||
)
|
&& from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m)))
|
||||||
.ToList();
|
{
|
||||||
|
queue.Enqueue(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
eable.Free();
|
eable.Free();
|
||||||
|
|
||||||
if (list.Count == 0)
|
if (queue.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(from.Location, map, sound);
|
Effects.PlaySound(from.Location, map, sound);
|
||||||
|
|
||||||
for (var i = 0; i < list.Count; ++i)
|
while (queue.Count > 0)
|
||||||
{
|
{
|
||||||
var m = list[i];
|
var m = queue.Dequeue();
|
||||||
|
|
||||||
var scalar = Core.ML ? 1.0 : (11 - from.GetDistanceToSqrt(m)) / 10;
|
var scalar = Core.ML ? 1.0 : (11 - from.GetDistanceToSqrt(m)) / 10;
|
||||||
var damage = GetBaseDamage(from);
|
|
||||||
|
|
||||||
if (scalar <= 0)
|
if (scalar <= 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var damage = GetBaseDamage(from);
|
||||||
|
|
||||||
if (scalar < 1.0)
|
if (scalar < 1.0)
|
||||||
{
|
{
|
||||||
damage *= (11 - from.GetDistanceToSqrt(m)) / 10;
|
damage *= (11 - from.GetDistanceToSqrt(m)) / 10;
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TimeSpan OnSwing(Mobile attacker, Mobile defender)
|
public override TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0)
|
||||||
{
|
{
|
||||||
if (!Core.AOS)
|
if (!Core.AOS)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ namespace Server.Items
|
||||||
|
|
||||||
public override SkillName AccuracySkill => SkillName.Archery;
|
public override SkillName AccuracySkill => SkillName.Archery;
|
||||||
|
|
||||||
public override TimeSpan OnSwing(Mobile attacker, Mobile defender)
|
public override TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0)
|
||||||
{
|
{
|
||||||
// WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
|
// WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue