Sweep the dead code off the court
EATEN_GRAB (write-only marker), ball.firstLand (written five places, read nowhere), zombies' unused VOLLEY import, three scoreboard palette fields from the pre-PNG board, the x_tin.png nothing references, and a dozen export keywords on functions no module ever imported. Kept on purpose: o_run3/o_run4.png — the SPR list excludes them so both tours run on two frames (the women's set has no 3/4 twins), per the comment at the preload list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e07196f247
commit
d847c2e4a8
7 files changed
+23
-24
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 8.3 KiB |
@@ -138,7 +138,7 @@ export const zombieDuck = out => fadeBed('zombie-mode.m4a', out); // key must ma
|
|||||||
export const menuDuck = out => fadeBed('background-music.m4a', out);
|
export const menuDuck = out => fadeBed('background-music.m4a', out);
|
||||||
|
|
||||||
let sysVoice = null;
|
let sysVoice = null;
|
||||||
export function say(text, delay = 0) { // fallback when a recorded umpire line is missing
|
function say(text, delay = 0) { // fallback when a recorded umpire line is missing
|
||||||
try {
|
try {
|
||||||
if (!sysVoice) sysVoice = speechSynthesis.getVoices().find(v => v.lang.startsWith('en-GB')) || null;
|
if (!sysVoice) sysVoice = speechSynthesis.getVoices().find(v => v.lang.startsWith('en-GB')) || null;
|
||||||
const u = new SpeechSynthesisUtterance(text);
|
const u = new SpeechSynthesisUtterance(text);
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ export const APPLAUSE_T = 4.2;
|
|||||||
// and what is left is the mound · C (EATEN_SUMMARY): the summary fades in over them still feeding.
|
// and what is left is the mound · C (EATEN_SUMMARY): the summary fades in over them still feeding.
|
||||||
// It is deliberately long. Oliver: "the movies surround and bite them, blood spills, and then the
|
// It is deliberately long. Oliver: "the movies surround and bite them, blood spills, and then the
|
||||||
// person basically drowns in the zombies" — that cannot happen in half a second.
|
// person basically drowns in the zombies" — that cannot happen in half a second.
|
||||||
export const EATEN_GRAB = 0.9, EATEN_BURST = 2.3, EATEN_SUMMARY = 3.6, EATEN_RESTART = 4.6;
|
export const EATEN_BURST = 2.3, EATEN_SUMMARY = 3.6, EATEN_RESTART = 4.6;
|
||||||
export const EATEN_FEED_R = 1.15; // m — how tight the feeding ring packs around the body
|
export const EATEN_FEED_R = 1.15; // m — how tight the feeding ring packs around the body
|
||||||
|
|
||||||
// UI accent colours, one place so the whole HUD can be re-tuned at once. Deliberately
|
// UI accent colours, one place so the whole HUD can be re-tuned at once. Deliberately
|
||||||
|
|||||||
+10
-11
@@ -29,11 +29,11 @@ export function predictLanding() { // first-bounce point, closed form — exact,
|
|||||||
// further, which is the whole fix: a shambler at the far baseline costs the same short pull as
|
// further, which is the whole fix: a shambler at the far baseline costs the same short pull as
|
||||||
// one on top of you, so the gesture always fits on the screen. The first body standing in the
|
// one on top of you, so the gesture always fits on the screen. The first body standing in the
|
||||||
// lane is the target; the cone widens with range so distant lanes stay pickable.
|
// lane is the target; the cone widens with range so distant lanes stay pickable.
|
||||||
export const pullFrac = mag => Math.max(0, Math.min(1, (mag - TUNE.pullMin) / (TUNE.pullFull - TUNE.pullMin)));
|
const pullFrac = mag => Math.max(0, Math.min(1, (mag - TUNE.pullMin) / (TUNE.pullFull - TUNE.pullMin)));
|
||||||
export const pullQuality = mag => TUNE.pullQMin + pullFrac(mag) * (1 - TUNE.pullQMin);
|
export const pullQuality = mag => TUNE.pullQMin + pullFrac(mag) * (1 - TUNE.pullQMin);
|
||||||
// pullQuality inverted: hitServe is handed a quality, not a drag, and the band it leaves behind is
|
// pullQuality inverted: hitServe is handed a quality, not a drag, and the band it leaves behind is
|
||||||
// drawn at the same weight the live preview had.
|
// drawn at the same weight the live preview had.
|
||||||
export const qualityFrac = q => Math.max(0, Math.min(1, (q - TUNE.pullQMin) / (1 - TUNE.pullQMin)));
|
const qualityFrac = q => Math.max(0, Math.min(1, (q - TUNE.pullQMin) / (1 - TUNE.pullQMin)));
|
||||||
// A pull that STOPS in the band at the top of the draw, rather than merely reaching it. See
|
// A pull that STOPS in the band at the top of the draw, rather than merely reaching it. See
|
||||||
// TUNE.perfectBand for why the old "quality == 1" test praised almost every serve.
|
// TUNE.perfectBand for why the old "quality == 1" test praised almost every serve.
|
||||||
export const pullPerfect = mag => mag >= TUNE.pullFull && mag <= TUNE.pullFull * TUNE.perfectBand;
|
export const pullPerfect = mag => mag >= TUNE.pullFull && mag <= TUNE.pullFull * TUNE.perfectBand;
|
||||||
@@ -139,7 +139,7 @@ function doHit(ch, quality, aim) {
|
|||||||
}
|
}
|
||||||
ball.g = g;
|
ball.g = g;
|
||||||
ball.vx = v.vx; ball.vy = v.vy; ball.vz = v.vz;
|
ball.vx = v.vx; ball.vy = v.vy; ball.vz = v.vz;
|
||||||
ball.lastHit = ch.side; ball.bounces = 0; ball.firstLand = null;
|
ball.lastHit = ch.side; ball.bounces = 0;
|
||||||
G.wasServe = false; // a serve volleyed back pre-bounce must not fault-check the return
|
G.wasServe = false; // a serve volleyed back pre-bounce must not fault-check the return
|
||||||
ball.pow = quality; // carried pace: zombies splatter only above zSplatQ
|
ball.pow = quality; // carried pace: zombies splatter only above zSplatQ
|
||||||
ball.kills = 0; // fresh shot: multi-kill streak restarts
|
ball.kills = 0; // fresh shot: multi-kill streak restarts
|
||||||
@@ -162,7 +162,7 @@ function doHit(ch, quality, aim) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------- serve ----
|
// ----------------------------------------------------------------- serve ----
|
||||||
function tossBall(sv) {
|
function tossBall(sv) {
|
||||||
ball.active = true; ball.bounces = 0; ball.firstLand = null; ball.collected = false;
|
ball.active = true; ball.bounces = 0; ball.collected = false;
|
||||||
// The player is right-handed: he tosses with his LEFT hand (viewer's left) and hits with the
|
// The player is right-handed: he tosses with his LEFT hand (viewer's left) and hits with the
|
||||||
// racket on the viewer's right, so the ball goes up almost over his head — a big offset either way
|
// racket on the viewer's right, so the ball goes up almost over his head — a big offset either way
|
||||||
// lands it on the wrong side of one of those two frames. The opponent is drawn from the front and
|
// lands it on the wrong side of one of those two frames. The opponent is drawn from the front and
|
||||||
@@ -171,7 +171,7 @@ function tossBall(sv) {
|
|||||||
ball.vx = 0; ball.vz = 0; ball.vy = TOSS.vy; ball.g = TUNE.gravity;
|
ball.vx = 0; ball.vz = 0; ball.vy = TOSS.vy; ball.g = TUNE.gravity;
|
||||||
G.phase = 'toss';
|
G.phase = 'toss';
|
||||||
}
|
}
|
||||||
export function serveApexY() { return TOSS.y0 + TOSS.vy * TOSS.vy / (2 * TUNE.gravity); } // ~2.95
|
function serveApexY() { return TOSS.y0 + TOSS.vy * TOSS.vy / (2 * TUNE.gravity); } // ~2.95
|
||||||
|
|
||||||
// how many 10%-pace cuts a shot may take to get over the net. 8 wasn't enough for a target
|
// how many 10%-pace cuts a shot may take to get over the net. 8 wasn't enough for a target
|
||||||
// sitting right behind the tape — that needs a near-vertical drop, so ~10 cuts (pace × 0.35).
|
// sitting right behind the tape — that needs a near-vertical drop, so ~10 cuts (pace × 0.35).
|
||||||
@@ -522,10 +522,10 @@ function startChangeover() {
|
|||||||
// that ("[0,1,2,3,4].find(...)"), so the moment the rack grew past five, a burst weapon sitting in
|
// that ("[0,1,2,3,4].find(...)"), so the moment the rack grew past five, a burst weapon sitting in
|
||||||
// slot 5..9 could never be found and never spent: beacon, flamer and rocket sat at their pickup
|
// slot 5..9 could never be found and never spent: beacon, flamer and rocket sat at their pickup
|
||||||
// count forever. One accessor, one place that knows the range.
|
// count forever. One accessor, one place that knows the range.
|
||||||
export const slotEntry = i => (i === 0 ? G.temp : G.rack[i - 1]) || null;
|
const slotEntry = i => (i === 0 ? G.temp : G.rack[i - 1]) || null;
|
||||||
export const slotId = i => slotEntry(i)?.id || (i === 0 ? 'ball' : null);
|
export const slotId = i => slotEntry(i)?.id || (i === 0 ? 'ball' : null);
|
||||||
export const slotStock = i => { const e = slotEntry(i); return e ? e.n : (i === 0 ? Infinity : 0); };
|
export const slotStock = i => { const e = slotEntry(i); return e ? e.n : (i === 0 ? Infinity : 0); };
|
||||||
export const slotOf = id => { // -1 if you are not carrying it
|
const slotOf = id => { // -1 if you are not carrying it
|
||||||
for (let i = 0; i <= RACK_MAX; i++) if (slotId(i) === id) return i;
|
for (let i = 0; i <= RACK_MAX; i++) if (slotId(i) === id) return i;
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
@@ -549,7 +549,7 @@ export function grantWeapon(id, n = WEAPONS[id].tin) {
|
|||||||
|
|
||||||
// Spend one from a slot, and hand you back plain balls when it runs dry. The temp weapon does not
|
// Spend one from a slot, and hand you back plain balls when it runs dry. The temp weapon does not
|
||||||
// leave an empty dimmed slot behind the way a rack entry does — slot 0 simply becomes BALL again.
|
// leave an empty dimmed slot behind the way a rack entry does — slot 0 simply becomes BALL again.
|
||||||
export function spendSlot(i) {
|
function spendSlot(i) {
|
||||||
const e = slotEntry(i);
|
const e = slotEntry(i);
|
||||||
if (!e) return;
|
if (!e) return;
|
||||||
if (--e.n > 0) return;
|
if (--e.n > 0) return;
|
||||||
@@ -646,7 +646,7 @@ function stockTestRack() {
|
|||||||
else if (G.rack.length < RACK_MAX) G.rack.push({ id, n: WEAPONS[id].tin });
|
else if (G.rack.length < RACK_MAX) G.rack.push({ id, n: WEAPONS[id].tin });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function tickTestMode(dt) {
|
function tickTestMode(dt) {
|
||||||
if (!G.testMode) return;
|
if (!G.testMode) return;
|
||||||
stockTestRack(); // no barrels: the rack is already full of everything they would hand you, and
|
stockTestRack(); // no barrels: the rack is already full of everything they would hand you, and
|
||||||
} // one rolling across the sandbox was just something else to look at
|
} // one rolling across the sandbox was just something else to look at
|
||||||
@@ -934,7 +934,6 @@ function onBounce() {
|
|||||||
}
|
}
|
||||||
if (G.mode !== 'tennis') return; // no lines, no faults — the umpire has other concerns
|
if (G.mode !== 'tennis') return; // no lines, no faults — the umpire has other concerns
|
||||||
if (ball.bounces === 1) {
|
if (ball.bounces === 1) {
|
||||||
ball.firstLand = { x: ball.x, z: ball.z };
|
|
||||||
const wasServe = G.wasServe; G.wasServe = false;
|
const wasServe = G.wasServe; G.wasServe = false;
|
||||||
if (wasServe) {
|
if (wasServe) {
|
||||||
if (!inServeBox(ball.x, ball.z)) { ball.active = false; fault(); }
|
if (!inServeBox(ball.x, ball.z)) { ball.active = false; fault(); }
|
||||||
@@ -1156,7 +1155,7 @@ export function dragServe(aim) {
|
|||||||
// walked the player around between shots was the confusing part, not the fire rate.
|
// walked the player around between shots was the confusing part, not the fire rate.
|
||||||
if (ball.active && G.phase !== 'toss') // the old ball flies on as a ballistic clone
|
if (ball.active && G.phase !== 'toss') // the old ball flies on as a ballistic clone
|
||||||
extras.push({ x: ball.x, y: ball.y, z: ball.z, vx: ball.vx, vy: ball.vy, vz: ball.vz, pow: ball.pow || 0.5, t: 2.5, g: ball.g, wid: ball.wid });
|
extras.push({ x: ball.x, y: ball.y, z: ball.z, vx: ball.vx, vy: ball.vy, vz: ball.vz, pow: ball.pow || 0.5, t: 2.5, g: ball.g, wid: ball.wid });
|
||||||
ball.active = true; ball.collected = false; ball.bounces = 0; ball.firstLand = null;
|
ball.active = true; ball.collected = false; ball.bounces = 0;
|
||||||
ball.x = P.x + 0.12; ball.z = P.z; ball.y = 2.2; ball.g = TUNE.gravity; // over his head, see tossBall
|
ball.x = P.x + 0.12; ball.z = P.z; ball.y = 2.2; ball.g = TUNE.gravity; // over his head, see tossBall
|
||||||
// a full pull is quality 1.0, but only a pull that STOPS at the top of the draw is praised
|
// a full pull is quality 1.0, but only a pull that STOPS at the top of the draw is praised
|
||||||
hitServe(P, pullQuality(aim.mag), aim, pullPerfect(aim.mag));
|
hitServe(P, pullQuality(aim.mag), aim, pullPerfect(aim.mag));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Camera, viewport, sprites and all drawing. Owns the crowd dots (visual-only state).
|
// Camera, viewport, sprites and all drawing. Owns the crowd dots (visual-only state).
|
||||||
|
|
||||||
import { cv, ctx } from './dom.js';
|
import { cv, ctx } from './dom.js';
|
||||||
import { TUNE, UI, EATEN_GRAB, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW } from './config.js';
|
import { TUNE, UI, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW } from './config.js';
|
||||||
import { P, O, ball, score, crowd, G, court, tour } from './state.js';
|
import { P, O, ball, score, crowd, G, court, tour } from './state.js';
|
||||||
import { predictLanding, previewServe, slotId, slotStock } from './gameplay.js';
|
import { predictLanding, previewServe, slotId, slotStock } from './gameplay.js';
|
||||||
import { zombies, gore, piles, parts, pellets, extras, shots } from './zombies.js';
|
import { zombies, gore, piles, parts, pellets, extras, shots } from './zombies.js';
|
||||||
@@ -67,7 +67,7 @@ export let W = 480, H = 270;
|
|||||||
// BOTTOM — the canvas deliberately runs to the PHYSICAL bottom edge so the court art fills the
|
// BOTTOM — the canvas deliberately runs to the PHYSICAL bottom edge so the court art fills the
|
||||||
// screen (the home indicator is a slim bar, not opaque UI). Only the interactive RACK is
|
// screen (the home indicator is a slim bar, not opaque UI). Only the interactive RACK is
|
||||||
// lifted clear of it, by SAFE.bottom below.
|
// lifted clear of it, by SAFE.bottom below.
|
||||||
export const SAFE = { top: 0, bottom: 0, topCss: 0 };
|
const SAFE = { top: 0, bottom: 0, topCss: 0 };
|
||||||
// Logical px of slack under a full draw, on top of the rack: the home indicator (~34 CSS px) plus
|
// Logical px of slack under a full draw, on top of the rack: the home indicator (~34 CSS px) plus
|
||||||
// enough that a pull ENDING near the edge is still nowhere near STARTING there. See fitViewport.
|
// enough that a pull ENDING near the edge is still nowhere near STARTING there. See fitViewport.
|
||||||
const PULL_ROOM = 30;
|
const PULL_ROOM = 30;
|
||||||
@@ -263,7 +263,7 @@ for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------ crowd ----
|
// ------------------------------------------------------------------ crowd ----
|
||||||
export function buildCrowd() {
|
function buildCrowd() {
|
||||||
crowd.dots.length = 0;
|
crowd.dots.length = 0;
|
||||||
const rows = Math.floor((proj(0, 0, 0).y - 26) / 5.5), cols = Math.ceil(W / 8);
|
const rows = Math.floor((proj(0, 0, 0).y - 26) / 5.5), cols = Math.ceil(W / 8);
|
||||||
for (let row = 0; row < rows; row++) for (let i = 0; i < cols; i++) crowd.dots.push({
|
for (let row = 0; row < rows; row++) for (let i = 0; i < cols; i++) crowd.dots.push({
|
||||||
@@ -1095,8 +1095,8 @@ const RACK_GRAB = 7; // px the TOUCH band extends above the drawn rack (below,
|
|||||||
// UPWARD instead, and only once you are actually carrying more than five: the common case is still
|
// UPWARD instead, and only once you are actually carrying more than five: the common case is still
|
||||||
// one row on the bottom edge, exactly as before.
|
// one row on the bottom edge, exactly as before.
|
||||||
const rackRows = () => (G.rack.length + 1 > RACK_ROW ? 2 : 1);
|
const rackRows = () => (G.rack.length + 1 > RACK_ROW ? 2 : 1);
|
||||||
export const rackTop = () => H - TUNE.rackH * rackRows() - RACK_BOT - SAFE.bottom;
|
const rackTop = () => H - TUNE.rackH * rackRows() - RACK_BOT - SAFE.bottom;
|
||||||
export const METER_Y = () => rackTop() - 17;
|
const METER_Y = () => rackTop() - 17;
|
||||||
function rackGeom() {
|
function rackGeom() {
|
||||||
const h = TUNE.rackH, tw = Math.min(64, (W - 4) / RACK_ROW), rw = tw * RACK_ROW;
|
const h = TUNE.rackH, tw = Math.min(64, (W - 4) / RACK_ROW), rw = tw * RACK_ROW;
|
||||||
const rows = rackRows();
|
const rows = rackRows();
|
||||||
@@ -1539,8 +1539,8 @@ export function render() {
|
|||||||
// sunk into a recessed slot — purple for the server, gold digits. Splatter adds a recessed
|
// sunk into a recessed slot — purple for the server, gold digits. Splatter adds a recessed
|
||||||
// status well (kills-to-next-point pips + weapon stock). Hard edges, no radius = retro.
|
// status well (kills-to-next-point pips + weapon stock). Hard edges, no radius = retro.
|
||||||
const splat = G.mode !== 'tennis';
|
const splat = G.mode !== 'tennis';
|
||||||
const bd = { face: '#1e5b3a', hi: '#3f9560', lo: '#0e3624', slot: '#0b2b1c', slotSvr: '#2b1a46',
|
const bd = { face: '#1e5b3a', hi: '#3f9560', lo: '#0e3624',
|
||||||
spine: '#472a70', spineHi: '#5f3d94', cream: '#f2ead6', dim: '#89a08f', gold: UI.pick, engHi: '#2c7a4f' };
|
spine: '#472a70', spineHi: '#5f3d94', cream: '#f2ead6', dim: '#89a08f', gold: UI.pick };
|
||||||
const R = (x, y, w, h, c) => { ctx.fillStyle = c; ctx.fillRect(x, y, w, h); };
|
const R = (x, y, w, h, c) => { ctx.fillStyle = c; ctx.fillRect(x, y, w, h); };
|
||||||
const ptTxt = i => score.pts[0] >= 3 && score.pts[1] >= 3
|
const ptTxt = i => score.pts[0] >= 3 && score.pts[1] >= 3
|
||||||
? (score.pts[i] === score.pts[1 - i] ? '40' : score.pts[i] > score.pts[1 - i] ? 'AD' : '40')
|
? (score.pts[i] === score.pts[1 - i] ? '40' : score.pts[i] > score.pts[1 - i] ? 'AD' : '40')
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { gore } from './zombies.js'; // runtime-only cycle (zombies imports stat
|
|||||||
export const P = { x: 1.3, z: 22.8, side: 'P', pose: 'idle', poseT: 0, swingT: -1, facing: 1, runT: 0 };
|
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 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,
|
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, flame: false,
|
active: false, lastHit: 'P', bounces: 0, collected: false, kills: 0, bomb: false, flame: false,
|
||||||
// which weapon launched the ball in flight — the stats screen files a kill under it long after
|
// which weapon launched the ball in flight — the stats screen files a kill under it long after
|
||||||
// the WEAPONS row itself is out of scope. Lives on the ball so PRISTINE resets it for free.
|
// the WEAPONS row itself is out of scope. Lives on the ball so PRISTINE resets it for free.
|
||||||
wid: 'ball' };
|
wid: 'ball' };
|
||||||
@@ -147,7 +147,7 @@ export const other = s => s === 'P' ? 'O' : 'P';
|
|||||||
export const deuceSide = () => (score.pts[0] + score.pts[1]) % 2 === 0; // even points → deuce (right) side
|
export const deuceSide = () => (score.pts[0] + score.pts[1]) % 2 === 0; // even points → deuce (right) side
|
||||||
|
|
||||||
export function setupPoint() {
|
export function setupPoint() {
|
||||||
G.phase = 'pretoss'; ball.active = false; ball.bounces = 0; ball.firstLand = null;
|
G.phase = 'pretoss'; ball.active = false; ball.bounces = 0;
|
||||||
G.swingSnaps = null; G.rallyNear = null; G.swung = false;
|
G.swingSnaps = null; G.rallyNear = null; G.swung = false;
|
||||||
if (G.mode === 'splatter') { // always your serve, from wherever you're standing
|
if (G.mode === 'splatter') { // always your serve, from wherever you're standing
|
||||||
score.server = 'P';
|
score.server = 'P';
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
// your baseline — one crossing it is a point for THEM.
|
// your baseline — one crossing it is a point for THEM.
|
||||||
// (zombies <-> gameplay is a runtime-only import cycle, same pattern as input.)
|
// (zombies <-> gameplay is a runtime-only import cycle, same pattern as input.)
|
||||||
|
|
||||||
import { TUNE, UI, COURT, VOLLEY, CONTACT, BOSS_ART, WEAPONS, BARREL_WEAPONS, woundStage, zombieH, EATEN_BURST, EATEN_SUMMARY, EATEN_FEED_R } from './config.js';
|
import { TUNE, UI, COURT, CONTACT, BOSS_ART, WEAPONS, BARREL_WEAPONS, woundStage, zombieH, EATEN_BURST, EATEN_SUMMARY, EATEN_FEED_R } from './config.js';
|
||||||
import { G, P, ball, sendBoy, setupPoint } from './state.js';
|
import { G, P, ball, sendBoy, setupPoint } from './state.js';
|
||||||
import { splat, moan, pock, thud, zap, voice, boom, swish, shriek, aww, sfx , whoosh } from './audio.js';
|
import { splat, moan, pock, thud, zap, voice, boom, swish, shriek, aww, sfx , whoosh } from './audio.js';
|
||||||
import { splatPoint, cheer, spentBall, resolveInterlude, showModal, endBossFight, aside, grantWeapon, weaponModal, endBurst } from './gameplay.js';
|
import { splatPoint, cheer, spentBall, resolveInterlude, showModal, endBossFight, aside, grantWeapon, weaponModal, endBurst } from './gameplay.js';
|
||||||
@@ -461,7 +461,7 @@ function killZombie(i, quiet) {
|
|||||||
// ---- fire. The flame ball doesn't just kill what it touches, it starts an epidemic: the kill
|
// ---- fire. The flame ball doesn't just kill what it touches, it starts an epidemic: the kill
|
||||||
// ignites its neighbours, and every burning body keeps igniting whatever it shambles past.
|
// ignites its neighbours, and every burning body keeps igniting whatever it shambles past.
|
||||||
// Read-only over zombies[] (it only sets burnT), so it is safe to call from inside a kill loop.
|
// Read-only over zombies[] (it only sets burnT), so it is safe to call from inside a kill loop.
|
||||||
export function ignite(x, z, r) {
|
function ignite(x, z, r) {
|
||||||
for (const zb of zombies) {
|
for (const zb of zombies) {
|
||||||
if (!zb || zb.burnT > 0) continue; // the boss DOES catch now — just at TUNE.bossBurnMul the rate,
|
if (!zb || zb.burnT > 0) continue; // the boss DOES catch now — just at TUNE.bossBurnMul the rate,
|
||||||
// so fire is a real answer to a big body instead of a no-op
|
// so fire is a real answer to a big body instead of a no-op
|
||||||
|
|||||||
Reference in new issue
Block a user