fifa17 store: render cover art on My Packs reward tiles
A reward pack advertised its own id (70-75) as assetId, which is not a client art
asset, so its My Packs tile rendered blank. Reward tiles now carry their tier
store pack as the cover asset (bronze->1, silver->3, gold->5) while `id` stays the
pack own id (the open packId / SERVER_ID); the sentinel keeps its own id so it
stays an inert placeholder.
LIVE-MAPPED on the retail client 2026-08-18 across all three store tabs and two
reward tiles, which corrected an earlier wrong assumption:
* assetId only gates whether art renders AT ALL (unknown id -> blank tile).
* WHICH art is drawn comes from packType + packContentInfo.rareQuantity, NOT
assetId: BRONZE+1rare -> bronze card, BRONZE+3 -> silver, SILVER+1 -> gold,
SILVER+3 -> silver trio, GOLD+1 -> blue special, GOLD+3 -> red inform.
Remapping assetId 5->3 and 3->2 left both frames unchanged and only rotated
the featured player, which proves art is content-driven.
So a reward tile now shows the same cover as the equivalent purchasable pack (a
gold reward shows the blue-special art the 5000-coin Gold Pack shows - EA art
advertises an aspirational card rather than the tier colour). Regression test
reward_tiles_carry_a_renderable_cover_asset added; pack70 golden regenerated.
This commit is contained in:
@@ -170,8 +170,30 @@ pub fn pack_body(p: &PackDef, idx: u64, owned: bool) -> Value {
|
|||||||
_ => 1,
|
_ => 1,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// My Packs cover art. LIVE-MAPPED on the retail client 2026-08-18 across all
|
||||||
|
// three store tabs and two reward tiles:
|
||||||
|
// * `assetId` only gates whether art renders AT ALL. A reward pack's own id
|
||||||
|
// (70-75) is not a known client asset, so its tile renders BLANK; any valid
|
||||||
|
// catalogue asset (1-6) makes art appear.
|
||||||
|
// * WHICH art is drawn comes from `packType` + `packContentInfo.rareQuantity`,
|
||||||
|
// not from `assetId`: BRONZE+1rare -> bronze card, BRONZE+3 -> silver,
|
||||||
|
// SILVER+1 -> gold, SILVER+3 -> silver trio, GOLD+1 -> blue special,
|
||||||
|
// GOLD+3 -> red inform. (Remapping assetId 5->3 and 3->2 left both frames
|
||||||
|
// unchanged and only rotated the featured player, which proves this.)
|
||||||
|
// So a reward tile automatically shows the same art as the equivalent
|
||||||
|
// purchasable pack; we only need a valid asset, and we use the tier's own store
|
||||||
|
// pack for clarity. `id` stays the pack's own id (the open packId / SERVER_ID).
|
||||||
|
let art_asset: u64 = if owned {
|
||||||
|
match p.category {
|
||||||
|
"gold" => 5,
|
||||||
|
"silver" => 3,
|
||||||
|
_ => 1,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.id
|
||||||
|
};
|
||||||
let mut body = json!({
|
let mut body = json!({
|
||||||
"assetId": p.id,
|
"assetId": art_asset,
|
||||||
"id": p.id,
|
"id": p.id,
|
||||||
"packType": pack_type,
|
"packType": pack_type,
|
||||||
"description": p.name,
|
"description": p.name,
|
||||||
@@ -249,6 +271,9 @@ pub fn sentinel_body(idx: u64) -> Value {
|
|||||||
// The sentinel must stay non-openable (it is only a resolve-without-crash shim
|
// The sentinel must stay non-openable (it is only a resolve-without-crash shim
|
||||||
// for an empty My Packs), so it keeps no purchase path.
|
// for an empty My Packs), so it keeps no purchase path.
|
||||||
obj.remove("currencies");
|
obj.remove("currencies");
|
||||||
|
// Keep the sentinel's own id as its asset: it must render as an inert blank
|
||||||
|
// placeholder, never borrow a real pack's cover.
|
||||||
|
obj.insert("assetId".into(), json!(SENTINEL_PACK_ID));
|
||||||
body
|
body
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,6 +371,28 @@ mod tests {
|
|||||||
assert_eq!(owned_pack_id_for_definition("mystery_pack"), None);
|
assert_eq!(owned_pack_id_for_definition("mystery_pack"), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reward_tiles_carry_a_renderable_cover_asset() {
|
||||||
|
// A reward pack's own id is not a client art asset, so its My Packs tile
|
||||||
|
// renders blank. Each reward tile must therefore carry a valid catalogue
|
||||||
|
// assetId (its tier's store pack) while `id` stays the open packId.
|
||||||
|
for (reward_id, want_asset) in [(71, 1), (72, 3), (73, 5), (74, 5), (75, 5)] {
|
||||||
|
let pack = pack_by_id(reward_id).expect("reward pack in catalogue");
|
||||||
|
let tile = pack_body(pack, 1, true);
|
||||||
|
assert_eq!(tile["id"], reward_id, "open packId stays the pack's own id");
|
||||||
|
assert_eq!(
|
||||||
|
tile["assetId"], want_asset,
|
||||||
|
"reward tile borrows its tier's store-pack cover asset"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
pack_by_id(tile["assetId"].as_u64().unwrap()).is_some_and(|p| !p.owned_only),
|
||||||
|
"the cover asset must be a real purchasable catalogue pack"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// The sentinel must NOT borrow a real cover — it stays an inert placeholder.
|
||||||
|
assert_eq!(sentinel_body(1)["assetId"], SENTINEL_PACK_ID);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn symbolic_reward_pack_renders_as_openable_my_packs_tile() {
|
fn symbolic_reward_pack_renders_as_openable_my_packs_tile() {
|
||||||
// A granted silver reward pack (resolved to id 72) must appear as an owned
|
// A granted silver reward pack (resolved to id 72) must appear as an owned
|
||||||
|
|||||||
@@ -199,7 +199,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"assetId": 70,
|
"assetId": 5,
|
||||||
"id": 70,
|
"id": 70,
|
||||||
"packType": "GOLD",
|
"packType": "GOLD",
|
||||||
"description": "Reward Gold Pack",
|
"description": "Reward Gold Pack",
|
||||||
|
|||||||
Reference in New Issue
Block a user