fix: Adds FindItemOnLayer generic (#1223)

This commit is contained in:
Kamron Batman 2022-11-01 00:49:20 -07:00 committed by GitHub
parent 053dbcbad0
commit fd6f4239e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 112 additions and 169 deletions

View file

@ -68,8 +68,7 @@ public struct Point2D
public bool Equals(Point2D other) => m_X == other.m_X && m_Y == other.m_Y; public bool Equals(Point2D other) => m_X == other.m_X && m_Y == other.m_Y;
public bool Equals(IPoint2D other) => public bool Equals(IPoint2D other) => m_X == other?.X && m_Y == other.Y;
m_X == other?.X && m_Y == other.Y;
public override bool Equals(object obj) => obj is Point2D other && Equals(other); public override bool Equals(object obj) => obj is Point2D other && Equals(other);

View file

@ -1568,7 +1568,7 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
return m_BankBox; return m_BankBox;
} }
m_BankBox = FindItemOnLayer(Layer.Bank) as BankBox; m_BankBox = FindItemOnLayer<BankBox>(Layer.Bank);
if (m_BankBox == null) if (m_BankBox == null)
{ {
@ -1586,7 +1586,7 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
{ {
if (m_Backpack?.Deleted != false || m_Backpack.Parent != this) if (m_Backpack?.Deleted != false || m_Backpack.Parent != this)
{ {
m_Backpack = FindItemOnLayer(Layer.Backpack) as Container; m_Backpack = FindItemOnLayer<Container>(Layer.Backpack);
} }
return m_Backpack; return m_Backpack;
@ -7405,12 +7405,15 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
{ {
if (m_BankBox?.Deleted != false || m_BankBox.Parent != this) if (m_BankBox?.Deleted != false || m_BankBox.Parent != this)
{ {
m_BankBox = FindItemOnLayer(Layer.Bank) as BankBox; m_BankBox = FindItemOnLayer<BankBox>(Layer.Bank);
} }
return m_BankBox; return m_BankBox;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T FindItemOnLayer<T>(Layer layer) where T : Item => FindItemOnLayer(layer) as T;
public Item FindItemOnLayer(Layer layer) public Item FindItemOnLayer(Layer layer)
{ {
var eq = Items; var eq = Items;
@ -7420,6 +7423,7 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
{ {
var item = eq[i]; var item = eq[i];
// TODO: We only allow 1 item per layer. It's an implicit contract.
if (!item.Deleted && item.Layer == layer) if (!item.Deleted && item.Layer == layer)
{ {
return item; return item;
@ -7463,15 +7467,8 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
eable.Free(); eable.Free();
} }
public bool PlaceInBackpack(Item item) public bool PlaceInBackpack(Item item) =>
{ !item.Deleted && Backpack?.TryDropItem(this, item, false) == true;
if (item.Deleted)
{
return false;
}
return Backpack?.TryDropItem(this, item, false) == true;
}
public bool AddToBackpack(Item item) public bool AddToBackpack(Item item)
{ {
@ -7504,10 +7501,8 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
from == this || from.AccessLevel > AccessLevel && from.AccessLevel >= AccessLevel.GameMaster; from == this || from.AccessLevel > AccessLevel && from.AccessLevel >= AccessLevel.GameMaster;
public virtual bool CheckTrade( public virtual bool CheckTrade(
Mobile to, Item item, SecureTradeContainer cont, bool message, bool checkItems, Mobile to, Item item, SecureTradeContainer cont, bool message, bool checkItems, int plusItems, int plusWeight
int plusItems, int plusWeight ) => true;
) =>
true;
public virtual bool OpenTrade(Mobile from, Item offer = null) public virtual bool OpenTrade(Mobile from, Item offer = null)
{ {

View file

@ -90,7 +90,7 @@ public static class OutgoingVendorBuyPackets
var writer = new SpanWriter(stackalloc byte[length]); var writer = new SpanWriter(stackalloc byte[length]);
writer.Write((byte)0x74); // Packet ID writer.Write((byte)0x74); // Packet ID
writer.Write((ushort)length); writer.Write((ushort)length);
writer.Write((vendor.FindItemOnLayer(Layer.ShopBuy) as Container)?.Serial ?? Serial.MinusOne); writer.Write(vendor.FindItemOnLayer<Container>(Layer.ShopBuy)?.Serial ?? Serial.MinusOne);
writer.Write((byte)list.Count); writer.Write((byte)list.Count);
for (var i = 0; i < list.Count; ++i) for (var i = 0; i < list.Count; ++i)

View file

@ -717,10 +717,7 @@ namespace Server.Engines.ConPVP
{ {
mob.Resurrect(); mob.Resurrect();
if (mob.FindItemOnLayer(Layer.OuterTorso) is DeathRobe robe) mob.FindItemOnLayer<DeathRobe>(Layer.OuterTorso)?.Delete();
{
robe.Delete();
}
if (cont is Corpse corpse) if (cont is Corpse corpse)
{ {

View file

@ -1016,20 +1016,22 @@ namespace Server.Engines.Craft
return; return;
} }
int checkResHue = 0, checkMaxAmount = 0; var checkResHue = 0;
var checkMaxAmount = 0;
TextDefinition checkMessage = null; TextDefinition checkMessage = null;
var consumeRes = ConsumeRes(
from,
typeRes,
craftSystem,
ref checkResHue,
ref checkMaxAmount,
ConsumeType.None,
ref checkMessage
);
// Not enough resource to craft it // Not enough resource to craft it
if (!(ConsumeRes( if (!(consumeRes && ConsumeAttributes(from, ref checkMessage, false)))
from,
typeRes,
craftSystem,
ref checkResHue,
ref checkMaxAmount,
ConsumeType.None,
ref checkMessage
)
&& ConsumeAttributes(from, ref checkMessage, false)))
{ {
if (tool?.Deleted == false && tool.UsesRemaining > 0) if (tool?.Deleted == false && tool.UsesRemaining > 0)
{ {
@ -1058,9 +1060,18 @@ namespace Server.Engines.Craft
if (CheckSkills(from, typeRes, craftSystem, ref ignored, out var allRequiredSkills)) if (CheckSkills(from, typeRes, craftSystem, ref ignored, out var allRequiredSkills))
{ {
consumeRes = ConsumeRes(
from,
typeRes,
craftSystem,
ref resHue,
ref maxAmount,
ConsumeType.All,
ref message
);
// Not enough resource to craft it // Not enough resource to craft it
if (!(ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, ConsumeType.All, ref message) if (!(consumeRes && ConsumeAttributes(from, ref message, true)))
&& ConsumeAttributes(from, ref message, true)))
{ {
if (tool?.Deleted == false && tool.UsesRemaining > 0) if (tool?.Deleted == false && tool.UsesRemaining > 0)
{ {
@ -1083,13 +1094,16 @@ namespace Server.Engines.Craft
tool.UsesRemaining--; tool.UsesRemaining--;
if (craftSystem is DefBlacksmithy && if (craftSystem is DefBlacksmithy)
from.FindItemOnLayer(Layer.OneHanded) is AncientSmithyHammer hammer && hammer != tool)
{ {
hammer.UsesRemaining--; var hammer = from.FindItemOnLayer<AncientSmithyHammer>(Layer.OneHanded);
if (hammer.UsesRemaining < 1) if (hammer != tool)
{ {
hammer.Delete(); hammer.UsesRemaining--;
if (hammer.UsesRemaining < 1)
{
hammer.Delete();
}
} }
} }

View file

@ -84,9 +84,10 @@ namespace Server.Engines.Craft
return EnhanceResult.BadResource; return EnhanceResult.BadResource;
} }
int resHue = 0, maxAmount = 0; int resHue = 0;
int maxAmount = 0;
if (!craftItem.ConsumeRes( var consumeRes = craftItem.ConsumeRes(
from, from,
resType, resType,
craftSystem, craftSystem,
@ -94,20 +95,19 @@ namespace Server.Engines.Craft
ref maxAmount, ref maxAmount,
ConsumeType.None, ConsumeType.None,
ref resMessage ref resMessage
)) );
if (!consumeRes)
{ {
return EnhanceResult.NoResources; return EnhanceResult.NoResources;
} }
if (craftSystem is DefBlacksmithy) if (craftSystem is DefBlacksmithy)
{ {
if (from.FindItemOnLayer(Layer.OneHanded) is AncientSmithyHammer hammer) var hammer = from.FindItemOnLayer<AncientSmithyHammer>(Layer.OneHanded);
if (hammer != null && --hammer.UsesRemaining < 1)
{ {
hammer.UsesRemaining--; hammer.Delete();
if (hammer.UsesRemaining < 1)
{
hammer.Delete();
}
} }
} }

View file

@ -62,8 +62,7 @@ namespace Server.Engines.Quests.Hag
{ {
PlaySound(Utility.RandomBool() ? 0x42E : 0x43F); PlaySound(Utility.RandomBool() ? 0x42E : 0x43F);
var hat = player.FindItemOnLayer(Layer.Helm); var tricorne = player.FindItemOnLayer<TricorneHat>(Layer.Helm) != null;
var tricorne = hat is TricorneHat;
if (tricorne && player.BAC >= 20) if (tricorne && player.BAC >= 20)
{ {

View file

@ -530,20 +530,13 @@ namespace Server.Items
return list; return list;
} }
public static Spellbook FindEquippedSpellbook(Mobile from) => from.FindItemOnLayer(Layer.OneHanded) as Spellbook; public static Spellbook FindEquippedSpellbook(Mobile from) => from.FindItemOnLayer<Spellbook>(Layer.OneHanded);
public static bool ValidateSpellbook(Spellbook book, int spellID, SpellbookType type) => public static bool ValidateSpellbook(Spellbook book, int spellID, SpellbookType type) =>
book.SpellbookType == type && (spellID == -1 || book.HasSpell(spellID)); book.SpellbookType == type && (spellID == -1 || book.HasSpell(spellID));
public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted) public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted) =>
{ Ethic.CheckTrade(from, to, newOwner, this) && base.AllowSecureTrade(from, to, newOwner, accepted);
if (!Ethic.CheckTrade(from, to, newOwner, this))
{
return false;
}
return base.AllowSecureTrade(from, to, newOwner, accepted);
}
public override bool CanEquip(Mobile from) public override bool CanEquip(Mobile from)
{ {

View file

@ -1373,7 +1373,7 @@ namespace Server.Items
return false; return false;
} }
var shield = defender.FindItemOnLayer(Layer.TwoHanded) as BaseShield; var shield = defender.FindItemOnLayer<BaseShield>(Layer.TwoHanded);
var parry = defender.Skills.Parry.Value; var parry = defender.Skills.Parry.Value;
var bushidoNonRacial = defender.Skills.Bushido.NonRacialValue; var bushidoNonRacial = defender.Skills.Bushido.NonRacialValue;
@ -1489,7 +1489,7 @@ namespace Server.Items
defender.Stam += Utility.RandomMinMax(1, (int)(bushido / 5)); defender.Stam += Utility.RandomMinMax(1, (int)(bushido / 5));
} }
var shield = defender.FindItemOnLayer(Layer.TwoHanded) as BaseShield; var shield = defender.FindItemOnLayer<BaseShield>(Layer.TwoHanded);
shield?.OnHit(this, damage); shield?.OnHit(this, damage);
} }
@ -1785,9 +1785,11 @@ namespace Server.Items
out var direct out var direct
); );
if (Core.ML && this is BaseRanged && attacker.FindItemOnLayer(Layer.Cloak) is BaseQuiver quiver) if (Core.ML && this is BaseRanged)
{ {
quiver.AlterBowDamage(ref phys, ref fire, ref cold, ref pois, ref nrgy, ref chaos, ref direct); attacker
.FindItemOnLayer<BaseQuiver>(Layer.Cloak)
?.AlterBowDamage(ref phys, ref fire, ref cold, ref pois, ref nrgy, ref chaos, ref direct);
} }
if (Consecrated) if (Consecrated)

View file

@ -171,7 +171,7 @@ namespace Server.Items
{ {
if (attacker.Player) if (attacker.Player)
{ {
var quiver = attacker.FindItemOnLayer(Layer.Cloak) as BaseQuiver; var quiver = attacker.FindItemOnLayer<BaseQuiver>(Layer.Cloak);
var pack = attacker.Backpack; var pack = attacker.Backpack;
if (quiver == null || Utility.Random(100) >= quiver.LowerAmmoCost) if (quiver == null || Utility.Random(100) >= quiver.LowerAmmoCost)

View file

@ -109,7 +109,7 @@ namespace Server
if (archer && from != null) if (archer && from != null)
{ {
quiver = from.FindItemOnLayer(Layer.Cloak) as BaseQuiver; quiver = from.FindItemOnLayer<BaseQuiver>(Layer.Cloak);
} }
int totalDamage; int totalDamage;

View file

@ -67,23 +67,14 @@ namespace Server.Mobiles
AddLoot(LootPack.LowScrolls); AddLoot(LootPack.LowScrolls);
} }
public override bool IsEnemy(Mobile m) public override bool IsEnemy(Mobile m) =>
{ (!m.Player || m.FindItemOnLayer<OrcishKinMask>(Layer.Helm) == null) && base.IsEnemy(m);
if (m.Player && m.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
{
return false;
}
return base.IsEnemy(m);
}
public override void AggressiveAction(Mobile aggressor, bool criminal) public override void AggressiveAction(Mobile aggressor, bool criminal)
{ {
base.AggressiveAction(aggressor, criminal); base.AggressiveAction(aggressor, criminal);
var item = aggressor.FindItemOnLayer(Layer.Helm); if (aggressor.FindItemOnLayer(Layer.Helm) is OrcishKinMask item)
if (item is OrcishKinMask)
{ {
AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0); AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0);
item.Delete(); item.Delete();

View file

@ -85,23 +85,14 @@ namespace Server.Mobiles
AddLoot(LootPack.Meager); AddLoot(LootPack.Meager);
} }
public override bool IsEnemy(Mobile m) public override bool IsEnemy(Mobile m) =>
{ (!m.Player || m.FindItemOnLayer<OrcishKinMask>(Layer.Helm) == null) && base.IsEnemy(m);
if (m.Player && m.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
{
return false;
}
return base.IsEnemy(m);
}
public override void AggressiveAction(Mobile aggressor, bool criminal) public override void AggressiveAction(Mobile aggressor, bool criminal)
{ {
base.AggressiveAction(aggressor, criminal); base.AggressiveAction(aggressor, criminal);
var item = aggressor.FindItemOnLayer(Layer.Helm); if (aggressor.FindItemOnLayer(Layer.Helm) is OrcishKinMask item)
if (item is OrcishKinMask)
{ {
AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0); AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0);
item.Delete(); item.Delete();

View file

@ -73,23 +73,14 @@ namespace Server.Mobiles
AddLoot(LootPack.Meager); AddLoot(LootPack.Meager);
} }
public override bool IsEnemy(Mobile m) public override bool IsEnemy(Mobile m) =>
{ (!m.Player || m.FindItemOnLayer<OrcishKinMask>(Layer.Helm) == null) && base.IsEnemy(m);
if (m.Player && m.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
{
return false;
}
return base.IsEnemy(m);
}
public override void AggressiveAction(Mobile aggressor, bool criminal) public override void AggressiveAction(Mobile aggressor, bool criminal)
{ {
base.AggressiveAction(aggressor, criminal); base.AggressiveAction(aggressor, criminal);
var item = aggressor.FindItemOnLayer(Layer.Helm); if (aggressor.FindItemOnLayer(Layer.Helm) is OrcishKinMask item)
if (item is OrcishKinMask)
{ {
AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0); AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0);
item.Delete(); item.Delete();

View file

@ -74,23 +74,14 @@ namespace Server.Mobiles
AddLoot(LootPack.Rich); AddLoot(LootPack.Rich);
} }
public override bool IsEnemy(Mobile m) public override bool IsEnemy(Mobile m) =>
{ (!m.Player || m.FindItemOnLayer<OrcishKinMask>(Layer.Helm) == null) && base.IsEnemy(m);
if (m.Player && m.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
{
return false;
}
return base.IsEnemy(m);
}
public override void AggressiveAction(Mobile aggressor, bool criminal) public override void AggressiveAction(Mobile aggressor, bool criminal)
{ {
base.AggressiveAction(aggressor, criminal); base.AggressiveAction(aggressor, criminal);
var item = aggressor.FindItemOnLayer(Layer.Helm); if (aggressor.FindItemOnLayer(Layer.Helm) is OrcishKinMask item)
if (item is OrcishKinMask)
{ {
AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0); AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0);
item.Delete(); item.Delete();

View file

@ -85,23 +85,14 @@ namespace Server.Mobiles
AddLoot(LootPack.Meager, 2); AddLoot(LootPack.Meager, 2);
} }
public override bool IsEnemy(Mobile m) public override bool IsEnemy(Mobile m) =>
{ (!m.Player || m.FindItemOnLayer<OrcishKinMask>(Layer.Helm) == null) && base.IsEnemy(m);
if (m.Player && m.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
{
return false;
}
return base.IsEnemy(m);
}
public override void AggressiveAction(Mobile aggressor, bool criminal) public override void AggressiveAction(Mobile aggressor, bool criminal)
{ {
base.AggressiveAction(aggressor, criminal); base.AggressiveAction(aggressor, criminal);
var item = aggressor.FindItemOnLayer(Layer.Helm); if (aggressor.FindItemOnLayer(Layer.Helm) is OrcishKinMask item)
if (item is OrcishKinMask)
{ {
AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0); AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0);
item.Delete(); item.Delete();

View file

@ -81,23 +81,14 @@ namespace Server.Mobiles
// TODO: evil orc helm // TODO: evil orc helm
} }
public override bool IsEnemy(Mobile m) public override bool IsEnemy(Mobile m) =>
{ (!m.Player || m.FindItemOnLayer<OrcishKinMask>(Layer.Helm) == null) && base.IsEnemy(m);
if (m.Player && m.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
{
return false;
}
return base.IsEnemy(m);
}
public override void AggressiveAction(Mobile aggressor, bool criminal) public override void AggressiveAction(Mobile aggressor, bool criminal)
{ {
base.AggressiveAction(aggressor, criminal); base.AggressiveAction(aggressor, criminal);
var item = aggressor.FindItemOnLayer(Layer.Helm); if (aggressor.FindItemOnLayer(Layer.Helm) is OrcishKinMask item)
if (item is OrcishKinMask)
{ {
AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0); AOS.Damage(aggressor, 50, 0, 100, 0, 0, 0);
item.Delete(); item.Delete();

View file

@ -181,7 +181,7 @@ namespace Server.Mobiles
return; return;
} }
if (m.FindItemOnLayer(Layer.TwoHanded) is Torch { Burning: true }) if (m.FindItemOnLayer<Torch>(Layer.TwoHanded)?.Burning == true)
{ {
StopEffect(m, true); StopEffect(m, true);
return; return;

View file

@ -33,12 +33,24 @@ namespace Server.Spells.Bushido
return false; return false;
} }
if (caster.FindItemOnLayer(Layer.OneHanded) is not BaseWeapon weap) var weap =
{ caster.FindItemOnLayer<BaseWeapon>(Layer.OneHanded) ??
weap = caster.FindItemOnLayer(Layer.TwoHanded) as BaseWeapon; caster.FindItemOnLayer<BaseWeapon>(Layer.TwoHanded);
}
if (weap != null) if (weap == null)
{
if (caster.FindItemOnLayer(Layer.TwoHanded) is not BaseShield)
{
if (messages)
{
// You must have a weapon or a shield equipped to use this ability!
caster.SendLocalizedMessage(1062944);
}
return false;
}
}
else
{ {
if (Core.ML && caster.Skills[weap.Skill].Base < 50) if (Core.ML && caster.Skills[weap.Skill].Base < 50)
{ {
@ -51,15 +63,6 @@ namespace Server.Spells.Bushido
return false; return false;
} }
} }
else if (caster.FindItemOnLayer(Layer.TwoHanded) is not BaseShield)
{
if (messages)
{
caster.SendLocalizedMessage(1062944); // You must have a weapon or a shield equipped to use this ability!
}
return false;
}
if (!caster.CanBeginAction<Evasion>()) if (!caster.CanBeginAction<Evasion>())
{ {
@ -76,10 +79,9 @@ namespace Server.Spells.Bushido
public static bool CheckSpellEvasion(Mobile defender) public static bool CheckSpellEvasion(Mobile defender)
{ {
if (defender.FindItemOnLayer(Layer.OneHanded) is not BaseWeapon weap) var weap =
{ defender.FindItemOnLayer<BaseWeapon>(Layer.OneHanded) ??
weap = defender.FindItemOnLayer(Layer.TwoHanded) as BaseWeapon; defender.FindItemOnLayer<BaseWeapon>(Layer.TwoHanded);
}
if (Core.ML) if (Core.ML)
{ {

View file

@ -12,22 +12,18 @@ namespace Server.Spells.Ninjitsu
public override bool Validate(Mobile from) public override bool Validate(Mobile from)
{ {
if (from.FindItemOnLayer(Layer.TwoHanded) is BaseShield) var twoHanded = from.FindItemOnLayer(Layer.TwoHanded);
if (twoHanded is BaseShield)
{ {
from.SendLocalizedMessage(1063096); // You cannot use this ability while holding a shield. from.SendLocalizedMessage(1063096); // You cannot use this ability while holding a shield.
return false; return false;
} }
Item handOne = from.FindItemOnLayer(Layer.OneHanded) as BaseWeapon; var meleeWeapon =
twoHanded is BaseWeapon and not BaseRanged ||
from.FindItemOnLayer(Layer.OneHanded) is BaseWeapon and not BaseRanged;
if (handOne != null && handOne is not BaseRanged) if (meleeWeapon)
{
return base.Validate(from);
}
Item handTwo = from.FindItemOnLayer(Layer.TwoHanded) as BaseWeapon;
if (handTwo != null && handTwo is not BaseRanged)
{ {
return base.Validate(from); return base.Validate(from);
} }