85 lines
2.1 KiB
GDScript3
85 lines
2.1 KiB
GDScript3
|
|
extends Node
|
||
|
|
## Array-based inventory with item IDs from data/items.json.
|
||
|
|
|
||
|
|
signal inventory_changed
|
||
|
|
signal item_used(item_id: String)
|
||
|
|
|
||
|
|
var _items: Dictionary = {} # id -> count
|
||
|
|
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:
|
||
|
|
push_error("Missing items.json")
|
||
|
|
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_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)
|
||
|
|
return true
|
||
|
|
"tiramisu":
|
||
|
|
remove_item("tiramisu", 1)
|
||
|
|
var eaten := int(GameState.get_flag("tiramisu_kg", 0)) + 1
|
||
|
|
GameState.set_flag("tiramisu_kg", eaten)
|
||
|
|
if eaten >= 1000:
|
||
|
|
Achievements.unlock("tiramisu_tonne")
|
||
|
|
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()
|