Experience levels WIRED: the egg field drives the simulation tier (Gitea #2)

BTPlayer's master ctor now seeds the flag block from
btMission->ExperienceLevel() + AdvancedDamageOn() (accessors from the
SURVIVED 1995 BTMSSN.HPP [T0]) instead of the NULL-stubbed scenario
role -- the egg experience knob works for the first time.  Both switch
slot errors fixed vs the binary @4c0bc8; phantom btMission duplicate
member removed (+0x1f8 IS Player::playerMission).

SEVEN gate stubs unified onto the real flags (two found empirically):
HeatModelActive, OwnerAdvancedDamage, LiveFireEnabled,
ControlsAllowLights, powersub @4b0efc, emitter's file-local FUN_004ad7d4
+ FUN_004ac9c8 stubs.  FUN_004ac9c8 family swept (incl. a live raw-offset
databinding trap in MechSubsystem::IsDamaged).  Flag block renamed to its
true semantics (simLive/heatModelOn/...), scoring-era names kept as
comments.  Includes the #5 [aud-tail] diag in emitter.cpp.

ALL 19 shipped eggs say experience=expert -> default behavior UNCHANGED
(per-tier verified: novice/standard = no heat/jams, authentic; veteran/
expert = today's exact behavior).  Real delta: egg advancedDamage=1 now
reaches player+0x264/0x268 (was hardwired 0).  Follow-up flagged: the
glass FE defaults empty experience to veteran (one tier below shipped).

Awaiting human verification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-20 14:51:35 -05:00
co-authored by Claude Fable 5
parent a0cec48e3f
commit d7158f1f82
14 changed files with 294 additions and 130 deletions
+11 -3
View File
@@ -366,13 +366,21 @@ void
}
//
// @0x4ac9c8 -- IsDamaged: true (dead) when the owning mech's electrical bus is
// down -- *(*(*(owner+0xd0)+0x190)+0x274) == 0.
// @0x4ac9c8 -- the NOVICE-experience lockout predicate (issue #2 [T1]):
// *(*(*(sub+0xd0)+0x190)+0x274) == 0, i.e. owner mech -> playerLink ->
// BTPlayer experienceLevel == 0. NOT a damage/bus query (the old label), and
// the old body raw-read the binary offset chain off `owner` (already the
// Mech, so the extra +0xd0 hop was doubly wrong) -- the databinding trap.
// Routed through the complete-type bridge in btplayer.cpp. NOTE:
// HeatSink::IsDamaged (heat.hpp) deliberately shadows this with a
// simulationState check for the gauge tint (btl4gaug.cpp); the FUN_004ac9c8
// call sites in powersub.cpp call the bridge directly.
//
Logical
MechSubsystem::IsDamaged()
{
return (*(int *)(*(int *)(*(int *)((char *)owner + 0xd0) + 0x190) + 0x274) == 0);
extern int BTPlayerRoleLocksAdvanced(void *owner_mech); // btplayer.cpp (FUN_004ac9c8)
return BTPlayerRoleLocksAdvanced(owner) ? True : False;
}