## 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
78 lines
2.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|