84 lines
1.8 KiB
GDScript
84 lines
1.8 KiB
GDScript
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
|