extends Node ## Central game state: tracks delivery tasks, aggregates NPC detection and ## drives the win / lose flow. Registered as the "GameManager" autoload. signal tasks_changed signal detection_changed(value: float) signal game_won signal game_lost var tasks: Array[Dictionary] = [] var game_over: bool = false var _detection: float = 0.0 var _npc_alerts: Dictionary = {} func reset_level() -> void: tasks.clear() _npc_alerts.clear() _detection = 0.0 game_over = false get_tree().paused = false tasks_changed.emit() detection_changed.emit(0.0) func register_task(id: String, description: String) -> void: for t in tasks: if t.id == id: return tasks.append({"id": id, "description": description, "done": false}) tasks_changed.emit() func complete_task(id: String) -> void: for t in tasks: if t.id == id and not t.done: t.done = true tasks_changed.emit() _check_win() return func is_task_done(id: String) -> bool: for t in tasks: if t.id == id: return t.done return false func all_tasks_done() -> bool: if tasks.is_empty(): return false for t in tasks: if not t.done: return false return true func report_npc_alert(npc_id: int, value: float) -> void: _npc_alerts[npc_id] = value var highest := 0.0 for v in _npc_alerts.values(): highest = maxf(highest, v) _set_detection(highest) func report_caught() -> void: if game_over: return game_over = true _set_detection(1.0) game_lost.emit() get_tree().paused = true func restart() -> void: reset_level() get_tree().reload_current_scene() func _set_detection(value: float) -> void: value = clampf(value, 0.0, 1.0) if not is_equal_approx(value, _detection): _detection = value detection_changed.emit(_detection) func _check_win() -> void: if all_tasks_done() and not game_over: game_over = true game_won.emit() get_tree().paused = true