diff --git a/data/shipScreen.json b/data/shipScreen.json index 48e27eb..334df7b 100644 --- a/data/shipScreen.json +++ b/data/shipScreen.json @@ -105,7 +105,7 @@ "hotBelow": 0.34 }, { - "_comment": "CURRENT HULL \u2014 the armor actually on the ship right now (the live fight's hull; full strength with no fight running).", + "_comment": "CURRENT HULL \u2014 the armor actually on the ship right now (the combat ledger's hull; it persists between fights and reads full once a landing or jump-arrival repairs it).", "id": "hullNow", "group": "armor", "label": "CURRENT HULL", diff --git a/js/scenes/GameScene.js b/js/scenes/GameScene.js index 9565b46..227a51f 100644 --- a/js/scenes/GameScene.js +++ b/js/scenes/GameScene.js @@ -8923,21 +8923,26 @@ export class GameScene extends Phaser.Scene { const s = this.ship; if (!s) return null; const c = this.combat; - const fighting = !!(c && c.active); // The maxima come from the combat system when it exists — that's where // the per-level armor bump lands (progression.reward.hullPerLevel / // shieldPerLevel), so the plate never shows a stale base number. const hullMax = Math.max(1, Math.round(Number(c?.maxHull ?? s.stats?.hullIntegrity) || 0)); const shieldsMax = Math.max(0, Math.round(Number(c?.maxShields ?? s.stats?.shields) || 0)); + // The CURRENT armor is the combat system's ledger too — it PERSISTS + // between fights (damage only heals on a landing's repairFull or a + // jump's arrival repair), so the plate reads it even when no pack is + // live: a fight over at half hull is still flying at half hull. + const hullNow = c ? Math.max(0, Math.round(Number(c.hull) || 0)) : hullMax; + const shieldsNow = c ? Math.max(0, Math.round(Number(c.shields) || 0)) : shieldsMax; // THE SKILL TREE DOOR — the ship console's standby tab lights the moment the // run's class owns a tree (data/skills.json → classes..skills). const skillDoor = !!(this.classState?.hasClass && skillHasTree(this.classState.id)); return { skillDoor, live: { - hull: fighting ? Math.max(0, Math.round(Number(c.hull) || 0)) : hullMax, + hull: hullNow, hullMax, - shields: fighting ? Math.max(0, Math.round(Number(c.shields) || 0)) : shieldsMax, + shields: shieldsNow, shieldsMax, }, ship: { diff --git a/js/ship/ShipScreenModel.js b/js/ship/ShipScreenModel.js index 3eec6c0..5c3c9b6 100644 --- a/js/ship/ShipScreenModel.js +++ b/js/ship/ShipScreenModel.js @@ -12,12 +12,17 @@ * 'ship:' a field of the ship snapshot (stats.cargoHold, * minerals, credits, cargo.used …) — state the run * mutates (upgrades, ore, buys/sells). - * 'live:' the LIVE combat session's armor (hull / hullMax / - * shields / shieldsMax), folded by GameScene: while - * a fight runs these are the session's values, and - * with no fight they read the maxima (the ship is - * never damaged out of combat — the plate says so - * through the row's `nominalLabel`). + * 'live:' the combat session's armor (hull / hullMax / + * shields / shieldsMax), folded by GameScene: + * the combat system's ledger PERSISTS between + * fights (damage only heals on a landing's + * repairFull or a jump's arrival repair), so + * these read the run's current armor whether a + * fight is live or not — and only with no combat + * system do they read the maxima (a fresh, never- + * flown ship). The `nominalLabel` is the row's + * at-full copy (hull at its limit is 'NOMINAL'), + * not an out-of-combat flag. * * Optional per-row math: op 'reciprocal' (a cooldown → a rate) and, for an * array of sources, op 'product' (damage × shots/sec = DPS). A row's meter is