fix: trade gate round 4 - "The trade has been cancelled." + retail's
staged-item trading marker - Cancel text: ClientTradeSystem::Handle_Trade__Recv_CloseTrade @0x0056DE30 shows "The trade has been cancelled." UNCONDITIONALLY (every close reason) as 0x1A ClientLocal - the yellow top-center SpewBox line. Wired at the router's onTradeClose beside ApplyClose; the string lives in ClientTextRefusals with its citation. - Staged-item marker: retail's mechanism decoded end-to-end - the UIItem prototype (catalog 0x21000037) authors overlay child 0x10000438 (sprite 0x06001DAE, the green frame + corner trade icon), bound @0x004E18FC and SetVisible(tradeState != 0) @0x004E2420; gmSecureTradeUI::AddItem @0x004CA801 sets ACCWeenieObject::SetTradeState(1) on YOUR staged items. Ported as: UiItemSlot.ShowTradeOverlay + TradeOverlaySprite (drawn over the icon), set on the trade window's self-grid cells; and RuntimeTradeState now borrows the canonical object table and maintains ClientObject.TradeState (1 at stage, 0 at remove/failure/ reset/close/clear) - which also brings the ALREADY-PORTED placement policy's "You cannot move an item while it is being traded" refusal to life (its input field previously had no live producer). Runtime 1,626, App 4,992/3 - green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
ffc73f80bf
commit
be3e617a2b
7 changed files with 119 additions and 6 deletions
|
|
@ -141,6 +141,29 @@ public sealed class PowerbarLayoutProbeTests
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>2026-08-14 trade gate round 4: dump the shared UIItem
|
||||
/// catalog 0x21000037 tree — find the trading-overlay art (retail marks
|
||||
/// staged cells via ACCWeenieObject::SetTradeState @ 0x004CA801; the
|
||||
/// UIItem draw reads it).</summary>
|
||||
[Fact]
|
||||
public void ProbeUiItemCatalog()
|
||||
{
|
||||
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
|
||||
return;
|
||||
|
||||
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
|
||||
?? Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
||||
"Documents",
|
||||
"Asheron's Call");
|
||||
using var dats = new DatCollection(datDir, DatAccessType.Read);
|
||||
var strings = new DatStringResolver(dats);
|
||||
|
||||
ElementInfo? root = LayoutImporter.ImportInfos(dats, 0x21000037u);
|
||||
Assert.NotNull(root);
|
||||
DumpElement(strings, root!, 0);
|
||||
}
|
||||
|
||||
private static ElementInfo? FindById(ElementInfo element, uint id)
|
||||
{
|
||||
if (element.Id == id) return element;
|
||||
|
|
@ -169,10 +192,16 @@ public sealed class PowerbarLayoutProbeTests
|
|||
private static void DumpElement(DatStringResolver strings, ElementInfo e, int depth)
|
||||
{
|
||||
string indent = new(' ', depth * 2);
|
||||
string media = string.Join(
|
||||
" ",
|
||||
e.StateMedia
|
||||
.OrderBy(static pair => pair.Key, StringComparer.Ordinal)
|
||||
.Select(static pair => $"'{pair.Key}'=0x{pair.Value.File:X8}"));
|
||||
Console.WriteLine(
|
||||
$"[pbprobe] {indent}0x{e.Id:X8} type={e.Type} ({e.X},{e.Y} {e.Width}x{e.Height}) "
|
||||
+ $"defaultState=0x{e.DefaultStateId:X8}('{e.DefaultStateName}') states={e.States.Count} "
|
||||
+ $"hjustify={e.HJustify} fontColor={(e.FontColor is { } fc ? fc.ToString() : "none")}");
|
||||
+ $"hjustify={e.HJustify} fontColor={(e.FontColor is { } fc ? fc.ToString() : "none")} "
|
||||
+ $"media[{media}]");
|
||||
foreach (var (stateId, state) in e.States)
|
||||
{
|
||||
string text = "";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue