extends Node ## Achievement unlock + persistence. signal unlocked(achievement_id: String, title: String) var _defs: Array = [] var _unlocked: Dictionary = {} # id -> true func _ready() -> void: _load_defs() func _load_defs() -> void: var file := FileAccess.open("res://data/achievements.json", FileAccess.READ) if file == null: push_error("Missing achievements.json") return var parsed: Variant = JSON.parse_string(file.get_as_text()) if typeof(parsed) == TYPE_ARRAY: _defs = parsed func unlock(achievement_id: String) -> void: if _unlocked.get(achievement_id, false): return _unlocked[achievement_id] = true var title := achievement_id for entry in _defs: if str(entry.get("id", "")) == achievement_id: title = Locale.tr_key(str(entry.get("title_key", achievement_id))) break unlocked.emit(achievement_id, title) _check_all() GameState.save_game() func is_unlocked(achievement_id: String) -> bool: return bool(_unlocked.get(achievement_id, false)) func get_defs() -> Array: return _defs func _check_all() -> void: if _unlocked.get("all_burgers", false): return for entry in _defs: var id := str(entry.get("id", "")) if id == "all_burgers": continue if not _unlocked.get(id, false): return _unlocked["all_burgers"] = true var title := Locale.tr_key("ach_all_title") unlocked.emit("all_burgers", title) func serialize() -> Dictionary: return {"unlocked": _unlocked.duplicate()} func deserialize(data: Dictionary) -> void: _unlocked = data.get("unlocked", {}).duplicate()