gauges: reconstruct cmArmor -- the per-zone ARMOR DAMAGE schematic [widget recon 3]
Each armor zone on the cockpit schematic is now tinted by that zone's live damage. Render-verified: the schematic shows an all-green Blackhawk (all zones damageLevel=0 at spawn), replacing the static green+red it showed before cmArmor was registered -- i.e. cmArmor now owns those zone colors and shows the real undamaged state; damaged zones shift toward red. Reuses the ColorMapper base (from cmHeat) + two pieces reconstructed from the binary (Ghidra dropped the x87, recovered by disassembly): - ArmorZoneConnection (@004c33a4/@004c3430): resolves one zone from the owner's inherited Entity::damageZones[zone_index]; per-frame feed = zone==NULL ? 100 : Round(zone->damageLevel * 100) (the 0..1 damage ratio -> 0..100 percentage -> the colour index ColorMapper::Execute pushes into the palette slot). - ColorMapperArmor::Make/ctor (@004c3aa4/@004c3b98): Make resolves the CFG zone name (dz_ltorso etc., the 6th param) to an index via Entity::GetDamageZoneIndex (== the binary's FUN_0042076c, scanning damageZones[] by name); the ctor wires the ArmorZoneConnection. Decomp fact (corrects the cmHeat note): the ColorMapper base ctor takes NINE args -- an owner_ID sits between renderer and graphics_port_number. Our 8-arg ColorMapper::ColorMapper folds owner_ID=0 in (gauges have owner 0), so it is equivalent; cmArmor's mapping matches cmHeat plus the zone name. Verified: parses, builds, all dz_* zones resolve (0 "not found"), no /FORCE unresolved, combat un-regressed (TARGET DESTROYED, 0 crashes). The dynamic red-on-damage needs the player to take damage (the passive spawn dummy never hits back). Details: docs/GAUGE_COMPOSITE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e869b00181
commit
1d2ddd8399
+26
-1
@@ -282,7 +282,32 @@ the Ghidra pseudo-C for Execute@004c5914 + ctor@004c562c had the x87 endpoint ma
|
||||
float computation Ghidra dropped by PE-parsing + capstone-disassembling the fn (`scratchpad/disas_hp.py`) —
|
||||
read the `fild/fmul/fadd` stream + the `.data` float pool.**
|
||||
|
||||
**Next increments (priority order from the map):** `cmArmor`/`colorMapperMultiArmor` (armor schematic, needs the
|
||||
**✅ Increment 3 — `cmArmor` (ColorMapperArmor) DONE — the ARMOR DAMAGE schematic, per-zone.** Each of the
|
||||
mech's armor zones on the cockpit schematic is now tinted by that zone's LIVE damage. Render-verified: the
|
||||
schematic shows the Blackhawk silhouette all-green (all zones `damageLevel`=0 at spawn) — which REPLACED the
|
||||
static green+red the schematic showed before cmArmor was registered (i.e. cmArmor now owns those zone colors,
|
||||
showing the real undamaged state; damaged zones shift toward red via the decomp-verified path). Reuses the
|
||||
ColorMapper base (done in incr.1) + adds two pieces reconstructed from the binary + a disassembly of the x87
|
||||
Ghidra dropped (`scratchpad/disas_hp.py`):
|
||||
- **`ArmorZoneConnection`** (@004c33a4 ctor / @004c3430 Transfer): resolves ONE zone from the owner's
|
||||
inherited `Entity::damageZones[zone_index]`; per-frame feed = `zone==NULL ? 100 : Round(zone->damageLevel
|
||||
@0x158 * 100)` (the damage ratio 0..1 → 0..100 percentage → the colour index ColorMapper::Execute pushes).
|
||||
- **`ColorMapperArmor::Make`/ctor** (@004c3aa4/@004c3b98): `Make` resolves the CFG zone NAME (`dz_ltorso` etc.,
|
||||
the 6th param) to an index via `Entity::GetDamageZoneIndex(CString)` — which IS the binary's `FUN_0042076c`
|
||||
(scans `damageZones[]` matching each zone's name @0x15c); the ctor wires the ArmorZoneConnection.
|
||||
- **DECOMP FACT (corrects the cmHeat note): the ColorMapper base ctor `FUN_004c37dc` takes NINE args** — there
|
||||
is an `owner_ID` between `renderer` and `graphics_port_number` (`Gauge(rate,mode,renderer,owner_ID,id)` +
|
||||
`colorSlot=param_7`, `graphicsPort=GetGraphicsPort(param_6)`). Our 8-arg `ColorMapper::ColorMapper` folds
|
||||
`owner_ID=0` in (gauges have owner 0), so it's equivalent — cmArmor's mapping matches cmHeat (gpn=port,
|
||||
colorSlot=p[2], palettes=p[3]/p[4]) plus the zone name (p[5]). Verified: parses, builds, **all `dz_*` zones
|
||||
resolve (0 "not found")**, no `/FORCE` unresolved, combat un-regressed (TARGET DESTROYED, 0 crashes). NOTE:
|
||||
the dynamic red-on-damage needs the PLAYER to take damage — the passive `BT_SPAWN_ENEMY` dummy never hits
|
||||
back, so a live demo of a zone reddening needs a player-damage path (real MP combat, or a test hook).
|
||||
⚠ The sibling `colorMapperMultiArmor` (worst-of-8-zones, MultiArmorConnection @004c346c) + `cmCrit`
|
||||
(ColorMapperCritical, CriticalConnection @004c3598) are the same shape — easy follow-ups now the pattern
|
||||
+ the ColorMapper base facts are pinned.
|
||||
|
||||
**Next increments (priority order from the map):** `colorMapperMultiArmor`/`cmCrit` (same ColorMapper pattern), then the
|
||||
`ArmorZoneConnection`/`MultiArmorConnection` classes reconstructed); then the attribute-table wave (`vertBar`/
|
||||
`segmentArcRatio` speed/`GeneratorCluster` — need `AttributePointers[]` on Mech/HeatableSubsystem, a separate
|
||||
pass); the XL items (`map`/`vehicleSubSystems`/`PlayerStatus`) last. The POD path needs the FULL 23-entry
|
||||
|
||||
Reference in New Issue
Block a user