extends Node ## Array-based inventory with item IDs from data/items.json. signal inventory_changed signal item_used(item_id: String) var _items: Dictionary = {} var _defs: Dictionary = {} func _ready() -> void: _load_defs() func _load_defs() -> void: var file := FileAccess.open("res://data/items.json", FileAccess.READ) if file == null: return var parsed: Variant = JSON.parse_string(file.get_as_text()) if typeof(parsed) != TYPE_ARRAY: return for entry in parsed: if typeof(entry) == TYPE_DICTIONARY and entry.has("id"): _defs[str(entry["id"])] = entry func add_item(item_id: String, amount: int = 1) -> void: if amount <= 0: return _items[item_id] = int(_items.get(item_id, 0)) + amount inventory_changed.emit() GameState.save_game() func remove_item(item_id: String, amount: int = 1) -> bool: var have := int(_items.get(item_id, 0)) if have < amount: return false have -= amount if have <= 0: _items.erase(item_id) else: _items[item_id] = have inventory_changed.emit() GameState.save_game() return true func has_item(item_id: String, amount: int = 1) -> bool: return int(_items.get(item_id, 0)) >= amount func get_count(item_id: String) -> int: return int(_items.get(item_id, 0)) func get_icon_path(item_id: String) -> String: var def: Variant = _defs.get(item_id, {}) if typeof(def) == TYPE_DICTIONARY: return str(def.get("icon", "")) return "" func get_all() -> Dictionary: return _items.duplicate() func use_item(item_id: String) -> bool: if not has_item(item_id): return false match item_id: "milk": remove_item("milk", 1) item_used.emit(item_id) GameState.skip_to_final_boss() return true "death_ticket": remove_item("death_ticket", 1) Achievements.unlock("eaten_to_death") item_used.emit(item_id) GameState.die("death_ticket_eaten") return true "tiramisu": remove_item("tiramisu", 1) GameState.apply_fat(600.0) item_used.emit(item_id) return true "dressler_apple": remove_item("dressler_apple", 1) item_used.emit(item_id) var ui := get_node_or_null("/root/UIRoot") if ui and ui.has_method("show_dialog"): ui.show_dialog_key("dialog_boss_unclever", 4.0) GameState.goto_scene("final_boss") return true "wedding_egg": remove_item("wedding_egg", 1) item_used.emit(item_id) GameState.set_flag("used_whiff", true) GameState.goto_scene("final_boss") return true "banana": remove_item("banana", 1) GameState.heal_full() item_used.emit(item_id) return true _: return false func serialize() -> Dictionary: return {"items": _items.duplicate()} func deserialize(data: Dictionary) -> void: _items = data.get("items", {}).duplicate() inventory_changed.emit()