diff --git a/Projects/Server/Items/Container.cs b/Projects/Server/Items/Container.cs index a85909cca..9469fa11f 100644 --- a/Projects/Server/Items/Container.cs +++ b/Projects/Server/Items/Container.cs @@ -1206,11 +1206,14 @@ public partial class Container : Item for (var i = 0; i < types.Length; ++i) { - items[i] = FindItemsByType(types[i], recurse); - - for (var j = 0; j < items[i].Count; ++j) + var itemList = items[i] = new List(); + foreach (var item in FindItems()) { - totals[i] += items[i][j].Amount; + if (types[i].IsInstanceOfType(item)) + { + totals[i] += item.Amount; + itemList.Add(item); + } } if (totals[i] < amounts[i]) diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index b319b65c4..4dd5b13ad 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -4187,19 +4187,15 @@ public class Item : IHued, IComparable, ISpawnable, IObjectPropertyListEnt } } - public virtual void Consume() + public virtual void Consume(int amount = 1) { - Consume(1); - } - - public virtual void Consume(int amount) - { - Amount -= amount; - - if (Amount <= 0) + if (Amount <= amount) { Delete(); + return; } + + Amount -= amount; } public virtual void ReplaceWith(Item newItem) diff --git a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs index 1a7238eb5..f16bbed90 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Collections; using Server.Commands; using Server.Factions; using Server.Items; @@ -453,23 +454,32 @@ namespace Server.Engines.Craft throw new ArgumentOutOfRangeException(nameof(types)); } - // TODO: Optimize allocation var items = new List[types.Length]; var totals = new int[types.Length]; + // First pass, make sure we have enough for (var i = 0; i < types.Length; ++i) { - items[i] = cont.FindItemsByType(types[i]); + var itemList = items[i] = new List(); + var typeList = types[i]; - for (var j = 0; j < items[i].Count; ++j) + // Since we are making our own list, we don't need to use EnumerateItems + foreach (var item in cont.FindItems()) { - if (items[i][j] is not IHasQuantity hq) + if (!item.InTypeList(typeList)) { - totals[i] += items[i][j].Amount; + continue; + } + + if (item is not IHasQuantity hq) + { + totals[i] += item.Amount; + itemList.Add(item); } else if (hq is not BaseBeverage beverage || beverage.Content == RequiredBeverage) { totals[i] += hq.Quantity; + itemList.Add(item); } } @@ -479,6 +489,7 @@ namespace Server.Engines.Craft } } + // Second pass, consume for (var i = 0; i < types.Length; ++i) { var need = amounts[i]; @@ -493,7 +504,7 @@ namespace Server.Engines.Craft if (theirAmount < need) { - item.Delete(); + item.Consume(theirAmount); need -= theirAmount; } else @@ -504,11 +515,6 @@ namespace Server.Engines.Craft } else { - if (hq is BaseBeverage beverage && beverage.Content != RequiredBeverage) - { - continue; - } - var theirAmount = hq.Quantity; if (theirAmount < need) diff --git a/Projects/UOContent/Items/Misc/ClockworkAssembly.cs b/Projects/UOContent/Items/Misc/ClockworkAssembly.cs index 9e3976825..7348b6469 100644 --- a/Projects/UOContent/Items/Misc/ClockworkAssembly.cs +++ b/Projects/UOContent/Items/Misc/ClockworkAssembly.cs @@ -1,3 +1,4 @@ +using System; using ModernUO.Serialization; using Server.Mobiles; @@ -6,6 +7,30 @@ namespace Server.Items; [SerializationGenerator(0, false)] public partial class ClockworkAssembly : Item { + private static Type[] _requiredParts = + { + typeof(PowerCrystal), + typeof(Gears), + typeof(BronzeIngot), + typeof(IronIngot), + }; + + private static int[] _requiredPartsClilocs = + { + 1071945, // You need a power crystal to construct a golem. + 1071946, // You need more gears to construct a golem. + 1071947, // You need more bronze ingots to construct a golem. + 1071948, // You need more iron ingots to construct a golem. + }; + + private static int[] _requiredAmounts = + { + 1, // Power Crystal + 5, // Gears + 50, // Bronze Ingot + 50, // Iron Ingot + }; + [Constructible] public ClockworkAssembly() : base(0x1EA8) { @@ -13,13 +38,14 @@ public partial class ClockworkAssembly : Item Hue = 1102; } - public override string DefaultName => "clockwork assembly"; + public override int LabelNumber => 1073426; // Clockwork Assembly public override void OnDoubleClick(Mobile from) { if (!IsChildOf(from.Backpack)) { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + // The clockwork assembly must be in your backpack to construct a golem. + from.SendLocalizedMessage(1071944); return; } @@ -27,7 +53,7 @@ public partial class ClockworkAssembly : Item if (tinkerSkill < 60.0) { - from.SendMessage("You must have at least 60.0 skill in tinkering to construct a golem."); + from.SendLocalizedMessage(1071943); // You must be a Journeyman or higher Tinker to construct a golem. return; } @@ -37,28 +63,14 @@ public partial class ClockworkAssembly : Item return; } - double scalar; - - if (tinkerSkill >= 100.0) + double scalar = tinkerSkill switch { - scalar = 1.0; - } - else if (tinkerSkill >= 90.0) - { - scalar = 0.9; - } - else if (tinkerSkill >= 80.0) - { - scalar = 0.8; - } - else if (tinkerSkill >= 70.0) - { - scalar = 0.7; - } - else - { - scalar = 0.6; - } + >= 100.0 => 1.0, + >= 90.0 => 0.9, + >= 80.0 => 0.8, + >= 70.0 => 0.7, + _ => 0.6 + }; var pack = from.Backpack; @@ -67,59 +79,22 @@ public partial class ClockworkAssembly : Item return; } - var res = pack.ConsumeTotal( - new[] - { - typeof(PowerCrystal), - typeof(IronIngot), - typeof(BronzeIngot), - typeof(Gears) - }, - new[] - { - 1, - 50, - 50, - 5 - } - ); + var res = pack.ConsumeTotal(_requiredParts, _requiredAmounts); - switch (res) + if (res >= 0) { - case 0: - { - from.SendMessage("You must have a power crystal to construct the golem."); - break; - } - case 1: - { - from.SendMessage("You must have 50 iron ingots to construct the golem."); - break; - } - case 2: - { - from.SendMessage("You must have 50 bronze ingots to construct the golem."); - break; - } - case 3: - { - from.SendMessage("You must have 5 gears to construct the golem."); - break; - } - default: - { - var g = new Golem(true, scalar); + from.SendLocalizedMessage(_requiredPartsClilocs[res]); + return; + } - if (g.SetControlMaster(from)) - { - Delete(); + var g = new Golem(true, scalar); - g.MoveToWorld(from.Location, from.Map); - from.PlaySound(0x241); - } + if (g.SetControlMaster(from)) + { + Delete(); - break; - } + g.MoveToWorld(from.Location, from.Map); + from.PlaySound(0x241); } } }