Doom-style weapon audio batch + remove footsteps
- Regenerated all 13 weapon fire one-shots and 4 weapon loops via the audio specialist (ElevenLabs) with a 1993 Doom style brief: chunky, bass-heavy, crunchy 90s FPS sounds - New clips wired into SfxBank: ui_active, ui_active_empty (active items), ui_curse (legendary pickups, replaces the normal item jingle), plr_revive (Second Skin revive) - Footstep system removed entirely (never worked right): Sfx.footstep, 8 plr_step* samples and bank entries, player.js call site, smoke test block - Cache v=42
This commit is contained in:
1 parent
4dad22d087
commit
64ac53434b
36 files changed
+37
-80
No files matched your search
+2
-2
@@ -176,9 +176,9 @@ function giveItem(iid) {
|
||||
spawnText(p.x, p.y - 14, 'UPGRADED!', '#ffd060');
|
||||
} else {
|
||||
addToast(item.name, item.desc);
|
||||
spawnText(p.x, p.y - 14, item.name.toUpperCase(), '#c9a227');
|
||||
spawnText(p.x, p.y - 14, item.name.toUpperCase(), ITEM_RARITY[item.rarity].color);
|
||||
}
|
||||
Sfx.item();
|
||||
if (item.rarity === 'legendary') Sfx.curse(); else Sfx.item();
|
||||
refreshOrbitals(p);
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -5,7 +5,7 @@ function initPlayer() {
|
||||
x: W / 2, y: H / 2, r: 20,
|
||||
hp: 6, shieldHp: 0,
|
||||
aim: 0, bodyFacing: 0, fireT: 0, charge: 0, invT: 0, frenzyT: 0,
|
||||
step: 0, stepTick: 0, moveBlend: 0, recoil: 0, muzzleT: 0,
|
||||
step: 0, moveBlend: 0, recoil: 0, muzzleT: 0,
|
||||
animT: 0, attackT: 0, actionT: 0, hitT: 0, deathT: 0,
|
||||
weapon: { id: 'bonepopper', ammo: Infinity },
|
||||
holstered: null, // a special weapon set aside while the pistol is out
|
||||
@@ -76,15 +76,11 @@ function updatePlayer(dt) {
|
||||
p.x += (mx / len) * spd * dt;
|
||||
p.y += (my / len) * spd * dt;
|
||||
p.step += dt * 9 * Math.min(st.speedMul, 1.8);
|
||||
const stepTick = Math.floor(p.step / Math.PI);
|
||||
if (stepTick !== p.stepTick && p.hp > 0) Sfx.footstep(p.moveBlend, onGore(p.x, p.y));
|
||||
p.stepTick = stepTick;
|
||||
}
|
||||
else {
|
||||
// Finish on a planted contact frame instead of freezing halfway through a stride.
|
||||
const planted = Math.round(p.step / Math.PI) * Math.PI;
|
||||
p.step = lerp(p.step, planted, clamp(dt * 10, 0, 1));
|
||||
p.stepTick = Math.round(p.step / Math.PI);
|
||||
}
|
||||
p.moveBlend = lerp(p.moveBlend, mx || my ? 1 : 0, clamp(dt * 12, 0, 1));
|
||||
p.recoil = Math.max(0, p.recoil - dt * 7);
|
||||
@@ -339,7 +335,7 @@ function hurtPlayer(dmg, ang, attacker) {
|
||||
addShake(10);
|
||||
spawnText(p.x, p.y - 20, 'SECOND SKIN', '#e2472f');
|
||||
addToast('SECOND SKIN', 'you refuse to die — once per floor');
|
||||
Sfx.shieldUp();
|
||||
Sfx.revive();
|
||||
return;
|
||||
}
|
||||
p.hp = 0;
|
||||
|
||||
@@ -3,12 +3,12 @@ const Sfx = {
|
||||
ctx: null, master: null, comp: null, glue: null, limiter: null, muted: false,
|
||||
mixBus: null, musicBus: null, musicMute: null, duckGain: null, saturators: {},
|
||||
buses: {}, active: [], procedural: [], lastPlayed: new Map(), currentWeaponLoop: null,
|
||||
footstepN: 0, fleshN: 0, wallN: 0, goreN: 0,
|
||||
fleshN: 0, wallN: 0, goreN: 0,
|
||||
lastPunch: -999, lastPunchLevel: 0,
|
||||
maxVoices: 24,
|
||||
cooldowns: {
|
||||
hit: 0.035, crit: 0.07, ricochet: 0.05, wallHit: 0.045, sawHit: 0.09, gem: 0.025,
|
||||
enemyDie: 0.04, goreBurst: 0.055, footstep: 0.10, lifesteal: 0.12,
|
||||
enemyDie: 0.04, goreBurst: 0.055, lifesteal: 0.12,
|
||||
loop_wpnloop_bile: 0.12, loop_wpnloop_cauterizer: 0.12,
|
||||
loop_wpnloop_redhand: 0.11, loop_wpnloop_spinaltap_charge: 0.12,
|
||||
},
|
||||
@@ -302,36 +302,6 @@ const Sfx = {
|
||||
this.blip(260, .14, 'sine', .2, 180, 'voices');
|
||||
},
|
||||
playerDeath() { this.stopAllLoops(); if (this.sample('plr_death', 'voices', null, 1, 'playerDeath')) return; this.thump(80, .65, .7, 25, 'voices'); this.noise(.7, .45, 350, 'voices'); },
|
||||
footstep(strength, wet) {
|
||||
if (!this.canPlay('footstep')) return;
|
||||
this.footstepN = (this.footstepN % 4) + 1;
|
||||
const dryName = 'plr_step' + this.footstepN;
|
||||
const wanted = wet ? 'plr_step_wet' + this.footstepN : dryName;
|
||||
const force = strength === undefined ? 1 : clamp(strength, .55, 1);
|
||||
const side = this.footstepN % 2 ? .96 : 1.04;
|
||||
const gain = .66 * force * side;
|
||||
let sampled = false;
|
||||
if (typeof SfxBank !== 'undefined' && SfxBank.buffers.has(wanted)) {
|
||||
this.enforceVoiceLimit();
|
||||
sampled = SfxBank.play(wanted, this.output('impacts', null), {
|
||||
gain: gain * rand(.96, 1.04), rate: rand(.965, 1.035),
|
||||
});
|
||||
} else if (typeof SfxBank !== 'undefined') {
|
||||
SfxBank.want(wanted);
|
||||
// Keep the gait audible while a wet variant is still decoding.
|
||||
if (wet && SfxBank.buffers.has(dryName)) {
|
||||
this.enforceVoiceLimit();
|
||||
sampled = SfxBank.play(dryName, this.output('impacts', null), { gain: gain * .9, rate: rand(.97, 1.03) });
|
||||
}
|
||||
}
|
||||
this.punch(.18 * force * side);
|
||||
if (!sampled) {
|
||||
if (wet) {
|
||||
this.noise(.08, .17 * force, 360, 'impacts');
|
||||
this.noise(.025, .05 * force, 1500, 'impacts', null, true);
|
||||
} else this.noise(.055, .13 * force, 420, 'impacts');
|
||||
}
|
||||
},
|
||||
ricochet(pos) { if (this.sample('imp_ricochet', 'impacts', pos, .5, 'ricochet')) return; this.blip(rand(1400, 1900), .045, 'triangle', .12, -500, 'impacts', pos); },
|
||||
|
||||
wallHit(pos) {
|
||||
@@ -376,8 +346,10 @@ const Sfx = {
|
||||
ammo() { this.ui('ammo', () => { this.click(.14, 1600, 'ui'); this.blip(520, .08, 'square', .12, -80, 'ui'); }); },
|
||||
weapon() { this.ui('weapon', () => { this.thump(120, .14, .4, 50, 'ui'); this.blip(300, .1, 'square', .25, 200, 'ui'); this.blip(450, .12, 'square', .2, 250, 'ui'); }); },
|
||||
item() { this.ui('item', () => { this.thump(100, .2, .4, 45, 'ui'); this.blip(350, .15, 'triangle', .3, 150, 'ui'); this.blip(525, .2, 'triangle', .25, 200, 'ui'); }); },
|
||||
active() { this.thump(140, .22, .5, 60, 'ui'); this.blip(700, .12, 'sawtooth', .28, 500, 'ui'); this.noise(.1, .14, 2400, 'ui', null, true); },
|
||||
activeEmpty() { this.blip(220, .12, 'square', .18, -90, 'ui'); },
|
||||
active() { this.ui('active', () => { this.thump(140, .22, .5, 60, 'ui'); this.blip(700, .12, 'sawtooth', .28, 500, 'ui'); this.noise(.1, .14, 2400, 'ui', null, true); }); },
|
||||
activeEmpty() { this.ui('active_empty', () => this.blip(220, .12, 'square', .18, -90, 'ui')); },
|
||||
curse() { this.ui('curse', () => { this.thump(60, .5, .5, 30, 'ui'); this.blip(180, .4, 'sawtooth', .22, -60, 'ui'); }); },
|
||||
revive() { if (this.sample('plr_revive', 'voices', null, .85, 'revive')) return; this.blip(500, .3, 'sine', .25, 300, 'ui'); this.thump(100, .3, .4, 50, 'ui'); },
|
||||
levelup() { this.ui('levelup', () => { this.blip(400, .12, 'square', .25, 200, 'ui'); setTimeout(() => this.blip(600, .12, 'square', .25, 200, 'ui'), 100); setTimeout(() => this.blip(800, .2, 'square', .25, 200, 'ui'), 200); }); },
|
||||
perk() { this.ui('perk', () => this.blip(500, .1, 'square', .25, 300, 'ui')); },
|
||||
menu() { this.ui('menu', () => this.blip(620, .055, 'square', .11, 120, 'ui')); },
|
||||
|
||||
+5
-9
@@ -79,6 +79,10 @@ const SfxBank = {
|
||||
ui_perk: 'ui_perk.mp3',
|
||||
ui_stairs: 'ui_stairs.mp3',
|
||||
ui_menu: 'ui_menu.mp3',
|
||||
ui_active: 'ui_active.mp3',
|
||||
ui_active_empty: 'ui_active_empty.mp3',
|
||||
ui_curse: 'ui_curse.mp3',
|
||||
plr_revive: 'plr_revive.mp3',
|
||||
|
||||
imp_crit: 'imp_crit.mp3',
|
||||
imp_ricochet: 'imp_ricochet.mp3',
|
||||
@@ -88,14 +92,6 @@ const SfxBank = {
|
||||
plr_death: 'plr_death.mp3',
|
||||
plr_shield_break: 'plr_shield_break.mp3',
|
||||
plr_shield_up: 'plr_shield_up.mp3',
|
||||
plr_step1: 'plr_step1.mp3',
|
||||
plr_step2: 'plr_step2.mp3',
|
||||
plr_step3: 'plr_step3.mp3',
|
||||
plr_step4: 'plr_step4.mp3',
|
||||
plr_step_wet1: 'plr_step_wet1.mp3',
|
||||
plr_step_wet2: 'plr_step_wet2.mp3',
|
||||
plr_step_wet3: 'plr_step_wet3.mp3',
|
||||
plr_step_wet4: 'plr_step_wet4.mp3',
|
||||
imp_flesh1: 'imp_flesh1.mp3',
|
||||
imp_flesh2: 'imp_flesh2.mp3',
|
||||
imp_flesh3: 'imp_flesh3.mp3',
|
||||
@@ -115,7 +111,7 @@ const SfxBank = {
|
||||
if (this.buffers.has(name) || this.pending.has(name) || this.failed.has(name)) return;
|
||||
const file = this.FILES[name];
|
||||
if (!file || !this.ctx || typeof fetch !== 'function') return;
|
||||
const job = fetch('/assets/sfx/' + encodeURIComponent(file) + '?v=41')
|
||||
const job = fetch('/assets/sfx/' + encodeURIComponent(file) + '?v=42')
|
||||
.then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.arrayBuffer(); })
|
||||
.then(bytes => this.ctx.decodeAudioData(bytes))
|
||||
.then(buffer => this.buffers.set(name, this.trim(buffer)))
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ const Sprites = {
|
||||
const img = new Image();
|
||||
img.onload = () => { this.imgs[name] = img; if (--pending === 0) G.imagesLoaded = true; };
|
||||
img.onerror = () => { if (--pending === 0) G.imagesLoaded = true; };
|
||||
img.src = 'assets/' + name + '.png?v=41';
|
||||
img.src = 'assets/' + name + '.png?v=42';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in new issue
Block a user