class_name GameState extends RefCounted ## Luck-centric game state (spec decision 5). The SOLE home of numeric Luck, ## the character sheet, world-NPC dispositions, and inventory — none of which ## enter the canon log (charter §7/§2). The log reads only luck_descriptor() ## from here. var luck: int = 0 var luck_base: int = 0 var sheet: CharacterSheet = null # the whole character (§2). Built by NewGame. var npc_dispositions: Dictionary = {} # world-npc id -> int (−100..100) var inventory: Dictionary = {} # item_id -> qty (NEVER money — see purse_copper) var purse_copper: int = 0 # ALL money, in copper. One integer (§4.1 of the spec). var revealed_topics: Dictionary = {} # topic_id -> true var gifts_given: Dictionary = {} # item_id -> true (idempotency for give_item) func set_luck(v: int) -> void: luck = clampi(v, Luck.MIN, Luck.MAX) func drift_luck(delta: int) -> void: luck = Luck.drift(luck, luck_base, delta) func luck_descriptor() -> String: return Luck.descriptor(luck) func set_npc_disposition(id: String, v: int) -> void: npc_dispositions[id] = clampi(v, -100, 100) func add_item(item_id: String, qty: int) -> void: inventory[item_id] = int(inventory.get(item_id, 0)) + qty func remove_item(item_id: String, qty: int) -> void: var left := int(inventory.get(item_id, 0)) - qty if left > 0: inventory[item_id] = left else: inventory.erase(item_id) func add_copper(amount: int) -> void: purse_copper = maxi(0, purse_copper + amount) func grant(item_id: String, qty: int) -> void: # The single routing point (with take): currency lands in the purse, every # other item in the inventory dict. Money is never an inventory row, so it # can never surface in an inventory grid — exclusion by construction. if Currency.is_currency(item_id): add_copper(Currency.value(item_id) * qty) else: add_item(item_id, qty) func take(item_id: String, qty: int) -> void: if Currency.is_currency(item_id): add_copper(-Currency.value(item_id) * qty) else: remove_item(item_id, qty) func mark_revealed(topic_id: String) -> void: revealed_topics[topic_id] = true func is_revealed(topic_id: String) -> bool: return revealed_topics.has(topic_id) func mark_gift_given(item_id: String) -> void: gifts_given[item_id] = true func is_gift_given(item_id: String) -> bool: return gifts_given.has(item_id)