feat(@projects/@magic-civilization): ⚔️ p3-26 B6b (3/3 boot) — FFI + harness boot the item combat table

- GdPlayerApi::set_item_combat_json — loads item combat bonuses onto GameState.
- player_api_main._apply_item_combat — stamps DataLoader.get_all_items() via the FFI at boot,
  emitting item_combat_api_loaded.

Equipped gear now boosts units in real headless combat (table booted → combat-read live).
gdext compiles. Remaining for full B6b: a Craft/Equip action to populate units' gear + loot
drop-on-death/decay (B5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-26 21:15:09 -04:00
parent a3dac211e3
commit a44ba951bd
2 changed files with 26 additions and 0 deletions

View file

@ -250,6 +250,10 @@ func _hydrate_player_api(num_players: int) -> void:
# `load_state_json`. Without this no resource refinement runs.
_apply_recipes()
# p3-26 B6b: stamp item combat bonuses so equipped gear boosts units in headless combat.
# Same `#[serde(skip)]` re-stamp pattern — load AFTER `load_state_json`.
_apply_item_combat()
## p3-26 B3: stamp improvement definitions (DataLoader's improvements: id, build_turns,
## yields:{food,production}) onto `GdPlayerApi` via `set_improvement_defs_json`. Consumed by
@ -276,6 +280,18 @@ func _apply_recipes() -> void:
_emit_event("recipes_api_loaded", {"bytes": n})
## p3-26 B6b: stamp item combat bonuses (DataLoader's items: id, stats:[{key,value}]) onto
## `GdPlayerApi` via `set_item_combat_json`. Consumed by the headless combat path so equipped
## gear adds attack/defense.
func _apply_item_combat() -> void:
var items: Array = DataLoader.get_all_items()
if items.is_empty():
_emit_protocol_error("items empty — equipped gear will not affect headless combat")
return
var n: int = int(_api.set_item_combat_json(JSON.stringify(items)))
_emit_event("item_combat_api_loaded", {"count": n})
## p3-26 gap 2: stamp the natural-event category configs (DataLoader's merged
## `{category: {base_frequency, severity_weights, tiers, …}}`) onto `GdPlayerApi` via
## `set_events_config_json`. Consumed by `mc-turn`'s climate-phase event dispatch.

View file

@ -200,6 +200,16 @@ impl GdPlayerApi {
self.state.load_recipes_json(json.to_string().as_str()) as i64
}
/// p3-26 B6b: load item combat bonuses (JSON array of item objects with
/// `stats`, from `public/resources/items/*.json`) so equipped gear boosts
/// units in headless combat. Returns the count stored. Call AFTER
/// `load_state_json` (the field is `#[serde(skip)]`).
#[func]
pub fn set_item_combat_json(&mut self, json: GString) -> i64 {
self.state
.load_item_combat_json(json.to_string().as_str()) as i64
}
/// Stamp the runtime `UnitsCatalog` (id → `UnitStats`) onto the held
/// `GameState`. Distinct from `set_units_catalog_json` (which loads the
/// tactical `ai_unit_catalog`): this is the same `mc_units::UnitsCatalog`