weapon SPEC AUDIT: the fleet's authored numbers in one pass -- missile delivery fully reconciled

"do we need to audit every possible weapon independently?" -- one dump answers
all of them.  [wspec]/[wspec-msl] (BT_SPEC_LOG) print every weapon's AUTHORED
damage/recycle/range/heat + missile count and post-divide per-missile at build.

THE KEY DISCOVERY: the catalog's FULL-NAME loadouts (madcat, thor, avatar,
sunder, vulture, loki, blkhawk, owens) author DIFFERENT weapons than the
4-char variants (mad1, thr1, ...) -- and the named ones are what players fly.
Every night-9 field number reconciles exactly:
    madcat/thor LRM15 = 50 total -> 3.33/missile (field: 3.33, bursts 3..15)
    avatar/sunder LRM10 = 35     -> 3.50          (field: 3.50, bursts 2..10)
    vulture LRM20 = 65           -> 3.25          (field: 3.25, bursts 5..20)
    loki SRM4 = 35               -> 8.75          (field: 8.75, bursts 1..4)
Missile delivery is FAITHFUL across the real fleet: per-missile = authored /
count (divide confirmed live post-ctor), delivered total = per-missile x the
binary's Random(n)+n/4 roll = 25..100% of listed, zone-scattered.

The "80+ point hits" recollection fits the data as an ALPHA: madcat full alpha
= 50 + 25 (AFC100) + 6 + 2 = 83.  A single 4.10 salvo cannot exceed 65
(vulture LRM20).  The "3-5 points" reports read our [projectile] IMPACT
per-missile diagnostic as a total.

Also: bac1 is not a valid vehicle (unhandled AV at btl4+0xac4cd on spawn --
noted for a guard someday); wspec-msl now prints AFTER the ctor divide.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-08-02 13:31:36 -05:00
co-authored by Claude Opus 5
parent 47d9a61402
commit 08ca66e5b5
2 changed files with 544 additions and 524 deletions
+14
View File
@@ -327,6 +327,20 @@ MechWeapon::MechWeapon(
rangeToTarget = 0.0f; // 0x324 rangeToTarget = 0.0f; // 0x324
targetWithinRange = False; // 0x34C targetWithinRange = False; // 0x34C
// #95-follow-up WEAPON SPEC AUDIT (BT_SPEC_LOG): one line per weapon with
// the AUTHORED numbers, so "missile damage is too low" can be argued
// against the shipped data instead of memory. damageAmount here is the
// authored TOTAL (the MissileLauncher ctor divides by missileCount after
// this, mirroring @004bcff0).
if (getenv("BT_SPEC_LOG"))
DEBUG_STREAM << "[wspec] " << (GetName() ? GetName() : "?")
<< " dmg=" << damageData.damageAmount
<< " type=" << (int)damageData.damageType
<< " recycle=" << rechargeRate
<< " range=" << weaponRange
<< " heat=" << heatCostToFire
<< "\n" << std::flush;
// segmentReference/pipSegment were phantom tail members (past the binary 0x3F0 end); // segmentReference/pipSegment were phantom tail members (past the binary 0x3F0 end);
// removed. The muzzle segment index is the inherited base slot this+0xdc (used by // removed. The muzzle segment index is the inherited base slot this+0xdc (used by
// GetMuzzlePoint); the pip mount is gated by useConfiguredPip in DrawWeaponPip. // GetMuzzlePoint); the pip mount is gated by useConfiguredPip in DrawWeaponPip.
+7 -1
View File
@@ -183,11 +183,17 @@ MissileLauncher::MissileLauncher(
// vtable installed by the compiler (PTR_FUN_00512570) // vtable installed by the compiler (PTR_FUN_00512570)
missileCount = subsystem_resource->missileCount; // @0x448 resource +0x1d0 missileCount = subsystem_resource->missileCount; // @0x448 resource +0x1d0
launchVelocity = subsystem_resource->muzzleVelocity; // @0x410 (inherited ProjectileWeapon slot; was aliased "muzzleVelocity") launchVelocity = subsystem_resource->muzzleVelocity; // @0x410 (inherited ProjectileWeapon slot; was aliased "muzzleVelocity")
// per-salvo count copy + per-missile damage (write the inherited Damage fields) // per-salvo count copy + per-missile damage (write the inherited Damage fields)
this->damageData.damageAmount /= (Scalar)missileCount; // @0x3ac this[0xeb] /= missileCount this->damageData.burstCount = missileCount; // @0x3d4 this[0xf5] (was shadow "salvoCount")
this->damageData.damageAmount /= (Scalar)missileCount;
if (getenv("BT_SPEC_LOG"))
DEBUG_STREAM << "[wspec-msl] " << (GetName() ? GetName() : "?")
<< " count=" << missileCount
<< " perMissile=" << damageData.damageAmount
<< " burstModel=[n/4..n]" << "\n" << std::flush; // @0x3ac this[0xeb] /= missileCount << " burstModel=[n/4..n]" << "\n" << std::flush; // @0x3ac this[0xeb] /= missileCount
} }