Phase 12: the weapon ladder — every tin opens something nastier

Deliveries cycle BOMB -> TRIPLE -> FIRE -> GUN (G.deliveries indexes the
ladder); one tin at a time, a fresh delivery replaces unspent stock. All
weapons stay one-thumb: the serve auto-consumes, zero new inputs.

- Triple serve (x3): one real serve fans two ballistic clones +-6deg (extras[]
  in zombies.js — NOT the reverted rapid-fire: each fan costs a proper serve).
  Side balls respect variant rules (wound brutes, clank off chairs, pass the boss)
- Flame ball (x3): kills on ANY contact regardless of pow, chair ignored,
  full pierce (splatter pace tax undone), ember trail, white-hot render
- Machine gun (8s): horde auto-fire as a pickup — no serving, drag steers,
  no assist, spawner keeps running, ammo bar drains on the HUD, then the
  serve loop resumes
- HUD pips per type (black/yellow/orange) at the bomb slot; flash names the
  tin ('NEW BALLS: FIRE')

Verified: ladder cycles across 5 deliveries; triple spawns 2 extras and the
fan kills flanked targets; pow-0.1 flame ball clears shambler+shield+brute in
one pass with TRIPLE KILL chaining; GUN tin arms at changeover, blocks taps,
streams pellets (kill in 5 frames), expires back to pretoss; tennis 11/12;
no weapon-flag leaks into tennis; no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-07-12 10:58:28 +02:00
1 parent 7bc26aec1c
commit 06bd24e6ea
6 files changed
+114 -22

No files matched your search

+7 -2
View File
@@ -5,7 +5,7 @@ import { HOME } from './config.js';
export const P = { x: 1.3, z: 22.8, side: 'P', pose: 'idle', poseT: 0, swingT: -1, facing: 1, runT: 0 };
export const O = { x: -1.3, z: 1.0, side: 'O', pose: 'idle', poseT: 0, swingT: -1, facing: 1, runT: 0 };
export const ball = { x: 0, y: 1, z: 20, vx: 0, vy: 0, vz: 0, g: 9.2,
active: false, lastHit: 'P', bounces: 0, firstLand: null, collected: false, kills: 0, bomb: false };
active: false, lastHit: 'P', bounces: 0, firstLand: null, collected: false, kills: 0, bomb: false, flame: false };
export const score = { pts: [0, 0], games: [0, 0], server: 'P' }; // pts index 0=P 1=O
export const crowd = { cheer: 0, dots: [] }; // dots are (re)built by render.buildCrowd
@@ -32,7 +32,12 @@ export const G = {
aiReactT: 9, // time since the player's last hit; CPU reads the shot after TUNE.aiReaction
wasServe: false, // the ball in flight is a serve (first bounce must hit the box)
splatT: 0, // time survived in splatter mode — drives the difficulty ramp
bombs: 0, // bomb-ball stock (max TUNE.bombMax); the next serve auto-consumes one
bombs: 0, // bomb-ball stock; the next serve auto-consumes one (delivery 1 of the ladder)
triples: 0, // triple-serve stock — a serve fans into three balls (delivery 2)
flames: 0, // flame-ball stock — kills on any touch, full pierce (delivery 3)
mgT: 0, // s of machine-gun time left (delivery 4) — auto-fire, no serving
mgCool: 0, // s until the next pickup-mode pellet
deliveries: 0, // tins delivered this run — indexes the weapon ladder
tinDue: false, // the rules called for new balls — deliver at the next changeover
horde: null, // active horde wave {t, spawnT, mgT} — machine-gun racket, no serving
runGames: 0, // games finished this run (either side) — the difficulty director