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
This commit is contained in:
parent
54c0040ac8
commit
ef8057d38e
6 changed files with 206 additions and 56 deletions
|
|
@ -0,0 +1,92 @@
|
|||
using Server;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Engines.Craft.T2A;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class T2AHuedFilterTests
|
||||
{
|
||||
private static PlayerMobile CreatePlayer(Point3D location)
|
||||
{
|
||||
var m = new PlayerMobile(World.NewMobile);
|
||||
m.DefaultMobileInit();
|
||||
m.MoveToWorld(location, Map.Felucca);
|
||||
m.AddItem(new Backpack());
|
||||
return m;
|
||||
}
|
||||
|
||||
private static CraftItem MakeRecipe()
|
||||
{
|
||||
var item = new CraftItem(typeof(Shirt), "shirt", "shirt");
|
||||
item.AddRes(typeof(Cloth), "cloth", 8, "You do not have enough cloth.");
|
||||
item.AddSkill(SkillName.Tailoring, 0.0, 100.0);
|
||||
return item;
|
||||
}
|
||||
|
||||
private static CraftSystem GetTailoringSystem()
|
||||
{
|
||||
if (DefTailoring.CraftSystem == null)
|
||||
{
|
||||
DefTailoring.Initialize();
|
||||
}
|
||||
|
||||
return DefTailoring.CraftSystem;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanCraftItem_WithHue_CountsOnlyMatchingHueCloth()
|
||||
{
|
||||
var player = CreatePlayer(new Point3D(4140, 500, 0));
|
||||
|
||||
try
|
||||
{
|
||||
var pack = player.Backpack;
|
||||
pack.AddItem(new Cloth(5) { Hue = 0x21 });
|
||||
pack.AddItem(new Cloth(5) { Hue = 0x30 });
|
||||
|
||||
var system = GetTailoringSystem();
|
||||
var recipe = MakeRecipe();
|
||||
|
||||
// 10 cloth total, but no single hue reaches the 8 the recipe needs
|
||||
Assert.True(T2ACraftSystem.CanCraftItem(player, recipe, system));
|
||||
Assert.False(T2ACraftSystem.CanCraftItem(player, recipe, system, null, 0x21));
|
||||
Assert.False(T2ACraftSystem.CanCraftItem(player, recipe, system, null, 0x30));
|
||||
|
||||
pack.AddItem(new Cloth(3) { Hue = 0x21 });
|
||||
Assert.True(T2ACraftSystem.CanCraftItem(player, recipe, system, null, 0x21));
|
||||
Assert.False(T2ACraftSystem.CanCraftItem(player, recipe, system, null, 0x30));
|
||||
}
|
||||
finally
|
||||
{
|
||||
player.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanCraftItem_WithHue_CountsSameHueUncutCloth()
|
||||
{
|
||||
var player = CreatePlayer(new Point3D(4140, 500, 0));
|
||||
|
||||
try
|
||||
{
|
||||
var pack = player.Backpack;
|
||||
pack.AddItem(new Cloth(5) { Hue = 0x21 });
|
||||
pack.AddItem(new UncutCloth(3) { Hue = 0x21 });
|
||||
pack.AddItem(new UncutCloth(5) { Hue = 0x30 });
|
||||
|
||||
var system = GetTailoringSystem();
|
||||
var recipe = MakeRecipe();
|
||||
|
||||
Assert.True(T2ACraftSystem.CanCraftItem(player, recipe, system, null, 0x21));
|
||||
Assert.False(T2ACraftSystem.CanCraftItem(player, recipe, system, null, 0x30));
|
||||
}
|
||||
finally
|
||||
{
|
||||
player.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue