"""Q: which struct offsets do the two UI getters read?

FUN_1800eb850 pushes:
    "DISCARD_CREDITS"            <- FUN_1801a8620(handle)
    "CALCULATED_DISCARD_CREDITS" <- FUN_1801a8090(handle)
    "CARD_LEVEL"                 <- FUN_1801a80c0(handle)
    "CARD_RARITY"                <- FUN_1801a8880 || FUN_1801a88c0

H1 predicts FUN_1801a8620 reads +0x38 and FUN_1801a8090 reads +0x3c, i.e. the
wire value and the client's own computation are exposed to the UI as two
SEPARATE named properties with no native fallback between them.

BONUS CONTROL, and it is a strong one: the live probe showed item+0x54 holding
1/2/3 exactly tracking rating (3 if >=75, 2 if >=65, else 1) on all 22 resident
records, which contradicts the existing field map's "itemType 3=player 2=staff".
If FUN_1801a80c0 ("CARD_LEVEL") reads +0x54, that independently settles it as
the fcc_discardcoins `level`.

Also print the callers of FUN_1800eb850 to name the screen.
"""
import traceback

OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/cards/q7_out.txt"

TARGETS = [0x1801A8620, 0x1801A8090, 0x1801A80C0, 0x1801A8880, 0x1801A88C0,
           0x1801A8850, 0x1801A8810, 0x1801A7140, 0x1801A78F0]

try:
    lines = []
    def P(*a):
        lines.append(" ".join(str(x) for x in a))

    for t in TARGETS:
        f = func(t)
        if f is None:
            P("%#x NO FUNCTION" % t)
            continue
        b = f.getBody()
        lo, hi = int(b.getMinAddress().getOffset()), int(b.getMaxAddress().getOffset())
        P("=" * 92)
        P("FUN_%x  body [%#x..%#x] size=%d" % (t, lo, hi, int(b.getNumAddresses())))
        P("--- disassembly (full) ---")
        p = lo
        while p <= hi:
            ins = listing.getInstructionAt(addr(p))
            if ins is None:
                P("  %#x  <none>" % p)
                p += 1
                continue
            P("  %#x  %s" % (p, ins))
            p += ins.getLength()
        s = dec(t)
        P("--- decompile, len=%d ---" % len(s))
        P(s)
        P("")

    P("=" * 92)
    P("=== CALLERS OF FUN_1800eb850 ===")
    for frm, typ, fn, ent in xrefs_to(0x1800EB850):
        P("   %#x %-12s %s @ %#x" % (frm, typ, fn, ent))
        if ent:
            for f2, t2, n2, e2 in xrefs_to(ent):
                P("        <- %#x %s @ %#x" % (f2, n2, e2))

    with open(OUT, "w") as fh:
        fh.write("\n".join(lines))
    print("wrote %s (%d lines)" % (OUT, len(lines)))
except Exception:
    traceback.print_exc()
