fix(fifa17): carry observed rareflag so special cards render as specials
shape_item hardcoded rareflag=1, so all 1949 cards shaped as basic rare gold regardless of type; informs/specials lost their card art. The dev fixture is base-only, so this was invisible until the real profile (10 distinct rareflag values) exposed it on .105. rareflag is definition-level FIFA identity metadata OBSERVED from the profile (the raw wire integer, never a guessed marketing label), so it lives in the FIFA catalog like asset_id/version, not in generic Core: - ObservedDefinition.rareflag + emitted into the production catalog entry. - Fifa17CardCatalog RawCard/Fifa17CardIdentity gain rareflag (default 1 when a base-only catalog omits it, preserving prior wire behaviour). - Fifa17Identity.rareflag; host resolver populates it from the catalog. - shape_item emits id.rareflag instead of a hardcoded 1. Verified on the real staged /club: wire rareflag distribution == source exactly (0 per-item mismatches across 1949; e.g. rareflag 3 x591, 24 x302, 21 x256). adapter 111 + host 24 + importer 25 tests green; clippy -D clean. rareflag lives in the host catalog, not Core, so no re-import was needed.
This commit is contained in:
@@ -27,6 +27,9 @@ pub struct Fifa17CardIdentity {
|
|||||||
pub asset_id: u32,
|
pub asset_id: u32,
|
||||||
pub version: u8,
|
pub version: u8,
|
||||||
pub resource_id: u32,
|
pub resource_id: u32,
|
||||||
|
/// FIFA wire `rareflag` (rare/special card TYPE). Carried so specials render
|
||||||
|
/// as specials; observed metadata, not a guessed label.
|
||||||
|
pub rareflag: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The FIFA 17 numeric namespace policy for owned-item wire ids.
|
/// The FIFA 17 numeric namespace policy for owned-item wire ids.
|
||||||
@@ -108,6 +111,14 @@ struct RawCard {
|
|||||||
asset_id: u32,
|
asset_id: u32,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
version: u8,
|
version: u8,
|
||||||
|
/// Absent in a base-only catalog → default 1 (rare), preserving prior wire
|
||||||
|
/// behaviour; the production catalog carries the observed value.
|
||||||
|
#[serde(default = "default_rareflag")]
|
||||||
|
rareflag: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_rareflag() -> i64 {
|
||||||
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A loaded, validated FIFA 17 card-definition identity catalog.
|
/// A loaded, validated FIFA 17 card-definition identity catalog.
|
||||||
@@ -153,6 +164,7 @@ impl Fifa17CardCatalog {
|
|||||||
asset_id: rc.asset_id,
|
asset_id: rc.asset_id,
|
||||||
version: rc.version,
|
version: rc.version,
|
||||||
resource_id,
|
resource_id,
|
||||||
|
rareflag: rc.rareflag,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ mod tests {
|
|||||||
item_id: 100000001,
|
item_id: 100000001,
|
||||||
asset_id: 20801,
|
asset_id: 20801,
|
||||||
resource_id: 20801,
|
resource_id: 20801,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
)]));
|
)]));
|
||||||
let items = vec![item(
|
let items = vec![item(
|
||||||
@@ -157,6 +158,7 @@ mod tests {
|
|||||||
item_id: 100000002,
|
item_id: 100000002,
|
||||||
asset_id: 158023,
|
asset_id: 158023,
|
||||||
resource_id: 158023,
|
resource_id: 158023,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
)]));
|
)]));
|
||||||
// Synthetic club "Northgate United" has no FIFA team id.
|
// Synthetic club "Northgate United" has no FIFA team id.
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ pub struct Fifa17Identity {
|
|||||||
/// `resourceId`/`definitionId`, kept DISTINCT from `asset_id` so a versioned
|
/// `resourceId`/`definitionId`, kept DISTINCT from `asset_id` so a versioned
|
||||||
/// (special) card never collapses onto its base on the wire.
|
/// (special) card never collapses onto its base on the wire.
|
||||||
pub resource_id: u32,
|
pub resource_id: u32,
|
||||||
|
/// FIFA wire `rareflag` — the card's rare/special TYPE (e.g. 3=inform,
|
||||||
|
/// 21..=24 = special programmes). Drives the client's special-card art;
|
||||||
|
/// carried from the catalog, never hardcoded, so specials render as specials.
|
||||||
|
pub rareflag: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Supplies the FIFA numeric identity for a Core item. Returning `None` means
|
/// Supplies the FIFA numeric identity for a Core item. Returning `None` means
|
||||||
@@ -119,7 +123,7 @@ pub fn shape_item(
|
|||||||
"definitionId": id.resource_id,
|
"definitionId": id.resource_id,
|
||||||
"cardsubtypeid": 0,
|
"cardsubtypeid": 0,
|
||||||
"itemType": "player",
|
"itemType": "player",
|
||||||
"rareflag": 1,
|
"rareflag": id.rareflag,
|
||||||
"rating": item.rating,
|
"rating": item.rating,
|
||||||
"preferredPosition": item.position,
|
"preferredPosition": item.position,
|
||||||
"nation": nation_id,
|
"nation": nation_id,
|
||||||
@@ -172,6 +176,7 @@ mod tests {
|
|||||||
item_id: 100000001,
|
item_id: 100000001,
|
||||||
asset_id: 20801,
|
asset_id: 20801,
|
||||||
resource_id: 20801,
|
resource_id: 20801,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
&ent,
|
&ent,
|
||||||
);
|
);
|
||||||
@@ -204,6 +209,7 @@ mod tests {
|
|||||||
item_id: 100000030,
|
item_id: 100000030,
|
||||||
asset_id: 101490,
|
asset_id: 101490,
|
||||||
resource_id: 101490,
|
resource_id: 101490,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
&ent,
|
&ent,
|
||||||
);
|
);
|
||||||
@@ -213,6 +219,7 @@ mod tests {
|
|||||||
item_id: 100000031,
|
item_id: 100000031,
|
||||||
asset_id: 101490,
|
asset_id: 101490,
|
||||||
resource_id: 101490,
|
resource_id: 101490,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
&ent,
|
&ent,
|
||||||
);
|
);
|
||||||
@@ -240,12 +247,20 @@ mod tests {
|
|||||||
item_id: 100000384,
|
item_id: 100000384,
|
||||||
asset_id: 176580,
|
asset_id: 176580,
|
||||||
resource_id: 117617092,
|
resource_id: 117617092,
|
||||||
|
rareflag: 3,
|
||||||
},
|
},
|
||||||
&ent,
|
&ent,
|
||||||
);
|
);
|
||||||
assert_eq!(it["resourceId"], 117617092, "versioned resource id on the wire");
|
assert_eq!(
|
||||||
|
it["resourceId"], 117617092,
|
||||||
|
"versioned resource id on the wire"
|
||||||
|
);
|
||||||
assert_eq!(it["definitionId"], 117617092);
|
assert_eq!(it["definitionId"], 117617092);
|
||||||
assert_eq!(it["assetId"], 176580, "base asset id preserved");
|
assert_eq!(it["assetId"], 176580, "base asset id preserved");
|
||||||
assert_eq!(it["cardassetid"], 176580);
|
assert_eq!(it["cardassetid"], 176580);
|
||||||
|
assert_eq!(
|
||||||
|
it["rareflag"], 3,
|
||||||
|
"special rareflag carried, not hardcoded 1"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ mod tests {
|
|||||||
item_id: 100000042,
|
item_id: 100000042,
|
||||||
asset_id: 20801,
|
asset_id: 20801,
|
||||||
resource_id: 20801,
|
resource_id: 20801,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
)]));
|
)]));
|
||||||
let input = one_slot_input(&owned, SquadExtInput::Fresh(fresh_ext()));
|
let input = one_slot_input(&owned, SquadExtInput::Fresh(fresh_ext()));
|
||||||
@@ -361,6 +362,7 @@ mod tests {
|
|||||||
item_id: 100000030,
|
item_id: 100000030,
|
||||||
asset_id: 101490,
|
asset_id: 101490,
|
||||||
resource_id: 101490,
|
resource_id: 101490,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -369,6 +371,7 @@ mod tests {
|
|||||||
item_id: 100000031,
|
item_id: 100000031,
|
||||||
asset_id: 101490,
|
asset_id: 101490,
|
||||||
resource_id: 101490,
|
resource_id: 101490,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]));
|
]));
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ fn oracle_tables() -> (HashMap<String, CoreOwnedItem>, TableIdentity) {
|
|||||||
item_id: wire as u32,
|
item_id: wire as u32,
|
||||||
asset_id: asset,
|
asset_id: asset,
|
||||||
resource_id: asset,
|
resource_id: asset,
|
||||||
|
rareflag: 1,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,6 +280,10 @@ pub struct ObservedDefinition {
|
|||||||
/// pace, shooting, passing, dribbling, defending, physical (index 0..=5).
|
/// pace, shooting, passing, dribbling, defending, physical (index 0..=5).
|
||||||
pub attrs: [i64; 6],
|
pub attrs: [i64; 6],
|
||||||
pub rarity: &'static str,
|
pub rarity: &'static str,
|
||||||
|
/// Observed FIFA wire `rareflag` (the card's rare/special TYPE, e.g. 3=inform,
|
||||||
|
/// 21..=24 = special programmes). Carried verbatim from the profile — the raw
|
||||||
|
/// integer, never a guessed marketing label — so specials render as specials.
|
||||||
|
pub rareflag: i64,
|
||||||
/// Wire ids of the owned copies of this exact resourceId (preserved).
|
/// Wire ids of the owned copies of this exact resourceId (preserved).
|
||||||
pub wire_ids: Vec<i64>,
|
pub wire_ids: Vec<i64>,
|
||||||
}
|
}
|
||||||
@@ -508,6 +512,7 @@ pub fn plan_definitions(
|
|||||||
team_id,
|
team_id,
|
||||||
attrs: attrs6.unwrap(),
|
attrs: attrs6.unwrap(),
|
||||||
rarity: tier(rating),
|
rarity: tier(rating),
|
||||||
|
rareflag: f.rareflag.unwrap_or(1),
|
||||||
wire_ids,
|
wire_ids,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -899,12 +904,12 @@ pub fn emit_content(
|
|||||||
let content_pack = content_dir.join("fifa17-production-cards.json");
|
let content_pack = content_dir.join("fifa17-production-cards.json");
|
||||||
write_json_pretty(&content_pack, &defs)?;
|
write_json_pretty(&content_pack, &defs)?;
|
||||||
|
|
||||||
// ---- PUBLIC: host identity catalog {card_id: {asset_id, version}} ----
|
// ---- PUBLIC: host identity catalog {card_id: {asset_id, version, rareflag}} ----
|
||||||
let mut cards = serde_json::Map::new();
|
let mut cards = serde_json::Map::new();
|
||||||
for d in &report.definitions.supported {
|
for d in &report.definitions.supported {
|
||||||
cards.insert(
|
cards.insert(
|
||||||
d.card_id.clone(),
|
d.card_id.clone(),
|
||||||
serde_json::json!({ "asset_id": d.asset_id, "version": d.version }),
|
serde_json::json!({ "asset_id": d.asset_id, "version": d.version, "rareflag": d.rareflag }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let catalog = serde_json::json!({
|
let catalog = serde_json::json!({
|
||||||
|
|||||||
@@ -552,6 +552,7 @@ impl ItemIdentityResolver for Fifa17IdentityResolver {
|
|||||||
item_id: wire as u32,
|
item_id: wire as u32,
|
||||||
asset_id: ident.asset_id,
|
asset_id: ident.asset_id,
|
||||||
resource_id: ident.resource_id,
|
resource_id: ident.resource_id,
|
||||||
|
rareflag: ident.rareflag,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user