Alerts: wire room_too_large, no_stockpile_accepts, bill_blocked
Three alert signals had no UI subscribers — gameplay failures vanished silently. Now all three feed AlertsLog via translator handlers that forward to the generic alert_added sink. - EventBus: new no_stockpile_accepts(item_type, tile) and bill_blocked(recipe_label, reason, focus_tile) signals. - HaulingProvider: per-item-type 30s cooldown; emits when find_best_for scan finishes with viable items but no destinations. - CraftingProvider: per-(workbench, reason) 60s cooldown; emits at the skill_too_low and missing_ingredient continue sites. no_workbench reason declared for future use but not emitted (the iteration shape has no natural site for it). - AlertsLog: connect + disconnect for all three signals using the same has_signal-guarded pattern; translator handlers convert to localized alert_added(severity, text, focus_tile). - AlertsLog catch-up: room_too_large emits during World init, before this CanvasLayer mounts. _catch_up_room_too_large() in _ready scans World.rooms for rooms > ROOM_AUTOROOF_CAP and replays them, so the pre-built cabin's 24-tile-too-large warning lands in the log on every boot. Hauling/bill signals fire at runtime so they need no catch-up. Verified runtime: cabin warning shows up in AlertsLog with severity 'warn' and focus_tile (45, 24) — the cabin top-left. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
335ccf52b2
commit
708080a022
4 changed files with 115 additions and 0 deletions
|
|
@ -73,6 +73,16 @@ func _ready() -> void:
|
|||
EventBus.storyteller_event_fired.connect(_on_storyteller_event)
|
||||
if EventBus.has_signal("day_ended"):
|
||||
EventBus.day_ended.connect(_on_day_ended)
|
||||
if EventBus.has_signal("room_too_large"):
|
||||
EventBus.room_too_large.connect(_on_room_too_large)
|
||||
# Catch-up: room_too_large emits during World init (cabin demo room),
|
||||
# which runs before this CanvasLayer mounts. Replay existing too-large
|
||||
# rooms now so the boot-state cabin warning shows up in the log.
|
||||
_catch_up_room_too_large()
|
||||
if EventBus.has_signal("no_stockpile_accepts"):
|
||||
EventBus.no_stockpile_accepts.connect(_on_no_stockpile_accepts)
|
||||
if EventBus.has_signal("bill_blocked"):
|
||||
EventBus.bill_blocked.connect(_on_bill_blocked)
|
||||
|
||||
Audit.log("alerts_log", "AlertsLog ready")
|
||||
|
||||
|
|
@ -84,6 +94,12 @@ func _exit_tree() -> void:
|
|||
EventBus.storyteller_event_fired.disconnect(_on_storyteller_event)
|
||||
if EventBus.has_signal("day_ended") and EventBus.day_ended.is_connected(_on_day_ended):
|
||||
EventBus.day_ended.disconnect(_on_day_ended)
|
||||
if EventBus.has_signal("room_too_large") and EventBus.room_too_large.is_connected(_on_room_too_large):
|
||||
EventBus.room_too_large.disconnect(_on_room_too_large)
|
||||
if EventBus.has_signal("no_stockpile_accepts") and EventBus.no_stockpile_accepts.is_connected(_on_no_stockpile_accepts):
|
||||
EventBus.no_stockpile_accepts.disconnect(_on_no_stockpile_accepts)
|
||||
if EventBus.has_signal("bill_blocked") and EventBus.bill_blocked.is_connected(_on_bill_blocked):
|
||||
EventBus.bill_blocked.disconnect(_on_bill_blocked)
|
||||
|
||||
|
||||
# ── public API ────────────────────────────────────────────────────────────────
|
||||
|
|
@ -254,6 +270,52 @@ func _on_day_ended(summary: Dictionary) -> void:
|
|||
Audit.log("alerts_log", "day_ended logged: %s" % text)
|
||||
|
||||
|
||||
## Boot catch-up: scan World.rooms for rooms exceeding the auto-roof cap and
|
||||
## replay them through the translator. RoomDetector emits room_too_large during
|
||||
## World init, before this CanvasLayer mounts; without this catch-up the cabin
|
||||
## warning (always present at boot in the demo seed) never reaches the log.
|
||||
func _catch_up_room_too_large() -> void:
|
||||
for id in World.rooms:
|
||||
var r = World.rooms[id]
|
||||
if r != null and r.tile_count() > Room.ROOM_AUTOROOF_CAP:
|
||||
_on_room_too_large(r.bounds.position, r.tile_count())
|
||||
|
||||
|
||||
## Translates room_too_large → alert_added (warn).
|
||||
func _on_room_too_large(top_left: Vector2i, cell_count: int) -> void:
|
||||
EventBus.alert_added.emit(
|
||||
&"warn",
|
||||
"Room too large to roof (%d tiles). Split with an interior wall." % cell_count,
|
||||
top_left,
|
||||
)
|
||||
Audit.log("alerts_log", "room_too_large translated: %d tiles at %s" % [cell_count, top_left])
|
||||
|
||||
|
||||
## Translates no_stockpile_accepts → alert_added (warn).
|
||||
func _on_no_stockpile_accepts(item_type: StringName, tile: Vector2i) -> void:
|
||||
EventBus.alert_added.emit(
|
||||
&"warn",
|
||||
"No stockpile accepts %s" % String(item_type),
|
||||
tile,
|
||||
)
|
||||
Audit.log("alerts_log", "no_stockpile_accepts translated: %s at %s" % [String(item_type), tile])
|
||||
|
||||
|
||||
## Translates bill_blocked → alert_added (warn).
|
||||
func _on_bill_blocked(recipe_label: String, reason: StringName, focus_tile: Vector2i) -> void:
|
||||
var reason_str: String = {
|
||||
&"missing_ingredient": "missing ingredient",
|
||||
&"skill_too_low": "skill too low",
|
||||
&"no_workbench": "no workbench reachable",
|
||||
}.get(reason, String(reason))
|
||||
EventBus.alert_added.emit(
|
||||
&"warn",
|
||||
"Bill blocked: %s — %s" % [recipe_label, reason_str],
|
||||
focus_tile,
|
||||
)
|
||||
Audit.log("alerts_log", "bill_blocked translated: %s — %s" % [recipe_label, reason_str])
|
||||
|
||||
|
||||
# ── helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func _format_timestamp() -> String:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue