fix(import-fifa17): carry the fields a consumable needs to exist
Two defects that together made the club's 17 owned consumables invisible while club/stats still counted them — the count gate promised 17, the item route served 0. 1. The catalog omitted `card_asset_id`, `amount`, `contract` and `rating` for non-player definitions. Without an art id the adapter refuses to emit the card (it would draw the notfound box), and the families that read `amount`/`contract` would render "-1" or grant nothing. All four values are present in the source wire and were simply dropped on the way out. 2. Owned rows were imported without a `content_kind`, and Core defaults an unstated row to `player` — durably recording a fitness coach and a contract card as players in the ownership authority, even though the catalog-driven wire looked right. These are definition-level fields, so every owned copy must agree; a group that disagrees is deferred rather than resolved by taking the first copy's value. Measured on the real profile: observed `amount` equals the `fcc_*` table row for every consumable that carries one (1, 2, 4, 5, 10, 15), and a wire omission corresponds to a table amount of 0. It is therefore NOT a stack count — two copies of 5003068 are two instances — so the import states no `quantity` at all.
This commit is contained in:
@@ -546,6 +546,21 @@ pub struct NonPlayerDefinition {
|
||||
pub card_asset_id: Option<i64>,
|
||||
/// Source team id for a kit definition, when present.
|
||||
pub team_id: Option<i64>,
|
||||
/// Consumable effect magnitude (`amount`), when the source carries one.
|
||||
///
|
||||
/// Definition-level, and measured to be so: across every owned consumable in
|
||||
/// the real profile the observed `amount` equals its `fcc_*` table row
|
||||
/// (1, 2, 4, 5, 10, 15 — no disagreements), and a wire omission corresponds
|
||||
/// to a table `amount` of 0. It is NOT a stack count: two copies of 5003068
|
||||
/// arrive as two separate instances, each with the same amount.
|
||||
pub amount: Option<i64>,
|
||||
/// Contract-card payload (`contract`), when the source carries one. Present
|
||||
/// on exactly the contract families (subtypes 201/202) and absent from every
|
||||
/// other owned consumable, so it is the card's own field rather than the
|
||||
/// generic per-item contract atom that players and staff carry.
|
||||
pub contract: Option<i64>,
|
||||
/// Card rating, when the source carries one (matches the `fcc_*` row).
|
||||
pub rating: Option<i64>,
|
||||
/// Honest functional label (e.g. "Player Contract", "GK Coach", "Kit").
|
||||
pub name: String,
|
||||
/// Wire ids of every owned copy of this resourceId (preserved).
|
||||
@@ -635,10 +650,20 @@ pub fn plan_non_player_definitions(profile: &Profile) -> NonPlayerPlan {
|
||||
|
||||
let card_asset_id = items[0].cardassetid;
|
||||
let team_id = items[0].teamid;
|
||||
if items
|
||||
.iter()
|
||||
.any(|item| item.cardassetid != card_asset_id || item.teamid != team_id)
|
||||
{
|
||||
// These are definition-level, so every owned copy must agree. Two copies
|
||||
// of one consumable that disagreed would mean the field is really
|
||||
// per-instance, and silently taking the first copy's value would bake a
|
||||
// guess into the catalog — so defer the whole group instead.
|
||||
let amount = items[0].amount;
|
||||
let contract = items[0].contract;
|
||||
let rating = items[0].rating;
|
||||
if items.iter().any(|item| {
|
||||
item.cardassetid != card_asset_id
|
||||
|| item.teamid != team_id
|
||||
|| item.amount != amount
|
||||
|| item.contract != contract
|
||||
|| item.rating != rating
|
||||
}) {
|
||||
plan.deferred.push(DeferredNonPlayer {
|
||||
resource_id,
|
||||
subtype: Some(subtype),
|
||||
@@ -700,6 +725,9 @@ pub fn plan_non_player_definitions(profile: &Profile) -> NonPlayerPlan {
|
||||
subtype,
|
||||
card_asset_id,
|
||||
team_id,
|
||||
amount,
|
||||
contract,
|
||||
rating,
|
||||
name: label.to_string(),
|
||||
wire_ids,
|
||||
});
|
||||
@@ -1184,6 +1212,14 @@ pub fn emit_content(
|
||||
serde_json::json!({
|
||||
"card_asset_id": d.card_asset_id,
|
||||
"team_id": d.team_id,
|
||||
// A consumable is unrenderable without these: the adapter refuses
|
||||
// to emit a card whose art id it does not know, and the families
|
||||
// that read `amount`/`contract` draw "-1" or grant nothing when
|
||||
// the field is missing. Omitting them here is what kept every
|
||||
// owned consumable off the wire.
|
||||
"amount": d.amount,
|
||||
"contract": d.contract,
|
||||
"rating": d.rating,
|
||||
"asset_id": d.asset_id.unwrap_or(d.resource_id),
|
||||
"version": 0,
|
||||
"rareflag": 0,
|
||||
|
||||
Reference in New Issue
Block a user