Fill the rack yourself, and roll barrels out that fill it
The rack had five hardcoded slots where the index WAS the weapon, spelled out in
five places: SLOTS, slotStock, WDESC, drawRack's three parallel arrays,
deliverTin's w+1, and bare wsel === 1|2|3 / G.weapon === 4 tests across five
files. config.WEAPONS is the one table now, G.rack holds up to four {id, n} in
the order you GATHERED them, and slot 0 stays BALL. Everything reads through
slotId/slotStock/slotEntry, so nothing else knows how the rack is stored.
A fifth weapon is always allowed, per Oliver: it rides slot 0 as G.temp until
spent, then slot 0 goes back to the infinite ball. A barrel arms on the spot and
is spent quickly, so refusing it would mean a barrel you shot did nothing. And a
spent weapon LEAVES its slot -- with gathered slots, an exhausted weapon holding
one is a quarter of the rack you can never pick up into. (The old rack kept its
empties dimmed, which was right when a slot meant "BOMB goes here".)
Four new weapons, and they are all the ONE existing pellet loop. firePellet(w)
stamps the WEAPONS row onto the round -- r, dmg, hp, pierce, boom, ignite, col,
speed, life -- so the beacon cannon, flamethrower, laser and rocket needed no new
array and no new update; the break after the first body was the only thing making
a pellet single-target. All four go through the same isBoss branch, which is why
none can silently no-op on a boss the way three of five once did. Measured:
gun/beacon/laser/rocket reach past 16 m, the flamer is a ~6 m cone that ignites.
G.mgT stays the mode timer for all of them, so the eighteen !(G.mgT > 0) guards
across five files did not have to change. kind:'burst' auto-fires at its own rate
for len seconds; kind:'shot' holds the same braced stance and fires one per tap.
The barrels reuse the ball machine's shape: a rolling, shootable non-body. All
three of the registrations that fail silently are done -- blocksClear (loot must
not gate the hand-clear), the contact guard (furniture cannot eat you), and
hitR/GORE_MUL/zombieH. It scores nothing.
The pink had to become procedural. The chroma key deletes every pixel where red
and blue both beat green by 40, so a magenta drum and a magenta laser pistol both
came back as hollow outlines -- 19% and 15% solid against 50-56% for the icons in
other colours. The drum is grey steel with hazard chevrons and every bit of its
pink is the halo drawBarrel paints; the laser went electric blue. Both are solid
now (92% and 58%), and the rule is written down in HANDOFF.
tinTriples 3 -> 10 as asked, and the four dead TUNE ammo constants are gone --
nothing read them once the table landed, which is a panel value you can tune all
day for no effect.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4cda6bde76
commit
25f915f236
16 files changed
+385
-97
No files matched your search
@@ -4,9 +4,9 @@
|
||||
|
||||
import { cv } from './dom.js';
|
||||
import { audio, pock } from './audio.js';
|
||||
import { TUNE } from './config.js';
|
||||
import { TUNE, WEAPONS } from './config.js';
|
||||
import { G, score } from './state.js';
|
||||
import { keyPressed, dragServe, selectWeapon, serveToss, pullQuality, dismissModal } from './gameplay.js';
|
||||
import { keyPressed, dragServe, selectWeapon, serveToss, pullQuality, dismissModal, slotId } from './gameplay.js';
|
||||
import { rackHit } from './render.js';
|
||||
import { togglePanel } from './panel.js';
|
||||
|
||||
@@ -45,10 +45,14 @@ export function takeFlickAim(maxAgeMs = 450) {
|
||||
// (G.aim, drawn by render); release fires the serve there, dragging back home cancels.
|
||||
// EVERY phase of splatter play, so the drag never silently turns into something else. The old
|
||||
// "drag walks the player" mode between shots was invisible state and read as a bug.
|
||||
// a weapon you UNLOAD (burst or shot) rather than serve — it takes the tap directly, so the
|
||||
// slingshot reticle must stay out of its way. Was `G.weapon !== 4` back when slot 4 was always GUN.
|
||||
const isGunLike = () => { const w = WEAPONS[slotId(G.weapon)]; return !!w && (w.kind === 'burst' || w.kind === 'shot'); };
|
||||
|
||||
const canAimServe = () =>
|
||||
!G.modal // the world is frozen behind a popup — the thumb that clears it must not draw a bow
|
||||
&& G.mode === 'splatter' // every phase of it; 'eaten' is its own mode and never gets here
|
||||
&& score.server === 'P' && G.weapon !== 4 // GUN pops on tap, no reticle
|
||||
&& score.server === 'P' && !isGunLike() // a gun-like weapon pops on tap, no reticle
|
||||
&& !G.interlude && !G.horde && !(G.mgT > 0) && !G.changeover; // the duel serves like tennis: no reticle
|
||||
|
||||
let steerPX = null; // live absolute finger x (-1..1 across the canvas) — machine-gun steering reads it
|
||||
|
||||
Reference in new issue
Block a user