Per-pilot mech paint: wire the color/badge/patch substitution end-to-end
- Mech::resourceNameA/B/C -> real CString members (the binary's 16-byte CStringRepresentation; deep-copy bind from the MakeMessage = FUN_00402a98, implicit member dtors) + paint-name accessors - SetupMaterialSubstitutionList reads the real egg names ([paint] log); TearDown clears the callback first (FUN_004d11e8) - dpl_SetMaterialNameCallback is real now (L4VIDEO registry); bgfload MaterialResolver::resolve() applies it to every material name -- the port analogue of the dpl board rewriting names at load - MP_BHMC.EGG: color=Red -> Crimson (vehicletable has no Red; binary Fail()ed) Verified live 2-node MP: crimson MadCat with hip hazard stripes + yellow VGL leg emblems; white Blackhawk + emblems; replicants painted on both nodes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
dda517b65c
commit
e0474ff92a
@@ -2128,23 +2128,25 @@ void
|
||||
//
|
||||
// Look up this mech's colour / badge / patch codes from the table, using
|
||||
// the egg-supplied names carried on the entity (badge=resourceNameA @0x844,
|
||||
// color=resourceNameB @0x848, patch=resourceNameC @0x84c).
|
||||
// color=resourceNameB @0x848, patch=resourceNameC @0x84c). The binary
|
||||
// reads the backing text straight off the ref-counted name objects
|
||||
// (*(char**)(*(int*)(mech+0x848)+8) etc.); the reconstructed Mech now
|
||||
// carries them as real CString members deep-copied from the MakeMessage,
|
||||
// exposed via the paint-name accessors.
|
||||
//
|
||||
// The recovered code read these directly off the BattleTech mech egg
|
||||
// (Mech::vehicleColor / vehicleBadge / vehiclePatch) and Fail()ed on a miss.
|
||||
// TODO(bring-up): the reconstructed Mech carries those names as ref-counted
|
||||
// creation-name objects (resourceNameA/B/C) whose backing string is the
|
||||
// transient MakeMessage buffer -- not safely readable here yet, and the
|
||||
// attribute-index path ("VehicleColor"/...) is not wired, so it returns
|
||||
// garbage that FindNote then deref-crashed on (btl4vid.cpp:808). Follow the
|
||||
// RP analogue (RPL4VID.cpp:1562) which simply tolerates a missing colour/
|
||||
// badge: a NULL egg name or a table miss leaves veh_* == NULL and the
|
||||
// placeholder substitution below drops to default materials. Re-wire the
|
||||
// real egg names (a named Mech accessor) once the Mech layout is mapped.
|
||||
// DEVIATION (documented): on a table miss the binary Fail()ed hard
|
||||
// ("Exiting" @BTL4VID.CPP:0xbeb/0xbf2/0xbf9). We follow the RP analogue
|
||||
// (RPL4VID.cpp:1562) and tolerate it -- a NULL/missing name leaves veh_* ==
|
||||
// NULL and that placeholder expands empty (base materials) -- so a sparse
|
||||
// test egg degrades to the old gray-metal look instead of killing the pod.
|
||||
//
|
||||
const char *egg_color = NULL; // [0x848] resourceNameB (color)
|
||||
const char *egg_badge = NULL; // [0x844] resourceNameA (badge)
|
||||
const char *egg_patch = NULL; // [0x84c] resourceNameC (patch)
|
||||
Mech *mech = (Mech *)entity; // caller dispatched on MechClassID
|
||||
const char *egg_color = mech->GetVehicleColorName(); // [0x848] resourceNameB
|
||||
const char *egg_badge = mech->GetVehicleBadgeName(); // [0x844] resourceNameA
|
||||
const char *egg_patch = mech->GetVehiclePatchName(); // [0x84c] resourceNameC
|
||||
if (egg_color && !*egg_color) egg_color = NULL;
|
||||
if (egg_badge && !*egg_badge) egg_badge = NULL;
|
||||
if (egg_patch && !*egg_patch) egg_patch = NULL;
|
||||
|
||||
const char *veh_color = NULL, *veh_badge = NULL, *veh_patch = NULL;
|
||||
if (egg_color && !veh_tbl->GetEntry("color", egg_color, &veh_color)) // @0051d94e
|
||||
@@ -2166,6 +2168,14 @@ void
|
||||
veh_patch = NULL;
|
||||
}
|
||||
|
||||
DEBUG_STREAM << "[paint] mech egg color='" << (egg_color ? egg_color : "<none>")
|
||||
<< "' badge='" << (egg_badge ? egg_badge : "<none>")
|
||||
<< "' patch='" << (egg_patch ? egg_patch : "<none>")
|
||||
<< "' -> codes color=" << (veh_color ? veh_color : "-")
|
||||
<< " badge=" << (veh_badge ? veh_badge : "-")
|
||||
<< " patch=" << (veh_patch ? veh_patch : "-")
|
||||
<< " serno=" << gSerno << "\n" << std::flush;
|
||||
|
||||
//
|
||||
// Generic substitution list, then expand placeholders per entry.
|
||||
//
|
||||
@@ -2257,6 +2267,7 @@ void
|
||||
void
|
||||
BTL4VideoRenderer::TearDownMaterialSubstitutionList()
|
||||
{
|
||||
dpl_SetMaterialNameCallback(NULL); // FUN_0049664c(0) -- first, as the binary does
|
||||
if (materialSubstitutionList != NULL)
|
||||
{
|
||||
for (NameList::Entry *entry = materialSubstitutionList->GetFirstEntry();
|
||||
@@ -2269,7 +2280,6 @@ void
|
||||
delete materialSubstitutionList;
|
||||
materialSubstitutionList = NULL;
|
||||
}
|
||||
// dpl_SetMaterialNameCallback(NULL);
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
|
||||
Reference in New Issue
Block a user