ModernUO/Projects/UOContent/Engines/Craft/T2A/T2ACraftToolTarget.cs
Kamron Batman ef8057d38e
fix: T2A menus only offer what the chosen resource can make (#2695)
## Summary
The T2A crafting menus offered items the chosen resource couldn't make:

- **Tailoring honours the targeted cloth hue.** The menu was built from all cloth in the pack, but the craft consumes only the targeted hue, so it offered items that then failed on resources. `CanCraftItem` / `FilterEntries` / `AnyCraftableInCategory` now take the hue and count with the same helper the craft uses.
- **Uncut cloth counts in the hued path.** The hue-aware count and consume matched only `Cloth`, so targeting uncut cloth gave an empty menu. The hued path now uses `CraftItem`'s equivalence table like the unhued path. `T2ACraftSystem` reuses that table instead of a narrower copy, which also covers the coloured woods and leathers on later-era shards.
- **T2A tinkering only uses iron ingots.** Coloured ingots are refused with a re-prompt. The menu filter now uses the selected ingot, and Make Last for tinkering always resolves to iron, so a coloured choice left over from the gump flow can't be used.

## Testing
- `dotnet build`: 0 warnings, 0 errors
- New `T2AHuedFilterTests`: only cloth of the targeted hue counts, and uncut cloth of the same hue counts toward the recipe
- No test for the tinkering target and message flow; not yet exercised in game
2026-10-20 23:12:10 -07:00

78 lines
2.8 KiB
C#

using Server.Items;
using Server.Targeting;
namespace Server.Engines.Craft.T2A;
public class T2ACraftToolTarget : Target
{
private readonly BaseTool _tool;
private readonly CraftSystem _system;
public T2ACraftToolTarget(BaseTool tool, CraftSystem system) : base(2, false, TargetFlags.None)
{
_tool = tool;
_system = system;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted == _tool)
{
// Make Last: repeat last crafted item
var context = _system.GetContext(from);
var lastMade = context?.LastMade;
if (lastMade != null)
{
var num = _system.CanCraft(from, _tool, lastMade.ItemType);
if (num > 0)
{
from.SendLocalizedMessage(num);
return;
}
var res = lastMade.UseSubRes2 ? _system.CraftSubRes2 : _system.CraftSubRes;
var resIndex = lastMade.UseSubRes2 ? context.LastResourceIndex2 : context.LastResourceIndex;
var type = resIndex > -1 ? res[resIndex].ItemType : null;
// T2A tinkering has no colored ingots; a stale index from the gump flow must not leak in
if (_system == DefTinkering.CraftSystem)
{
type = typeof(IronIngot);
T2ACraftSystem.SetLastResourceIndex(from, _system, type);
}
// Jewelry requires gem targeting — re-prompt instead of crafting directly
if (typeof(BaseJewel).IsAssignableFrom(lastMade.ItemType))
{
context.PendingGemType = GemType.None;
context.PendingGemCount = 0;
from.SendAsciiMessage("Target the gemstone you wish to use.");
from.Target = new TinkeringMenu.GemSelectTarget(from, _tool, lastMade.ItemType, type);
return;
}
if (context.LastHue >= 0)
{
_system.CreateItem(from, lastMade.ItemType, type, _tool, lastMade, context.LastHue);
}
else
{
_system.CreateItem(from, lastMade.ItemType, type, _tool, lastMade);
}
}
else
{
from.SendAsciiMessage("You have not yet crafted anything.");
T2ACraftSystem.ShowMenu(from, _system, _tool);
}
}
else
{
// Normal flow: pass the targeted object through so resource selection
// can use it directly instead of requiring a second target.
T2ACraftSystem.ShowMenu(from, _system, _tool, targeted as Item);
}
}
}