From c41b1514d34239a68d502d3a7fbadec3cc68d66f Mon Sep 17 00:00:00 2001 From: funman300 Date: Wed, 5 Aug 2026 11:38:47 -0700 Subject: [PATCH] fifa17-recon: consumables are served tradeable, so the untradeable badge clears A player pointed at a green tag under every consumable card. It is ours, not the client's: the deserializer sets a flag from (untradeableCount < count), we set untradeableCount == count, so every stack read as fully untradeable and drew the badge. UNTRADEABLE_COUNT and UNTRADABLE_COUNT are UI state keys in .rdata. In FIFA 17 a pack-opened consumable is normally tradeable, so this was our own data showing through rather than a rendering fault. Now untradeableCount is 0 and the served copy carries untradeable false. FUT_CONSUM_UNTRADEABLE=1 restores the old behaviour. TODO/CONFIRM: the exact badge text was not read, only its source. If the tag survives this change it is a different label and the untradeable theory is wrong. 439 + 414 checks green. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW --- fifa17-recon/tools/utas_server.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fifa17-recon/tools/utas_server.py b/fifa17-recon/tools/utas_server.py index ad081a1..70547ac 100755 --- a/fifa17-recon/tools/utas_server.py +++ b/fifa17-recon/tools/utas_server.py @@ -1190,6 +1190,8 @@ def _club_stat_context(kind): # Default ON: answering the consumables panel with player counts is wrong by # inspection, not a judgement call. Set FUT_CONSUM_STATS=0 to go back. CONSUM_STATS = os.environ.get("FUT_CONSUM_STATS", "1") == "1" +# Serve consumables as TRADEABLE by default; see _consumable_stacks for why. +CONSUM_UNTRADEABLE = os.environ.get("FUT_CONSUM_UNTRADEABLE", "0") == "1" def _consumable_stat_rows(): @@ -1324,10 +1326,20 @@ def _consumable_stacks(items): rid = it.get("resourceId") s = stacks.get(rid) if s is None: - s = stacks[rid] = {"count": 0, "discardValue": 0, "item": it, + # untradeable is forced OFF on the copy we serve. The deserializer sets a + # flag from (untradeableCount < count), so untradeableCount == count means + # "every copy is untradeable" and the card draws the untradeable badge -- + # the green tag a player asked about on 2026-08-05. In FIFA 17 a + # pack-opened consumable is normally tradeable, so the badge was our own + # data showing through, not the client being wrong. FUT_CONSUM_UNTRADEABLE=1 + # restores the old behaviour. + item = dict(it) + if not CONSUM_UNTRADEABLE: + item["untradeable"] = False + s = stacks[rid] = {"count": 0, "discardValue": 0, "item": item, "resourceId": rid, "untradeableCount": 0} s["count"] += 1 - if it.get("untradeable"): + if CONSUM_UNTRADEABLE and it.get("untradeable"): s["untradeableCount"] += 1 return list(stacks.values())