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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW
This commit is contained in:
funman300
2026-08-05 11:38:47 -07:00
parent 550313362c
commit c41b1514d3
+14 -2
View File
@@ -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())