## RoomChest — tappable storage node. Spawns HoldableItem/OutfitItem instances on demand. ## Items fly out with a tween. Receives items back via receive_item(). class_name RoomChest extends Node2D signal items_spawned(chest: RoomChest) signal item_received(chest: RoomChest, item_id: String) const SPAWN_TWEEN_DURATION: float = 0.3 @export var chest_id: String = "" var _spawned_items: Array = [] var _item_configs: Array[ChestItemData] = [] func _ready() -> void: add_to_group("room_chests") _item_configs = RoomChestConfig.get_items(chest_id) if not chest_id.is_empty() and GameState.has_method("get_chest_state"): if not GameState.get_chest_state(chest_id).is_empty(): spawn_items() func spawn_items() -> void: if not _spawned_items.is_empty(): return var parent: Node = get_parent() for config: ChestItemData in _item_configs: var item: HoldableItem = _create_item(config) item.home_chest = self if parent != null: parent.add_child(item) else: add_child(item) item.global_position = global_position _spawned_items.append(item) _tween_item_out(item, config.spawn_offset) if GameState.has_method("set_chest_state"): GameState.set_chest_state(chest_id, _get_spawned_ids()) items_spawned.emit(self) func receive_item(item: HoldableItem) -> void: _spawned_items.erase(item) if GameState.has_method("set_chest_state"): if _spawned_items.is_empty(): GameState.clear_chest_state(chest_id) else: GameState.set_chest_state(chest_id, _get_spawned_ids()) item_received.emit(self, item.item_id) _tween_item_in(item) func are_items_spawned() -> bool: return not _spawned_items.is_empty() func get_spawned_count() -> int: return _spawned_items.size() func get_item_config_count() -> int: return _item_configs.size() func _create_item(config: ChestItemData) -> HoldableItem: var item: HoldableItem if config.item_type == ChestItemData.ItemType.OUTFIT: var outfit: OutfitItem = OutfitItem.new() outfit.outfit_layer = config.outfit_layer item = outfit else: item = HoldableItem.new() item.item_id = config.item_id return item func _get_spawned_ids() -> Array: var ids: Array = [] for item: HoldableItem in _spawned_items: ids.append(item.item_id) return ids func _tween_item_out(item: HoldableItem, offset: Vector2) -> void: var tween: Tween = create_tween() tween.tween_property(item, "global_position", global_position + offset, SPAWN_TWEEN_DURATION) func _tween_item_in(item: HoldableItem) -> void: var tween: Tween = create_tween() tween.tween_property(item, "global_position", global_position, SPAWN_TWEEN_DURATION) tween.tween_callback(item.queue_free)