- Add shotgun, machine gun, gatling gun, and plasma rifle weapons with
distinct fire modes (semi-auto, auto, burst) and damage profiles
- Refactor ammo from per-weapon pools to shared pools keyed by ammo type
(9mm, shells, plasma), allowing multiple weapons to share the same pool
- Add pickup system with 11 item types: 5 weapons, 4 ammo variants, and
2 health packs, all with spritesheet frames for rendering
- Update level editor with dynamic pickup dropdown populated from rules.json
- Generalize weapon viewmodel rendering to support multiple weapon images
with per-weapon bob/sway animation
- Add cosmetic pickup animations: vertical bobbing and orbiting sparkle
effects drawn in screen space around each pickup billboard
- Bump save version to v3 to invalidate old saves with incompatible ammo
structure
- Update keyboard bindings for weapon switching (keys 1-6)
- Add comprehensive test coverage for new weapons, burst fire mechanics,
ammo pooling, and pickup behavior
- Rename weapon_gattling.png to weapon_gatling.png to fix spelling
Introduces a new "Object" entity type that blocks movement but not sight/bullets, distinct from walls and pickups:
- **Data**: New `objects` array in level JSON (`{x, y, frame}`), with `data/wolfenstein-objects.json` as the frame registry (Tall Bush, Gold Eagle)
- **Artwork**: New `objects.png` spritesheet registered in `wolfenstein-artwork.json`; placeholder texture via `paintObject()` in WolfensteinArt.js
- **Logic**: Objects stored in `state.objects`, with a derived `map.objectBlocked` Set checked only by movement collision (`isWallCell`) — raycaster/sight/bullets never read it, so objects are see-through and shoot-through by construction
- **View**: Rendered as billboard sprites in `_drawSprites` with ground-anchored positioning (bottom edge on floor) and asymptotic depth sorting that stays below the weapon viewmodel
- **Editor**: New "Object" tool category with dynamic dropdown; click open floor to place/remove (toggle), click wall is a no-op; teal square indicator on board
- **Validation**: `validateLevel` checks objects sit on open floor; save/load round-trips with graceful degradation for pre-existing saves
- **Tests**: Verifies object blocks player movement but bullets pass through