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
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Collections;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Ethics;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
@ -723,12 +721,12 @@ namespace Server.Items
|
|||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!(newItem is BaseWeapon weap))
|
||||
if (newItem is not BaseWeapon weap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -877,8 +875,8 @@ namespace Server.Items
|
|||
return true;
|
||||
}
|
||||
|
||||
if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) &&
|
||||
!(item is BaseEquipableLight))
|
||||
if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && item is not BaseShield &&
|
||||
item is not BaseEquipableLight)
|
||||
{
|
||||
m.SendLocalizedMessage(500215); // You can only wield one weapon at a time.
|
||||
return true;
|
||||
|
|
@ -1096,7 +1094,6 @@ namespace Server.Items
|
|||
var defWeapon = defender.Weapon as BaseWeapon;
|
||||
|
||||
var atkSkill = attacker.Skills[atkWeapon?.Skill ?? SkillName.Wrestling];
|
||||
// Skill defSkill = defender.Skills[defWeapon.Skill];
|
||||
|
||||
var atkValue = atkWeapon?.GetAttackSkillValue(attacker, defender) ?? 0.0;
|
||||
var defValue = defWeapon?.GetDefendSkillValue(attacker, defender) ?? 0.0;
|
||||
|
|
@ -1209,23 +1206,11 @@ namespace Server.Items
|
|||
}
|
||||
else
|
||||
{
|
||||
if (atkValue <= -50.0)
|
||||
{
|
||||
atkValue = -49.9;
|
||||
}
|
||||
|
||||
if (defValue <= -50.0)
|
||||
{
|
||||
defValue = -49.9;
|
||||
}
|
||||
|
||||
ourValue = atkValue + 50.0;
|
||||
theirValue = defValue + 50.0;
|
||||
ourValue = Math.Max(0.1, atkValue + 50.0);
|
||||
theirValue = Math.Max(0.1, defValue + 50.0);
|
||||
}
|
||||
|
||||
var chance = ourValue / (theirValue * 2.0);
|
||||
|
||||
chance *= 1.0 + (double)bonus / 100;
|
||||
var chance = ourValue / (theirValue * 2.0) * 1.0 + (double)bonus / 100;
|
||||
|
||||
if (Core.AOS && chance < 0.02)
|
||||
{
|
||||
|
|
@ -1418,7 +1403,7 @@ namespace Server.Items
|
|||
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;
|
||||
}
|
||||
|
|
@ -1459,9 +1444,8 @@ namespace Server.Items
|
|||
return defender.CheckSkill(SkillName.Parry, chance);
|
||||
}
|
||||
|
||||
return
|
||||
aosChance > Utility
|
||||
.RandomDouble(); // Only skillcheck if wielding a shield & there's no effect from Bushido
|
||||
// Only skillcheck if wielding a shield & there's no effect from Bushido
|
||||
return aosChance > Utility.RandomDouble();
|
||||
}
|
||||
|
||||
public virtual int AbsorbDamageAOS(Mobile attacker, Mobile defender, int damage)
|
||||
|
|
@ -1493,9 +1477,8 @@ namespace Server.Items
|
|||
|
||||
if (Confidence.IsConfident(defender))
|
||||
{
|
||||
defender.SendLocalizedMessage(
|
||||
1063117
|
||||
); // Your confidence reassures you as you successfully block your opponent's blow.
|
||||
// Your confidence reassures you as you successfully block your opponent's blow.
|
||||
defender.SendLocalizedMessage(1063117);
|
||||
|
||||
var bushido = defender.Skills.Bushido.Value;
|
||||
|
||||
|
|
@ -1590,7 +1573,7 @@ namespace Server.Items
|
|||
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;
|
||||
}
|
||||
|
|
@ -1603,16 +1586,26 @@ namespace Server.Items
|
|||
}
|
||||
|
||||
var eable = defender.GetMobilesInRange<BaseCreature>(1);
|
||||
var inPack = 1 + eable
|
||||
.Where(m => m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned))
|
||||
.Count(m => master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender);
|
||||
var inPack = 1;
|
||||
foreach (var m in eable)
|
||||
{
|
||||
if (m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned) &&
|
||||
master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender)
|
||||
{
|
||||
inPack++;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return inPack >= 5 ? 100 :
|
||||
inPack >= 4 ? 75 :
|
||||
inPack >= 3 ? 50 :
|
||||
inPack >= 2 ? 25 : 0;
|
||||
return inPack switch
|
||||
{
|
||||
>= 5 => 100,
|
||||
4 => 75,
|
||||
3 => 50,
|
||||
2 => 25,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
|
||||
public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus = 1.0)
|
||||
|
|
@ -1688,12 +1681,9 @@ namespace Server.Items
|
|||
|
||||
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)
|
||||
|
|
@ -1769,16 +1759,14 @@ namespace Server.Items
|
|||
{
|
||||
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 )*/
|
||||
// Parried special moves have no mana cost
|
||||
{
|
||||
a = null;
|
||||
WeaponAbility.ClearCurrentAbility(attacker);
|
||||
|
||||
attacker.SendLocalizedMessage(1061140); // Your attack was parried!
|
||||
}
|
||||
/*&& a.CheckMana( attacker, true )*/
|
||||
// Parried special moves have no mana cost
|
||||
a = null;
|
||||
WeaponAbility.ClearCurrentAbility(attacker);
|
||||
attacker.SendLocalizedMessage(1061140); // Your attack was parried!
|
||||
}
|
||||
|
||||
AddBlood(attacker, defender, damage);
|
||||
|
|
@ -1936,9 +1924,8 @@ namespace Server.Items
|
|||
|
||||
if (context?.Type == typeof(WraithFormSpell))
|
||||
{
|
||||
wraithLeech =
|
||||
5 + (int)(15 * attacker.Skills.SpiritSpeak.Value /
|
||||
100); // Wraith form gives an additional 5-20% mana leech
|
||||
// Wraith form gives an additional 5-20% mana leech
|
||||
wraithLeech = 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value / 100);
|
||||
|
||||
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
|
||||
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) ||
|
||||
Utility.RandomDouble() < .04)) // Stratics says 50% chance, seems more like 4%..
|
||||
// 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!*
|
||||
}
|
||||
|
|
@ -1979,29 +1966,23 @@ namespace Server.Items
|
|||
{
|
||||
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
|
||||
{
|
||||
if (m_Hits > 0)
|
||||
{
|
||||
--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();
|
||||
}
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2021,16 +2002,20 @@ namespace Server.Items
|
|||
|
||||
if (Core.AOS)
|
||||
{
|
||||
var physChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) *
|
||||
propertyBonus);
|
||||
var physChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) * propertyBonus);
|
||||
|
||||
var fireChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitFireArea) * propertyBonus);
|
||||
|
||||
var coldChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitColdArea) * propertyBonus);
|
||||
var poisChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) *
|
||||
propertyBonus);
|
||||
var nrgyChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) *
|
||||
propertyBonus);
|
||||
|
||||
var poisChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) * propertyBonus);
|
||||
|
||||
var nrgyChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) * propertyBonus);
|
||||
|
||||
if (physChance != 0 && physChance > Utility.Random(100))
|
||||
{
|
||||
|
|
@ -2092,10 +2077,10 @@ namespace Server.Items
|
|||
DoDispel(attacker, defender);
|
||||
}
|
||||
|
||||
var laChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) *
|
||||
propertyBonus);
|
||||
var ldChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) *
|
||||
propertyBonus);
|
||||
var laChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) * propertyBonus);
|
||||
var ldChance =
|
||||
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) * propertyBonus);
|
||||
|
||||
if (laChance != 0 && laChance > Utility.Random(100))
|
||||
{
|
||||
|
|
@ -2121,7 +2106,7 @@ namespace Server.Items
|
|||
it.ReceivedHonorContext?.OnTargetHit(attacker);
|
||||
}
|
||||
|
||||
if (!(this is BaseRanged))
|
||||
if (this is not BaseRanged)
|
||||
{
|
||||
if (AnimalForm.UnderTransformation(attacker, typeof(GiantSerpent)))
|
||||
{
|
||||
|
|
@ -2157,7 +2142,7 @@ namespace Server.Items
|
|||
// SDI bonus
|
||||
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;
|
||||
}
|
||||
|
|
@ -2319,13 +2304,8 @@ namespace Server.Items
|
|||
attacker.PlaySound(GetMissAttackSound(attacker, defender));
|
||||
defender.PlaySound(GetMissDefendSound(attacker, defender));
|
||||
|
||||
var ability = WeaponAbility.GetCurrentAbility(attacker);
|
||||
|
||||
ability?.OnMiss(attacker, defender);
|
||||
|
||||
var move = SpecialMove.GetCurrentMove(attacker);
|
||||
|
||||
move?.OnMiss(attacker, defender);
|
||||
WeaponAbility.GetCurrentAbility(attacker)?.OnMiss(attacker, defender);
|
||||
SpecialMove.GetCurrentMove(attacker)?.OnMiss(attacker, defender);
|
||||
|
||||
if (defender is IHonorTarget target)
|
||||
{
|
||||
|
|
@ -2417,56 +2397,38 @@ namespace Server.Items
|
|||
{
|
||||
var bonus = VirtualDamageBonus;
|
||||
|
||||
switch (m_Quality)
|
||||
bonus += m_Quality switch
|
||||
{
|
||||
case WeaponQuality.Low:
|
||||
bonus -= 20;
|
||||
break;
|
||||
case WeaponQuality.Exceptional:
|
||||
bonus += 20;
|
||||
break;
|
||||
}
|
||||
WeaponQuality.Low => -20,
|
||||
WeaponQuality.Exceptional => 20,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
switch (m_DamageLevel)
|
||||
return bonus + m_DamageLevel switch
|
||||
{
|
||||
case WeaponDamageLevel.Ruin:
|
||||
bonus += 15;
|
||||
break;
|
||||
case WeaponDamageLevel.Might:
|
||||
bonus += 20;
|
||||
break;
|
||||
case WeaponDamageLevel.Force:
|
||||
bonus += 25;
|
||||
break;
|
||||
case WeaponDamageLevel.Power:
|
||||
bonus += 30;
|
||||
break;
|
||||
case WeaponDamageLevel.Vanq:
|
||||
bonus += 35;
|
||||
break;
|
||||
}
|
||||
|
||||
return bonus;
|
||||
WeaponDamageLevel.Ruin => 15,
|
||||
WeaponDamageLevel.Might => 20,
|
||||
WeaponDamageLevel.Force => 25,
|
||||
WeaponDamageLevel.Power => 30,
|
||||
WeaponDamageLevel.Vanq => 35,
|
||||
_ => bonus
|
||||
};
|
||||
}
|
||||
|
||||
public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills)
|
||||
{
|
||||
if (checkSkills)
|
||||
{
|
||||
attacker.CheckSkill(
|
||||
SkillName.Tactics,
|
||||
0.0,
|
||||
attacker.Skills.Tactics.Cap
|
||||
); // Passively check tactics for gain
|
||||
attacker.CheckSkill(
|
||||
SkillName.Anatomy,
|
||||
0.0,
|
||||
attacker.Skills.Anatomy.Cap
|
||||
); // Passively check Anatomy for gain
|
||||
// Passively check tactics for gain
|
||||
attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap);
|
||||
|
||||
// Passively check Anatomy for gain
|
||||
attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap);
|
||||
|
||||
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)
|
||||
{
|
||||
attacker.CheckSkill(
|
||||
SkillName.Tactics,
|
||||
0.0,
|
||||
attacker.Skills.Tactics.Cap
|
||||
); // Passively check tactics for gain
|
||||
attacker.CheckSkill(
|
||||
SkillName.Anatomy,
|
||||
0.0,
|
||||
attacker.Skills.Anatomy.Cap
|
||||
); // Passively check Anatomy for gain
|
||||
// Passively check tactics for gain
|
||||
attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap);
|
||||
|
||||
// Passively check Anatomy for gain
|
||||
attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap);
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
|
|
@ -2643,6 +2601,11 @@ namespace Server.Items
|
|||
|
||||
public virtual void PlayHurtAnimation(Mobile from)
|
||||
{
|
||||
if (from.Mounted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int action;
|
||||
int frames;
|
||||
|
||||
|
|
@ -2667,12 +2630,10 @@ namespace Server.Items
|
|||
frames = 5;
|
||||
break;
|
||||
}
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (from.Mounted)
|
||||
{
|
||||
return;
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from.Animate(action, frames, 1, true, false, 0);
|
||||
|
|
@ -2695,10 +2656,18 @@ namespace Server.Items
|
|||
switch (Animation)
|
||||
{
|
||||
default:
|
||||
action = Utility.Random(4, 3);
|
||||
break;
|
||||
case WeaponAnimation.ShootBow: return; // 7
|
||||
case WeaponAnimation.ShootXBow: return; // 8
|
||||
{
|
||||
action = Utility.Random(4, 3);
|
||||
break;
|
||||
}
|
||||
case WeaponAnimation.ShootBow:
|
||||
{
|
||||
return; // 7
|
||||
}
|
||||
case WeaponAnimation.ShootXBow:
|
||||
{
|
||||
return; // 8
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -2728,7 +2697,10 @@ namespace Server.Items
|
|||
|
||||
break;
|
||||
}
|
||||
default: return;
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from.Animate(action, 7, 1, true, false, 0);
|
||||
|
|
@ -2739,11 +2711,11 @@ namespace Server.Items
|
|||
public int GetElementalDamageHue()
|
||||
{
|
||||
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 hue = 0;
|
||||
|
||||
// Order is Cold, Energy, Fire, Poison, Physical
|
||||
if (pois >= currentMax)
|
||||
{
|
||||
hue = 1267 + (pois - 50) / 10;
|
||||
|
|
@ -2812,7 +2784,7 @@ namespace Server.Items
|
|||
* formatting show, and remove CLILOCs embedded: more like OSI
|
||||
* 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.
|
||||
*
|
||||
* 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 ) ); */
|
||||
}
|
||||
|
||||
public override bool AllowEquippedCast(Mobile from)
|
||||
{
|
||||
if (base.AllowEquippedCast(from))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool AllowEquippedCast(Mobile from) =>
|
||||
base.AllowEquippedCast(from) || Attributes.SpellChanneling != 0;
|
||||
|
||||
return Attributes.SpellChanneling != 0;
|
||||
}
|
||||
|
||||
public virtual int GetLuckBonus()
|
||||
{
|
||||
var resInfo = CraftResources.GetInfo(m_Resource);
|
||||
|
||||
var attrInfo = resInfo?.AttributeInfo;
|
||||
|
||||
if (attrInfo == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return attrInfo.WeaponLuck;
|
||||
}
|
||||
public virtual int GetLuckBonus() => CraftResources.GetInfo(m_Resource)?.AttributeInfo?.WeaponLuck ?? 0;
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
|
|
@ -3235,17 +3188,25 @@ namespace Server.Items
|
|||
switch (Skill)
|
||||
{
|
||||
case SkillName.Swords:
|
||||
list.Add(1061172);
|
||||
break; // skill required: swordsmanship
|
||||
{
|
||||
list.Add(1061172); // skill required: swordsmanship
|
||||
break;
|
||||
}
|
||||
case SkillName.Macing:
|
||||
list.Add(1061173);
|
||||
break; // skill required: mace fighting
|
||||
{
|
||||
list.Add(1061173); // skill required: mace fighting
|
||||
break;
|
||||
}
|
||||
case SkillName.Fencing:
|
||||
list.Add(1061174);
|
||||
break; // skill required: fencing
|
||||
{
|
||||
list.Add(1061174); // skill required: fencing
|
||||
break;
|
||||
}
|
||||
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)
|
||||
{
|
||||
var sound = attacker.GetAttackSound();
|
||||
|
||||
if (sound == -1)
|
||||
{
|
||||
sound = HitSound;
|
||||
}
|
||||
|
||||
return sound;
|
||||
return sound == -1 ? HitSound : sound;
|
||||
}
|
||||
|
||||
public virtual int GetHitDefendSound(Mobile attacker, Mobile defender) => defender.GetHurtSound();
|
||||
|
|
@ -3518,33 +3473,37 @@ namespace Server.Items
|
|||
var range = Core.ML ? 5 : 10;
|
||||
|
||||
var eable = from.GetMobilesInRange(range);
|
||||
var list = eable.Where(
|
||||
m =>
|
||||
from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m)
|
||||
&& from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m))
|
||||
)
|
||||
.ToList();
|
||||
using var queue = PooledRefQueue<Mobile>.Create();
|
||||
foreach (var m in eable)
|
||||
{
|
||||
if (from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m)
|
||||
&& from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m)))
|
||||
{
|
||||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
if (list.Count == 0)
|
||||
if (queue.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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 damage = GetBaseDamage(from);
|
||||
|
||||
if (scalar <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var damage = GetBaseDamage(from);
|
||||
|
||||
if (scalar < 1.0)
|
||||
{
|
||||
damage *= (11 - from.GetDistanceToSqrt(m)) / 10;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue