"""Q21: the FUT data-manager vtable slots that name a club item.

FUN_1800f6c40 (the pack/award tile builder) does:
    if (item+0x4c == 1)         -> ITEM_RARITY / ITEM_LEVEL
    else if (item+0x50 == 9)    -> "IS_KIT_%d" = 1          <-- names subtype 9
    name = mgr->vt[0x490](out, item+0x4c cardtype, item+0x50 subtype, item+0x18)
    if (name empty && item+0x4c == 7)
        name = mgr->vt[0x498](out, item+0x50 subtype, item+0x94 teamid, item+0x20)
where mgr = FUN_18011a830(). Slots 0x490 and 0x498 are therefore the club-item name
resolvers and must switch on the subtype.

Resolve the manager's vtable, then decompile slots 0x490, 0x498, 0xa08, 0xa38, 0xa40.

CONTROL: slot 0xa08 is the one the item deserializer calls to file a parsed item
(FUN_18013fe00 line 825), and slot 0xa40 is the lookup FUN_18011e3c0 uses with a
resourceId. If the resolved vtable's 0xa08/0xa40 are not functions, the vtable
resolution is wrong.
"""
import traceback

try:
    src = dec(0x18011A830)
    print("=== FUN_18011a830 (manager accessor) len=%d ===" % len(src))
    print(src)
    # find the vtable it installs / the object's class
    print()
    print("=== candidate vtables referenced from FUN_18011a830 and its callees ===")
    f = func(0x18011A830)
    cands = set()
    for ad in f.getBody().getAddresses(True):
        ins = listing.getInstructionAt(ad)
        if ins is None:
            continue
        for r in ins.getReferencesFrom():
            t = int(r.getToAddress().getOffset())
            if 0x1801E5000 <= t <= 0x1802891FF:
                cands.add(t)
    for t in sorted(cands):
        try:
            v0, v1 = qword(t), qword(t + 8)
        except Exception:
            continue
        print("  %#x -> %#x %#x  (%s / %s)" %
              (t, v0, v1, fname(v0) if 0x180000000 <= v0 < 0x181000000 else "-",
               fname(v1) if 0x180000000 <= v1 < 0x181000000 else "-"))
except Exception:
    traceback.print_exc()
