From 3759971c80f5e8dea161ea37f1a8e45eb6e368ef Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 12 Aug 2026 20:03:17 -0700 Subject: [PATCH] fix: Require BOD combine items to be player-crafted SmallBOD.EndCombine validates an item's type, material and exceptional quality, but never checks that it was actually crafted by a player. Any item matching the request can be turned in, including one bought from an NPC vendor. Where a vendor sells a type a BOD can request, this lets a player fill the deed by buying the items rather than crafting them, and collect the reward gold for the difference. Tailoring is the clearest case because SmallTailorBOD.CreateRandomFor guarantees Material=None and RequireExceptional=false below 70.1 skill, so the rolled deed asks for plain cloth items that tailor vendors stock directly -- e.g. a qty-20 Bandana BOD filled from vendor stock, against a reward of several times the purchase cost. Adds a PlayerConstructed check alongside the existing material and quality checks, following the pattern already used in Engines/Craft/Core/Resmelt.cs for distinguishing crafted from store-bought items. Note on the message: there is no dedicated cliloc for "this item must be crafted", so 1045169 ("The item is not in the request.") is reused. Happy to change it if a better one is known -- flagging it rather than inventing a string. Co-Authored-By: Claude Opus 5 (1M context) --- Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs index 6356780de..7742a9935 100644 --- a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs @@ -136,8 +136,14 @@ public abstract partial class SmallBOD : BaseBOD else { var material = GetMaterial(armor?.Resource ?? clothing?.Resource ?? CraftResource.None); + var playerConstructed = armor?.PlayerConstructed ?? clothing?.PlayerConstructed ?? + weapon?.PlayerConstructed ?? false; - if (Material >= BulkMaterialType.DullCopper && Material <= BulkMaterialType.Valorite && material != Material) + if (!playerConstructed) + { + from.SendLocalizedMessage(1045169); // The item is not in the request. + } + else if (Material >= BulkMaterialType.DullCopper && Material <= BulkMaterialType.Valorite && material != Material) { from.SendLocalizedMessage(1045168); // The item is not made from the requested ore. }