Combat: critical-subsystem plugs BOUND -- zone destruction damages carried subsystems (task #2)
The binding was in the zone ctor all along: Ghidra dropped the two arg pushes @0049d0e1 (Slot::AddImplementation(subsystemArray[streamedIndex])), making it read as a bare Resolve(). DZSlot stand-in -> engine SlotOf<T>; SendSubsystemDamage rewritten to the recovered @0049c9a8 body (allotment into the subsystem's OWN private zone; vital -> graphicAlarm 9); CriticalHit -> real ApplyDamageAndMeasure; parentArtifactZone.Add revived (LOD damage averaging); videoObjectFlag renamed vitalSubsystem (+0xE4). BT_CRIT_PROBE diag added. Verified: 66 plugs bound/mech; probe-destroyed zone -> crits damaged/DESTROYED, statusAlarm + destroyed-skin chain fire; MP kill + solo un-regressed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a652ddcdbc
commit
87c25b9206
@@ -126,7 +126,7 @@ MechSubsystem::MechSubsystem(
|
||||
this->owner = owner; // this[0x34] -- the owning Mech (canonical)
|
||||
hostEntity = owner; // this[0x3a] = param_7
|
||||
subsystemId2 = subsystem_ID; // this[0x3b] = param_8
|
||||
videoObjectFlag = 0; // this[0x39]
|
||||
vitalSubsystem = 0; // this[0x39]
|
||||
BindName(refCount, "None"); // FUN_00402a98(.,this+0x3d,"None") @0x50df7a
|
||||
alarmModel = 0; // identity ResourceID // FUN_00408440(this+0x3e, identity)
|
||||
criticalReference = 0; // this[0x42]
|
||||
@@ -163,7 +163,7 @@ MechSubsystem::MechSubsystem(
|
||||
subsystemId2 = subsystem_ID; // this[0x3b]=param_7
|
||||
resource = subsystem_resource; // this[0x3c]
|
||||
vitalSubsystemIndex = -1; // this[0x44]
|
||||
videoObjectFlag = (subsystem_resource->vitalSubsystemIndex == 1); // res+0x48==1
|
||||
vitalSubsystem = (subsystem_resource->vitalSubsystemIndex == 1); // res+0x48==1
|
||||
|
||||
BindName(refCount, subsystem_resource->videoObjectName); // res+0x4c
|
||||
alarmModel = subsystem_resource->alarmModel; // res+0xcc -> this[0x3e]
|
||||
@@ -218,6 +218,24 @@ Scalar MechSubsystem::GetSubsystemDamageLevel() const
|
||||
return damageZone ? ((DamageZone *)damageZone)->damageLevel : 0.0f;
|
||||
}
|
||||
|
||||
//
|
||||
// @0049c9a8 (zone-side inline) -- the destroyed-side effects applied when a
|
||||
// crit drives this subsystem's own zone to 1.0: status Destroyed, the gated
|
||||
// debug print, and the zone's state valve. (task #2)
|
||||
//
|
||||
void MechSubsystem::ForceCriticalFailure()
|
||||
{
|
||||
statusAlarm.SetLevel(1); // +0x2C: 1 = Destroyed
|
||||
if (printSimulationState) // +0x104 gate
|
||||
{
|
||||
PrintState(); // vtable slot 0x34 @4ac8c0
|
||||
}
|
||||
if (damageZone != 0)
|
||||
{
|
||||
((DamageZone *)damageZone)->SetDamageZoneState(1); // zone+0x10
|
||||
}
|
||||
}
|
||||
|
||||
void MechSubsystem::SetSubsystemDamageLevel(Scalar level)
|
||||
{
|
||||
if (damageZone)
|
||||
@@ -263,7 +281,7 @@ Logical
|
||||
OnAlarmChanged(); // (*this.vtable+0x34)(this)
|
||||
}
|
||||
damageZone->structureLevel = 1.0f; // dz+0x158 = 1.0
|
||||
if (videoObjectFlag != 0) // this[0x39]
|
||||
if (vitalSubsystem != 0) // this[0x39]
|
||||
{
|
||||
((Mech *)owner)->RaiseStatusAlarm(9); // FUN_0041bbd8(owner+0x2c, 9)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user