"""DIMENSION 1 / query 4: the resolver and the store screen. ESTABLISHED: FUN_1800147f0(model, groupOrdinal, out, incInvisible, checkPlat) is "give me the contents of group N". groupOrdinal 0 means "give me the list of group tiles" (FUN_180014610). Otherwise it calls FUN_180014420(model, groupOrdinal) and copies that group's pack vector at +0x40. FUN_180014580 / FUN_180014df0 map a UI category enum to the HARDCODED lowercase group-name strings mypacks / points / bronze / silver / gold / special, look the group up by name, and return group+0x00 (the ordinal). HYPOTHESIS H-CLAMP: FUN_180014420 does not handle "ordinal not found" by failing; it falls through to the last group. With displayGroupAssetId 1/5/6 and only 3 groups, 5 and 6 both resolve to the last group (Premium), which is exactly the observed Bronze-ok / Gold-wrong / Premium-ok pattern. CONTROL: FUN_18002c8b0 is decompiled in the same batch as a same-shape predicate; and every "field X is not read" claim is backed by printing the whole function and its length, never by grep. """ import traceback OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store/q4_out.txt" buf = [] def P(*a): s = " ".join(str(x) for x in a) buf.append(s) print(s) def C(a, label, show_callers=True): P("=" * 78) P(label, hex(a)) P("=" * 78) s = dec(a) P("len(src) =", len(s)) P(s) if show_callers: P("--- callers ---") for ent, nm in callers(a): P(" %-30s %s" % (nm, hex(ent))) try: C(0x180014420, "*** FUN_180014420 group lookup by ordinal ***") C(0x18002c8b0, "CONTROL predicate FUN_18002c8b0") P("=" * 78) P("callers of the resolver FUN_1800147f0") P("=" * 78) for ent, nm in callers(0x1800147f0): P(" %-30s %s" % (nm, hex(ent))) for a in (0x18007dab0, 0x18007df60, 0x18007e430, 0x18007e5e0): C(a, "store screen FUN_%x" % a) except Exception: P(traceback.format_exc()) open(OUT, "w").write("\n".join(buf)) print("WROTE", OUT)