feat: dash ability; ammo pressure scaling, full-HP hearts, muzzle alignment, holstered debug ammo
- Shift dash: 0.45*v*0.6 instant burst then 0.6s of 50% slow (net 95% of walking distance); slow doubles as cooldown, no dash while idle/slowed. - Generic ammo refills scale with the live pressure dial at 80% of the HP multiplier via ammoPressureMul(). - Hearts at full HP stay on the floor (magnet ignores them) instead of converting to score. - Muzzle audit: flame FX and pellets share one right-hand origin, Spinal Tap beam starts at the muzzle, saw flash suppressed (blade sparks are the effect). - Debug REFILL/INF AMMO and the ammo row now cover a spent special holstered behind the Bone Popper. - Sfx.duck() defaults its args; a no-arg call crashed the loop with a non-finite AudioParam value (found via the dash E2E).
This commit is contained in:
1 parent
684a54f5ad
commit
4b9e4a1e97
6 files changed
+49
-24
No files matched your search
+10
-3
@@ -211,6 +211,13 @@ function dbgRenderPlayer(ctx, b) {
|
||||
dbgText(ctx, 'Mutating this tab taints the run — best score will not be saved.', b.x, y, '#7d5a58', hfont(8));
|
||||
}
|
||||
|
||||
function debugRefillAmmo() {
|
||||
const p = G.player;
|
||||
for (const inst of [p.weapon, p.holstered]) {
|
||||
if (inst && inst.ammo !== Infinity) inst.ammo = WEAPONS[inst.id].ammo;
|
||||
}
|
||||
}
|
||||
|
||||
function dbgRenderWeapons(ctx, b) {
|
||||
const p = G.player;
|
||||
const lw = 320;
|
||||
@@ -232,12 +239,12 @@ function dbgRenderWeapons(ctx, b) {
|
||||
p.charge = 0; p.fireT = 0;
|
||||
addToast('DEBUG', WEAPONS[wid].name);
|
||||
});
|
||||
act('REFILL AMMO', () => { if (p.weapon.ammo !== Infinity) p.weapon.ammo = WEAPONS[p.weapon.id].ammo; });
|
||||
act('REFILL AMMO', () => { debugRefillAmmo(); });
|
||||
act('HOLSTER CURRENT', () => { if (p.weapon.id !== 'bonepopper') { p.holstered = p.weapon; p.weapon = { id: 'bonepopper', ammo: Infinity }; } });
|
||||
act('DROP AT CURSOR', () => { const c = dbgCursor(); spawnPickup('weapon', c.x, c.y, { wid }); });
|
||||
act('SPAWN ITEM PEDESTAL', () => { const c = dbgCursor(); spawnItemPedestal(c.x, c.y, null, 'room'); });
|
||||
ay += 4;
|
||||
dbgNumRow(ctx, 'ammo', ax, ay, b.w - lw - 20, () => (p.weapon.ammo === Infinity ? 999 : p.weapon.ammo), v => { debugTaint(); if (p.weapon.ammo !== Infinity) p.weapon.ammo = Math.max(0, v); }, 10, 0, 999);
|
||||
dbgNumRow(ctx, 'ammo', ax, ay, b.w - lw - 20, () => (p.weapon.ammo !== Infinity ? p.weapon.ammo : (p.holstered && p.holstered.ammo !== Infinity ? p.holstered.ammo : 999)), v => { debugTaint(); const t = p.weapon.ammo !== Infinity ? p.weapon : (p.holstered && p.holstered.ammo !== Infinity ? p.holstered : null); if (t) t.ammo = Math.max(0, v); }, 10, 0, 999);
|
||||
dbgText(ctx, 'Equip swaps the live weapon; the old one goes to the holster unless it was the Bone Popper.', ax, ay + 32, '#6f5c58', hfont(8));
|
||||
}
|
||||
|
||||
@@ -528,7 +535,7 @@ const DEBUG_PAGES = [
|
||||
// ---- top-level update / draw ----
|
||||
function updateDebug() {
|
||||
// infinite-ammo upkeep (also runs while pinned so live play benefits)
|
||||
if (G.debugFlags.infAmmo && G.player && G.player.weapon.ammo !== Infinity) G.player.weapon.ammo = WEAPONS[G.player.weapon.id].ammo;
|
||||
if (G.debugFlags.infAmmo && G.player) for (const inst of [G.player.weapon, G.player.holstered]) if (inst && inst.ammo !== Infinity) inst.ammo = WEAPONS[inst.id].ammo;
|
||||
|
||||
// wall-clock fps counter for the stats tab (independent of timescale/freeze)
|
||||
DBG.fpsFrames++;
|
||||
|
||||
Reference in new issue
Block a user