myomer system COMPLETE -- the 'WAVE 6 mover cutover' was a phantom built on
a misattribution; the authentic couplings are all live
THE CORRECTION [T1]: @004b9550/@004b95b8 ('ConnectToMover'/'Disconnect
FromMover') are MechWeapon::ConfigureMappables/ChooseButton -- their +0x31C
is the weapon TriggerState and **(mech+0x128) is the CONTROLS MAPPER's
button roster (the MECHWEAP.CPP assert string + the trigger-edge detector
@004b9608 sit adjacent in the image). The binary has NO dynamic myomer->
speed feed: AvailableOutput has exactly TWO callers in the whole image --
RegisterMaxOutput (assembly) and the SeekVoltageGraph sampler -- and
speedEffect@0x31C is a published GAUGE attribute.
The authentic myomer system (now fully live):
1. drive heat (#85, this morning);
2. VITAL death -- myomers are the only authored vital=1 subsystem
(BTL4.RES res+0x48 scan): destroying them kills the mech via the #80
vital-crit path (this is also the ram-death mechanism -- myomers are a
0.35-weight collision-rattle target);
3. the assembly-time gait cap: RegisterMaxOutput @004b8ef0 raises
mech+0x7A0 to AvailableOutput(top gear) = base x ~1.4284 -- now called
(idempotent max, per tick; the 0x358 layout lock leaves no latch room)
with real OwnerBaseSpeed/OwnerMaxSpeed bridges; the old per-frame
reverseSpeedMax2 heal that would have clobbered it is garbage-guarded;
4. the ENG-page power curve at correct absolute scale (real base speed);
5. electrical sourcing (low gears run on a browned-out generator).
REMOVED (inventions): the mechmppr `speedDemand *= speedEffect` demand
multiplier + BTMyomersDriveOf + the Myomers ConnectToMover/MoverAttach
family. Damaged-but-alive myomers heat faster and drop the power curve
but do NOT slow the mech (gitea #75's premise is falsified by the binary;
the real damage slowdown is the LEG-damage gimp gait). Seek gears change
heat/sourcing/graph -- never speed.
Verified live: a mech at myomer dmg=0.234 (speedEffect attr 0.766)
beelines at full commanded speed with dmgGain=1.234 heat; 0 faults.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Zh7PTkFy4KwTzVighLR9J
This commit is contained in:
co-authored by
Claude Fable 5
parent
31552c0444
commit
cf8618bcb9
@@ -414,28 +414,13 @@ Scalar Myomers::SeekVoltageResponse(Scalar input_voltage)
|
||||
// (see emitter.cpp BTSeekVoltageSample). Guarded: a non-Myomers subsystem
|
||||
// samples 0 (only emitter/myomer pages own a graph in the shipped config).
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
// #75 bridge -- the myomers' live drive fraction for the mech's speed demand.
|
||||
//
|
||||
// The authentic coupling: ConnectToMover attached &speedEffect into the
|
||||
// mech's mover, which multiplied every attached feed into its drive. The
|
||||
// 2007 engine's mover has no such roster, so the port applies the same
|
||||
// multiplication at the speed-demand site (mechmppr.cpp): demand *= this.
|
||||
// speedEffect@0x31C is the wrapper's live 0..1 output -- gear ratio, thermal
|
||||
// curve and (1 - zone damage) -- already republished every tick. A mech
|
||||
// with no Myomers (or no roster yet) drives at 1.0; a DESTROYED myomers
|
||||
// drives 0.0 (no drive -- the subsystem that moves the mech is gone).
|
||||
//***************************************************************************
|
||||
Scalar BTMyomersDriveOf(void *subsystem)
|
||||
{
|
||||
Entity *entity = (Entity *)subsystem;
|
||||
if (entity == 0 || !entity->IsDerivedFrom(Myomers::ClassDerivations))
|
||||
return -1.0f; // not a Myomers
|
||||
Scalar f = ((Myomers *)entity)->SpeedEffect();
|
||||
if (f < 0.0f) f = 0.0f;
|
||||
if (f > 1.0f) f = 1.0f;
|
||||
return f;
|
||||
}
|
||||
// (BTMyomersDriveOf is DELETED -- myomer-system completion, 2026-07-31. The
|
||||
// demand-side `speedDemand *= speedEffect` coupling it fed (mechmppr.cpp) was
|
||||
// an invention built on the ConnectToMover misattribution. The binary's only
|
||||
// runtime AvailableOutput consumers are RegisterMaxOutput (assembly) and the
|
||||
// SeekVoltageGraph sampler; myomer damage does NOT slow a live mech -- a
|
||||
// DESTROYED myomers KILLS it, via the authored vital flag (the only vital=1
|
||||
// subsystem in the RES) + the #80 vital-crit death path.)
|
||||
|
||||
Scalar BTMyomersSeekSample(void *subsystem, Scalar voltage)
|
||||
{
|
||||
@@ -505,6 +490,20 @@ static const Scalar MyomerRecoveryPerTick = -0.010999999940395355f; // 0xbc34395
|
||||
//
|
||||
void Myomers::MyomersSimulation(Scalar time_slice)
|
||||
{
|
||||
// 0. RegisterMaxOutput (@004b8ef0) -- the assembly-time top-speed cap.
|
||||
// The binary calls it from the mech-assembly loop over the myomer chain
|
||||
// (part_012.c:10322), after the model record is streamed:
|
||||
// mech[0x7A0] = max(mech[0x7A0], AvailableOutput(seekVoltage[maxIdx]))
|
||||
// = base x (topGear/recGear) = base x ~1.4284 on a healthy assembly --
|
||||
// the gait rise-clamp both channels bound against (part_012:12103/12334).
|
||||
// The port's capability-chain fill is the SubProxy stub (same situation as
|
||||
// the flush's chain walk), so each myomer registers ITSELF here. Called
|
||||
// per tick instead of once (the 0x358 layout lock leaves no room for a
|
||||
// latch member): RegisterMaxOutput is an idempotent max() -- best falls as
|
||||
// heat/damage degrade AvailableOutput, and max() never lowers the cap --
|
||||
// so the resulting state is identical to the binary's once-at-assembly.
|
||||
RegisterMaxOutput(); // @004b8ef0
|
||||
|
||||
// 1. @004b8bab -- the base electrical state machine. MUST come first, and
|
||||
// must precede any heat-model gate: OwnerAdvancedDamage() is off below
|
||||
// veteran, so gating ahead of this denied the machine to most pilots.
|
||||
@@ -739,52 +738,14 @@ void Myomers::ResetToInitialState(Logical powered)
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Myomers::ConnectToMover (mislabeled)
|
||||
//***************************************************************************
|
||||
//
|
||||
// ⚠ MISATTRIBUTION (task #5 correction): @004b9550/@004b95b8 are NOT Myomers
|
||||
// functions -- the weapon message-table @0x511860 proves they are
|
||||
// MechWeapon::ConfigureMappables (id 9) / ChooseButton (id 10), the weapon->
|
||||
// button grouping handlers (the +0x31C coincidence: Myomers speedEffect vs
|
||||
// MechWeapon TriggerState). The bodies below are retained as the port's
|
||||
// Myomers stand-ins but carry no binary address.
|
||||
//
|
||||
// Attaches the live SpeedEffect output (@0x31C) into the Mech's JointedMover
|
||||
// roster (the mover at **(Mech[0xD0]+0x128)). Driven by a connect message
|
||||
// whose payload index is at message+0xC:
|
||||
// index = abs(message->value) - 1;
|
||||
// if (message->value < 1) { mover->Detach(index); this[0x110] = -1; }
|
||||
// else { this[0x110] = 0; mover->Attach(index, &speedEffect, this, 10, 9, 0); }
|
||||
// (mover vtable +0x38 = Attach, +0x3C = Detach.)
|
||||
//
|
||||
void Myomers::ConnectToMover(SubsystemMessage &message)
|
||||
{
|
||||
int index = abs(message.value) - 1; // message+0xC
|
||||
if (message.value < 1) {
|
||||
MoverDetach(index); // owner mover vtable +0x3C
|
||||
/* base+0x110 = -1 (detached) -- inert, no base accessor yet */
|
||||
} else {
|
||||
/* base+0x110 = 0 (attached) -- inert, no base accessor yet */
|
||||
MoverAttach(index, &speedEffect); // owner mover vtable +0x38, feed @0x31C
|
||||
// (original args: index,&speedEffect,this,10,9,0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Myomers::DisconnectFromMover (stand-in; no binary address)
|
||||
//***************************************************************************
|
||||
// Counterpart of ConnectToMover: detaches the SpeedEffect feed.
|
||||
// if (message->value > 0)
|
||||
// mover->Release(message->value, &speedEffect); // mover vtable +0x44
|
||||
void Myomers::DisconnectFromMover(SubsystemMessage &message)
|
||||
{
|
||||
if (message.value > 0) { // message+0xC
|
||||
MoverRelease(message.value, &speedEffect); // owner mover vtable +0x44, feed @0x31C
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// (ConnectToMover / DisconnectFromMover are DELETED -- myomer-system
|
||||
// completion, 2026-07-31. Their source functions @004b9550/@004b95b8 are
|
||||
// MechWeapon::ConfigureMappables / ChooseButton (the +0x31C there is the
|
||||
// weapon TriggerState and **(mech+0x128) is the CONTROLS MAPPER's button
|
||||
// roster -- proven by the MECHWEAP.CPP assert string and the trigger-edge
|
||||
// detector @004b9608 adjacent in the image). The binary has NO dynamic
|
||||
// myomer->mover feed; see the RegisterMaxOutput latch in MyomersSimulation
|
||||
// for the real (assembly-time cap) locomotion coupling.)
|
||||
//***************************************************************************
|
||||
// Myomers::ToggleSeekVoltageMessageHandler @004b8a48
|
||||
//***************************************************************************
|
||||
|
||||
Reference in New Issue
Block a user