Normalize ammo economy: per-weapon refill, stream drain, behavior fixes
- Every special weapon gets an explicit 'refill' (units per ammo pickup,
tuned so one pickup funds ~10 kills) replacing the ammoRefillFraction
log2 heuristic and ammoWeight overrides
- Bile Blunderbuss + The Cauterizer join Red Right Hand as time-denominated
stream weapons ('drain' per second) instead of per-shot cost
- Sawblades ricochet through enemies (bounce fix), traps catch 3 victims,
lobbed projectiles arc overhead and always trigger at the target point
(Flesh Masher / Trap Queen / Swarm Jar payloads now actually deploy)
- Boss rooms stock one ammo on entry and drop one guaranteed on death
- Cauterizer burn trimmed (2.2s x2 -> 1.5s x0.8), bile acid pools trimmed
(3.5s x1.5 -> 2.5s x0.8), Marrow Draught now covers stream drain
- New tools/ammo_sim.js calibrates every weapon into the 8-13 kills/refill
band (all 15 pass); smoke test guards the ammo structure
- v0.3.0, cache bump v=44
This commit is contained in:
1 parent
7d33e36c1e
commit
d9eae34df4
18 files changed
+380
-101
No files matched your search
+4
-12
@@ -16,17 +16,9 @@ function spawnGems(x, y, value) {
|
||||
}
|
||||
|
||||
|
||||
// Ammo drops preserve useful trigger time: low-damage rapid weapons receive
|
||||
// a larger share, while heavy multi-pellet shots receive fewer rounds.
|
||||
function ammoRefillFraction(w) {
|
||||
const effectiveDamage = Math.max(1, (w.dmg || 1) * (w.pellets || 1));
|
||||
const interval = Math.max(0.05, w.interval ?? 0.3);
|
||||
const damageWeight = Math.log2(effectiveDamage / 8);
|
||||
const rateWeight = Math.log2(interval / 0.3);
|
||||
// Heavy, slow attacks push the fraction down; light, rapid attacks push it up.
|
||||
const heaviness = clamp((damageWeight + rateWeight) / 4, -1, 1);
|
||||
return clamp(0.62 - heaviness * 0.28, 0.30, 0.88) * (w.ammoWeight || 1) * AMMO_REFILL_SCALE;
|
||||
}
|
||||
// Ammo pickups hand back each weapon's authored `refill` (see WEAPONS), tuned
|
||||
// so one pickup funds roughly ten kills. Magazine size (`ammo`) is a separate
|
||||
// feel dial; the economy dial lives on `refill`.
|
||||
|
||||
// room-clear reward burst (weapons come from bosses / item rooms, not room clears)
|
||||
function spawnRoomReward(x, y, floor) {
|
||||
@@ -87,7 +79,7 @@ function collectPickup(k) {
|
||||
for (const inst of carried) {
|
||||
const def = WEAPONS[inst.id];
|
||||
const cap = def.ammo * 1.5;
|
||||
const wanted = Math.max(1, Math.ceil(def.ammo * ammoRefillFraction(def) * p.stats.ammoPickupMul));
|
||||
const wanted = Math.max(1, Math.ceil((def.refill || 1) * p.stats.ammoPickupMul));
|
||||
const add = Math.max(0, Math.min(wanted, cap - inst.ammo));
|
||||
inst.ammo += add;
|
||||
total += add;
|
||||
|
||||
Reference in new issue
Block a user