Phase 17/18 closure: stockpile filter UI + day summary + atmospheric audio

Three-agent fan-out (gdscript-refactor x3) closing deferred polish:

- Stockpile chip filter UI: new StockpilePanel (layer 18, right-anchored,
  mirrors WorkbenchPanel). 5-priority segmented control + 21-chip 4-col
  filter grid using Item.ALL_TYPES; wildcard (empty accepted_types) shows
  all chips checked with 'All' hint, first explicit pick switches to
  explicit-list mode. Selection chain extended to pawn → workbench →
  stockpile with mutual exclusion. 12 ui.stockpile.* + 13 item.* keys.

- DaySummaryCard: layer-19 modal auto-opens at dusk→night via day_ended,
  auto-pauses sim, shows day+season header, weather row, stats grid with
  green/yellow/red tension bar, Continue dismiss + backdrop tap.
  Settings 'Show end-of-day summary' toggle persists via GameState.

- Atmospheric audio: rain ambient loop (Cozy Melodies Pack 6) on
  weather_changed rain/storm with 0.5s fade-out on clear; thunder sting
  (Magic and Spells 6) on rain→storm transition; raid warning sting
  (Sword Pack 1, 'blades drawn') on EventBus.wolf_spawned. All on SFX
  bus — inherits existing slider + suspend mute.

Contracts pre-written before fan-out: EventBus.stockpile_selected /
stockpile_deselected / wolf_spawned signals; WolfSpawner._trigger_raid
+ _on_request_wolf_spawn now emit wolf_spawned with the spawned array.

MCP runtime verified: StockpilePanel opens with 21 chips, DaySummaryCard
renders weather row + tension bar + auto-pause, rain_player.playing=true
on weather_changed(rain), all three new SFX keys in Audio.SFX_FILES.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
megaproxy 2026-05-16 17:20:40 +01:00
parent 88e3fa9364
commit bba1ce4334
18 changed files with 935 additions and 18 deletions

View file

@ -54,10 +54,13 @@ func _trigger_raid(current_tick: int) -> void:
_last_raid_tick = current_tick
var pack_size := randi_range(PACK_MIN, PACK_MAX)
var spawn_tiles := _pick_spawn_tiles(pack_size)
var spawned: Array = []
for spawn_tile in spawn_tiles:
var w: Wolf = WOLF_SCENE.instantiate()
get_parent().add_child(w)
w.setup(spawn_tile)
spawned.append(w)
EventBus.wolf_spawned.emit(spawned)
Audit.log("wolf", "RAID: %d wolf(ves) spawned at %s" % [pack_size, spawn_tiles])
@ -68,10 +71,13 @@ func _trigger_raid(current_tick: int) -> void:
## the night-attack cooldown, so organic raids can still follow.
func _on_request_wolf_spawn(count: int) -> void:
var spawn_tiles := _pick_spawn_tiles(count)
var spawned: Array = []
for spawn_tile in spawn_tiles:
var w: Wolf = WOLF_SCENE.instantiate()
get_parent().add_child(w)
w.setup(spawn_tile)
spawned.append(w)
EventBus.wolf_spawned.emit(spawned)
Audit.log("wolf", "FORCED RAID (event): %d wolf(ves) spawned at %s" % [count, spawn_tiles])