#!/usr/bin/env bash # ========================================================================= # SCORING verify -- the type-0 interceptor (@004bffa0) restored. # # Composition lifted from night12/scorekill.sh, which is known to produce a # clean cross-node kill: A (madcat, shooter) zone-walk-hammers B (loki, # spinner) at 90u until B dies. # # THE A/B IS READABLE IN ONE RUN, because the old behaviour left a receipt: # BEFORE every inflicted report hit ScoreMessageHandler's type-0 arm and # tripped Verify "ScoreMessageHandler should not be given # DamageInflictedScoreMessages!" -- night12's bench listed those # Verify prints as an expected PASS signal. # AFTER the interceptor routes type 0 to ScoreInflictedMessageHandler, so # those Verify prints must be GONE and matchlog SCORE type=0 rows # with non-zero awards must appear instead. # # Chart cross-check (original manual, via Lynx): "+1 each damage point scored # on opponent's armor". The handler scales by tonnage ratio and the role's # damageInflictedModifier, so award != damage exactly -- but it must TRACK # damage, not sit at zero, and must be NEGATIVE for self-damage. # ========================================================================= set -x . /c/git/bt411/scratchpad/night6/bench_common.sh cd /c/git/bt411/content || exit 1 bt_assert_player_env taskkill //F //IM btl4.exe > /dev/null 2>&1 sleep 2 rm -f sv_a.log sv_b.log sv_relay.log matchlog_*.txt bt_expert_egg MP.EGG SV.EGG sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/" SV.EGG python - << 'EOF' lines = open('SV.EGG').read().splitlines(True) n = 0 for i, l in enumerate(lines): if l.startswith('vehicle='): n += 1 lines[i] = 'vehicle=madcat\n' if n == 1 else 'vehicle=loki\n' open('SV.EGG', 'w').writelines(lines) print('vehicles set:', n) EOF ( export BT_DMG_LOG=1 BT_DEATH_LOG=1 BT_MP_LOG=1 BT_MATCHLOG=1 BT_SCORE_LOG=1 bt_launch sv_b.log SV.EGG 0x0C -net 1601 ) sleep 2 ( export BT_ZONE_WALK=8 BT_WALK_ZONES=dz_ldleg export BT_GOTO=enemy BT_GOTO_STOP=90 BT_KEY_NOFOCUS=1 export BT_DMG_LOG=1 BT_DEATH_LOG=1 BT_MP_LOG=1 BT_MATCHLOG=1 BT_SCORE_LOG=1 bt_launch sv_a.log SV.EGG 0x03 -net 1501 ) sleep 5 python ../tools/btconsole.py SV.EGG 127.0.0.1:1501 127.0.0.1:1601 > sv_relay.log 2>&1 & RELAY=$! sleep 400 kill $RELAY 2>/dev/null sleep 3 bt_kill_ours sleep 2 taskkill //F //IM btl4.exe > /dev/null 2>&1 sleep 3 echo "=================== SCORING VERIFY ===================" echo "--- 0. did combat happen at all? (if 0 hits the run is VOID) ---" echo -n "damage rows on victim B : "; grep -ac "dmghit\|DMG" sv_b.log echo echo "--- 1. THE OLD SYMPTOM: type-0 rejections (must be ZERO now) ---" echo -n "'should not be given DamageInflictedScore' Verify prints: " cat sv_a.log sv_b.log | grep -ac "should not be given DamageInflictedScore" echo echo "--- 2. THE FIX: inflicted score rows (matchlog SCORE type=0) ---" echo -n "type=0 rows: "; cat matchlog_*.txt 2>/dev/null | grep -ac "type=0" cat matchlog_*.txt 2>/dev/null | grep -a "type=0" | head -8 echo echo "--- 3. award vs damage: does the credit TRACK damage? ---" python - << 'EOF' import glob, re aw = [] for fn in glob.glob('matchlog_*.txt'): for line in open(fn, errors='replace'): m = re.search(r'type=0 award=(-?[\d.]+) total=(-?[\d.]+)', line) if m: aw.append((float(m.group(1)), float(m.group(2)))) if not aw: print(' NO type=0 rows -- interceptor did not fire') else: pos = [a for a, t in aw if a > 0] neg = [a for a, t in aw if a < 0] print(' rows=%d positive=%d negative(self)=%d' % (len(aw), len(pos), len(neg))) print(' award range: %.2f .. %.2f running total ends at %.2f' % (min(a for a, t in aw), max(a for a, t in aw), aw[-1][1])) EOF echo echo "--- 4. kill path un-regressed (type=2) + respawn ---" echo -n "type=2 kill rows: "; cat matchlog_*.txt 2>/dev/null | grep -ac "type=2" cat matchlog_*.txt 2>/dev/null | grep -a "type=2" | head -3 echo -n "victim death cycles: "; grep -ac "death cycle START" sv_b.log