BT410 5.3.122: the pilot can punch out of the fire -- RealMaxSpeed, SetBurningState and ClearBurningState join the roster, and two more modes get names
Three of the six authentic Mech message handlers land, decomp-verified: - RealMaxSpeed (@0049f604): adopt the streamed real-max-speed (+0x7a0, the 5-notch throttle quantizer base) only while our own is unknown (+0x7a4); wire payload at +0x1c, sender stamped by Entity's network send @0041f640. The master-perf head's one-shot send stays staged with the EntityManager stream path. - SetBurningState (@0049f674): the burning wreck parks in a per-host off-field slot -- x = localHostID x 10000, y = localHostID x -1000 (data words @0049f6fc/@0049f6f8; the id is HostManager:: GetLocalHostID, the same accessor the entity-instance dispatch compares against ownerID) -- and the mode alarm drops to 2: BURNING, the second InDeathTransition state, whose writer was the last missing piece of that predicate. ForceUpdate(1) + AlwaysExecute (the binary's `flags &= ~2` IS DontExecuteFlag clearing). - ClearBurningState (@0049f700): mode 0, same dirty/execute pair. Decoded and recorded for the next sitting (MECH4.NOTES.md): BalanceCoolant (@0049f728 mark + @0049f788 redistribute-with-gauge-blip; blocked on the mech tail chain triple +0x7ac/+0x7bc/+0x7cc identity), and EjectPilot (@0049f854, read end-to-end): the ejection gate is mech+0x414 -- the combat-effectiveness census's consumer, found -- you can only punch out of a CRIPPLED mech; ejection is mode 10 (why IsMechDestroyed tests >= 9) plus a self-dispatched type-2 TakeDamage whose amount reads through the mapper's +0x208 binding. Soak: duck cycles green on the new build (7 volume swaps, crash-sig 0). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,9 @@ const Receiver::HandlerEntry
|
|||||||
Mech::MessageHandlerEntries[] =
|
Mech::MessageHandlerEntries[] =
|
||||||
{
|
{
|
||||||
MESSAGE_ENTRY(Mech, TakeDamage),
|
MESSAGE_ENTRY(Mech, TakeDamage),
|
||||||
|
MESSAGE_ENTRY(Mech, RealMaxSpeed),
|
||||||
|
MESSAGE_ENTRY(Mech, SetBurningState),
|
||||||
|
MESSAGE_ENTRY(Mech, ClearBurningState),
|
||||||
MESSAGE_ENTRY(Mech, DuckRequest)
|
MESSAGE_ENTRY(Mech, DuckRequest)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -308,6 +311,9 @@ Mech::Mech(
|
|||||||
defaultStateRequests = 0; // the streamed mode-request counters
|
defaultStateRequests = 0; // the streamed mode-request counters
|
||||||
gimpLeftRequests = 0; // (binary ctor @004a1674 zeroes
|
gimpLeftRequests = 0; // (binary ctor @004a1674 zeroes
|
||||||
gimpRightRequests = 0; // +0x334/+0x338/+0x33c)
|
gimpRightRequests = 0; // +0x334/+0x338/+0x33c)
|
||||||
|
realMaxSpeed = 0.0f; // the 0x15 share triplet (+0x7a0/4/8)
|
||||||
|
realMaxSpeedKnown = 0;
|
||||||
|
realMaxSpeedSent = 0;
|
||||||
collisionVolumeState.Initialize(2);
|
collisionVolumeState.Initialize(2);
|
||||||
collisionVolumeState.SetLevel(1);
|
collisionVolumeState.SetLevel(1);
|
||||||
standingVolumeHeight = 0.0f;
|
standingVolumeHeight = 0.0f;
|
||||||
@@ -855,6 +861,70 @@ void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
// RealMaxSpeedMessageHandler -- binary @0049f604 (authentic name from the
|
||||||
|
// handler table). Adopt the streamed real max speed only while our own is
|
||||||
|
// unknown. The wire shape is the entity-stream family: 12-byte header,
|
||||||
|
// sender EntityID at +0xc (stamped by Entity's network send @0041f640),
|
||||||
|
// reserved pair, payload at +0x1c.
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Mech::RealMaxSpeedMessageHandler(Receiver::Message *message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(message);
|
||||||
|
|
||||||
|
if (realMaxSpeedKnown == 0)
|
||||||
|
{
|
||||||
|
realMaxSpeed = *(Scalar *)((char *)message + 0x1c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
// SetBurningStateMessageHandler -- binary @0049f674. The burning wreck is
|
||||||
|
// parked in a per-host off-field slot: x = localHostID x 10000, y =
|
||||||
|
// localHostID x -1000 (the data words @0049f6fc/@0049f6f8; the id read is
|
||||||
|
// HostManager::GetLocalHostID -- the accessor the entity-instance dispatch
|
||||||
|
// compares against ownerID), z untouched. The mode alarm drops to 2 --
|
||||||
|
// BURNING, the second InDeathTransition state (its missing writer, found)
|
||||||
|
// -- the position dirty mark fires, and execution is forced back on so the
|
||||||
|
// state runs even on a DontExecute replicant.
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Mech::SetBurningStateMessageHandler(Receiver::Message *message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
|
||||||
|
HostID
|
||||||
|
local_host = application->GetHostManager()->GetLocalHostID();
|
||||||
|
localOrigin.linearPosition.x = (Scalar)local_host * 10000.0f;
|
||||||
|
localOrigin.linearPosition.y = (Scalar)local_host * -1000.0f;
|
||||||
|
localToWorld = localOrigin;
|
||||||
|
SetSimulationState(2);
|
||||||
|
ForceUpdate(1);
|
||||||
|
AlwaysExecute();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
// ClearBurningStateMessageHandler -- binary @0049f700: back to
|
||||||
|
// DefaultState, dirty the position, re-arm execution.
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Mech::ClearBurningStateMessageHandler(Receiver::Message *message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
|
||||||
|
SetSimulationState(0);
|
||||||
|
ForceUpdate(1);
|
||||||
|
AlwaysExecute();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
// The collision-volume swap (binaries @004ac04c / @004ac064): write the
|
// The collision-volume swap (binaries @004ac04c / @004ac064): write the
|
||||||
|
|||||||
@@ -958,8 +958,28 @@
|
|||||||
int gimpLeftRequests;
|
int gimpLeftRequests;
|
||||||
int gimpRightRequests;
|
int gimpRightRequests;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The real-max-speed share (binary +0x7a0/+0x7a4/+0x7a8). +0x7a0
|
||||||
|
// is the base every throttle command snaps to (5 notches, master
|
||||||
|
// perf head). A mech that has COMPUTED its own value (+0x7a4 set;
|
||||||
|
// that writer is still undecoded) sends it once over the wire
|
||||||
|
// (message 0x15, payload at byte 0x1c; latch +0x7a8) and ignores
|
||||||
|
// incoming shares; anyone else adopts the streamed value (handler
|
||||||
|
// @0049f604). The send rides the EntityManager stream path
|
||||||
|
// (@0041f640) -- staged with the ForceUpdate/update-record feed.
|
||||||
|
//
|
||||||
|
Scalar realMaxSpeed;
|
||||||
|
int realMaxSpeedKnown;
|
||||||
|
int realMaxSpeedSent;
|
||||||
|
|
||||||
void
|
void
|
||||||
DuckRequestMessageHandler(Receiver::Message *message);
|
DuckRequestMessageHandler(Receiver::Message *message);
|
||||||
|
void
|
||||||
|
RealMaxSpeedMessageHandler(Receiver::Message *message);
|
||||||
|
void
|
||||||
|
SetBurningStateMessageHandler(Receiver::Message *message);
|
||||||
|
void
|
||||||
|
ClearBurningStateMessageHandler(Receiver::Message *message);
|
||||||
void
|
void
|
||||||
SetStandingCollisionVolume(); // binary @004ac04c... see .CPP
|
SetStandingCollisionVolume(); // binary @004ac04c... see .CPP
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -282,3 +282,38 @@ advance dispatch death-guarded. SIDE EFFECT: `Mech::InDeathTransition`
|
|||||||
and the camera director's cut-away are now LIVE (mode 9 is finally
|
and the camera director's cut-away are now LIVE (mode 9 is finally
|
||||||
written on kills) -- the director path needs a rig eyeball when a pod is
|
written on kills) -- the director path needs a rig eyeball when a pod is
|
||||||
back.
|
back.
|
||||||
|
|
||||||
|
## 5.3.122 -- the message roster fills (three of the six landed)
|
||||||
|
|
||||||
|
Landed: **RealMaxSpeed** (@0049f604: adopt streamed +0x7a0 while +0x7a4
|
||||||
|
clear; wire payload at +0x1c, sender EntityID stamped at +0xc by Entity's
|
||||||
|
network send @0041f640 = {stamp id, msg+0x14 <- entity+0x194, EntityManager
|
||||||
|
(app+0x30) send @00434ea0}), **SetBurningState** (@0049f674: park the wreck
|
||||||
|
at (localHostID x 10000, localHostID x -1000) -- constants @0049f6fc/f8,
|
||||||
|
host id = HostManager::GetLocalHostID, THE accessor the instance dispatch
|
||||||
|
compares against ownerID -- then MODE 2 = BURNING, the second
|
||||||
|
InDeathTransition state's missing writer, + ForceUpdate(1) +
|
||||||
|
AlwaysExecute), **ClearBurningState** (@0049f700: mode 0 + same pair).
|
||||||
|
simulationFlags bit 1 == DontExecuteFlag (SIMULATE.HPP) -- the binary's
|
||||||
|
`&= ~2` IS AlwaysExecute().
|
||||||
|
|
||||||
|
Still to land from the roster:
|
||||||
|
|
||||||
|
* **BalanceCoolant @0049f728** (decoded): if payload > 0, mark item+0x1d0=1
|
||||||
|
across the mech+0x7cc roster, then the redistribute pass @0049f788: total
|
||||||
|
the marks, per item fraction = mark/total (0.0 @0049f850 when empty),
|
||||||
|
blip the item's alarm at +0x1dc (level 2 if fraction <= stored else 1,
|
||||||
|
then 0 -- the gauge flash), store fraction at item+0x15c. BLOCKED ON:
|
||||||
|
identifying the mech tail chain triple +0x7ac (legs -- the mobility
|
||||||
|
scan) / +0x7bc / +0x7cc (coolant holders) against our capability chains
|
||||||
|
-- @004aefa4 walks all three plus the plug at +0x590 to collect the
|
||||||
|
coolant set, so decode that fn to pin them.
|
||||||
|
* **EjectPilot @0049f854** (head read): gated on payload > 0 AND
|
||||||
|
**mech+0x414** -- THE EFFECTIVENESS-CENSUS CONSUMER FOUND: you can only
|
||||||
|
eject a CRIPPLED mech (@0049fa1c's weapons/coolant/generator/limp
|
||||||
|
census) -- and !InDeathTransition; notifies via an app+0x2c accessor
|
||||||
|
(@00429078) + app+0x20 vcall (score/event, code 5, ownerID +0x18c);
|
||||||
|
sets **MODE 10 = EJECTED** (which is WHY IsMechDestroyed tests >= 9:
|
||||||
|
9 killed, 10 ejected); then builds a large effect/explosion struct --
|
||||||
|
tail still unread. Mode roster now: 0 default, 2 burning, 3/4 gimp
|
||||||
|
L/R, 5-8 falls, 9 killed, 10 ejected; writers of 5-8 still open.
|
||||||
|
|||||||
Reference in New Issue
Block a user