Issue #3 (b)+(c): weapon damage reaches cultural icons -> full trkdead explosion + authored burn fire

(b) The 'tiny explosion' on the ram kill is AUTHORED: crunch res 31 = 'stephit'
(one video object, effect 1008 = ddam5 damage smoke) -- a step/ram squash is
small by design.  The FULL explosion res 32 = 'trkdead' = psfx 15 dtrkboom
(fiery omni burst) + psfx 16 dtrkburn (the burning-wreck fire), reached by
WEAPON kills -- which the 1995 binary dispatches [T1]:
  - MechWeapon::SendDamageMessage @004b9728 (part_013.c:6765) gates only
    "target NOT derived from Mech@0x50bdb4 OR aimed zone set": a non-Mech
    boresight target takes the zone=-1 damage UNCONDITIONALLY;
  - Missile contact @004be078 dispatches at the struck solid's OWNER entity
    with no class test at all.
Port wiring: Mech::WorldStructurePick returns the struck solid's owning entity
(BoxedSolid::GetOwningSimulation; TERRAIN.cpp:107/246 build every static solid
with its Terrain/CulturalIcon/Door entity as owner); the mech4 pick block
designates IT instead of the gBTTerrainEntity sentinel (sentinel = fallback);
the projectile contact path grew the non-mech damage-zoned else-branch
(@004be078 mirror, direct Dispatch).  Plain terrain ignores the damage
(ENTITY.cpp:885 zone==-1 guard); an icon's handler maps -1 -> 0 and dies.
Truck armor is WeaponDamagePoints=1 (TRK.DMG): one laser = one dead truck.

(c) The burning fire is dtrkburn.pfx, authored INTO the death package (every
icon family carries 1016: trkdead/bigdead/meddead/msldead/twrdead).  There is
NO looping BurningState fire in the binary: the damage-zone effect watcher
ctor @0042a984 has exactly one call site (the Mech ctor, part_012.c:10405), so
icon ExplosionTables are inert, and CulturalIcon has no Performance.
Documented as authentic -- nothing invented.

Verified live (BT_SHOT pixel capture): 26 laser kills, [cult] TakeDamage
type=3 -> DYING res=32 -> DPLIndependantEffect 1015+1016 at the icon origin;
frames show the orange dtrkboom fireball, dtrkburn flames on the fresh wreck,
and the rubble aftermath; ram harness re-run still fires crunch res 31.
Diags: BT_FIRE_AT_ICON (designate nearest ahead icon; live-icon census in
CULTURAL.cpp), BT_FX_TEST="1015,1016".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-19 12:02:15 -05:00
co-authored by Claude Fable 5
parent 9fff079df4
commit 6f6a39b8c9
6 changed files with 198 additions and 16 deletions
+22 -1
View File
@@ -258,6 +258,15 @@ CulturalIcon::AttributeIndexSet& CulturalIcon::GetAttributeIndex()
// Construction and Destruction
//
//
// Live-icon census (issue #3 diag): lets the BT_FIRE_AT_ICON harness designate
// a real map icon deterministically (headless weapon-vs-icon verification).
// Registration bookkeeping only -- no behavior change; entries are removed in
// the dtor (interest streaming can delete icons on zone transitions).
//
Entity *gBTCultIcons[256];
int gBTCultIconCount = 0;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CulturalIcon::CulturalIcon(
@@ -266,6 +275,10 @@ CulturalIcon::CulturalIcon(
) :
UnscalableTerrain(creation_message, shared_data)
{
if (gBTCultIconCount < 256)
{
gBTCultIcons[gBTCultIconCount++] = this;
}
Str_Copy(teamName, "Defualt", sizeof(teamName));
//
@@ -428,7 +441,15 @@ CulturalIcon*
//
CulturalIcon::~CulturalIcon()
{
// live-icon census removal (swap-with-last; see the registration above)
for (int ii = 0; ii < gBTCultIconCount; ++ii)
{
if (gBTCultIcons[ii] == this)
{
gBTCultIcons[ii] = gBTCultIcons[--gBTCultIconCount];
break;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//