diff --git a/game/reconstructed/btl4galm.cpp b/game/reconstructed/btl4galm.cpp index 162f7bb..501dedb 100644 --- a/game/reconstructed/btl4galm.cpp +++ b/game/reconstructed/btl4galm.cpp @@ -163,7 +163,8 @@ static const int kBTQuadModeMask[12] = { 0x1,0x1,0x1,0x1, 0x20,0x20,0x20,0x20, 0 static const int kBTEngModeMask[12] = { 0x2,0x4,0x8,0x10, 0x40,0x80,0x100,0x200, 0x800,0x1000,0x2000,0x4000 }; static const int kBTQuadLamp[12] = { 0xF,0xD,0xB,0x9, 0x27,0x25,0x23,0x21, 0x7,0x5,0x3,0x1 }; static const int kBTEngBankTop[12] = { 0xF,0xF,0xF,0xF, 0x27,0x27,0x27,0x27, 0x7,0x7,0x7,0x7 }; -static const int kBTCondenserLamp[6] = { 0x7, 0x2F,0x2E,0x2D,0x2B,0x2A }; // [condenserNumber] +// (the per-condenser lamp table that used to live here is retired: condenser N +// resolves through BTFixedLampOf(N-1), the same six cooling-loop lamps. #98) static const int kBTPlacementLamp[5] = { 0x29, 0x1A,0x1B,0x1C,0x1D }; // [auxScreenPlacement] // @@ -287,9 +288,25 @@ void { if (the_condition == 2) // CoolantLeaking { + // + // #98 -- "I'm getting leaks but no indicators" / "the display + // buttons aren't ALWAYS flashing on leaking components". + // + // condenserNumber is 1-BASED (verified live: 'Condenser6' reports 6), + // which the old table's own comment said -- but the guard was + // `n >= 0 && n < 6`, a 0-based bound. Condenser 6 was therefore + // REJECTED outright and could never annunciate, and the table it + // indexed was missing 0x2C, so condensers 4 and 5 flashed the NEXT + // loop's button instead of their own. Three of six correct, one + // silent, two lying -- exactly the "sometimes" players reported. + // + // Condenser N drives cooling-loop N, whose six lamps are the same + // ones the coolingLoop1..6 codes resolve to, so use that verified + // map rather than a second, partly-wrong copy of it. + // int n = BTCondenserNumber(the_subsystem); - if (n >= 0 && n < 6) - lamp_id = kBTCondenserLamp[n]; + if (n >= 1 && n <= 6) + lamp_id = BTFixedLampOf(n - 1); // loop N -> its own button } } else if (BTSubsystemIsGenerator(the_subsystem)) @@ -331,6 +348,21 @@ void if (lamp_id < 0) { + // DIAGNOSTIC (#98): this is the SILENT path -- the item matched the + // condition but no lamp could be resolved for this subsystem, so nothing + // flashes and nothing was logged. Players see "leaking but no + // indicator". Name the subsystem and why it fell through, so the + // mapping gap is visible in a field log instead of being invisible. + if (BTLampLog()) + DEBUG_STREAM << "[galarm] condition " << (int)the_condition + << " code 0x" << std::hex << lamp_code << std::dec + << " sub '" << (the_subsystem && the_subsystem->GetName() + ? the_subsystem->GetName() : "?") + << "' -> NO LAMP RESOLVED (condenser=" << BTSubsystemIsCondenser(the_subsystem) + << " condenserNumber=" << (BTSubsystemIsCondenser(the_subsystem) + ? BTCondenserNumber(the_subsystem) : -1) + << " generator=" << BTSubsystemIsGenerator(the_subsystem) + << ")" << std::endl << std::flush; return; } diff --git a/scratchpad/night8/leaklamp.sh b/scratchpad/night8/leaklamp.sh new file mode 100644 index 0000000..74962d6 --- /dev/null +++ b/scratchpad/night8/leaklamp.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# #98: which leaking components actually FLASH their panel button? +# +# Players: "the display buttons aren't always flashing or lighting up on leaking +# components" (Oracle), "I'm getting leaks but no indicators" (Lynx), "I am +# getting indicators sometimes" (Sauron). Intermittent, not simply unwired. +# +# The chain is: HeatSink::GetStatusFlags raises bit 0x4 (CoolantLeaking) when +# coolantActive && HeatModelActive -> MechTech::TechnicalAssistance sees the bit +# CHANGE and calls ReportStatusSet -> GaugeAlarmManager::Activate -> the +# per-item lamp resolve in btl4galm.cpp. +# +# BT_LAMP_LOG prints all three stages: +# [techstat] condition 2 SET / CLEARED -- the edge the alarm rides +# [galarm] ... -> lamp 0x.. FLASH -- resolved and flashing +# [galarm] ... -> NO LAMP RESOLVED (...) -- matched but no lamp (NEW) +# +# Damage the mech steadily so heat subsystems take crits and start leaking. +set -x +. /c/git/bt411/scratchpad/night6/bench_common.sh +cd /c/git/bt411/content || exit 1 +taskkill //F //IM btl4.exe > /dev/null 2>&1 +sleep 2 +sed "s/^map=.*/map=grass/; s/^time=.*/time=day/" MP.EGG > LEAK.EGG + +LOG=leaklamp_${1:-post}.log +rm -f "$LOG" + +# Self-damage keeps crits landing on the heat family; autofire keeps heat LOAD +# up, which is what coolantDraw (= zoneDamage x heatLoad) scales with. +BT_LAMP_LOG=1 BT_COOL_LOG=1 BT_DMG_LOG=1 \ +BT_SPAWN_ENEMY=1 BT_AUTOFIRE=1 BT_AF_PERIOD=2 \ +BT_SELF_DAMAGE=4 BT_SELF_DAMAGE_ZONE=${2:-dz_rarm} \ + bt_launch "$LOG" LEAK.EGG 0x03 + +sleep 150 +taskkill //F //IM btl4.exe > /dev/null 2>&1 +sleep 2 + +echo "=== coolant-leak status edges (condition 2) ===" +grep -E "^\[techstat\].*condition 2" "$LOG" | sort | uniq -c | sort -rn | head -15 +echo "=== lamp resolution ===" +grep -E "^\[galarm\]" "$LOG" | sed 's/[0-9a-fx]\{3,\}/N/g' | sort | uniq -c | sort -rn | head -12