102 lines
2.8 KiB
GDScript
102 lines
2.8 KiB
GDScript
## 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[HoldableItem] = []
|
|
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:
|
|
if not _spawned_items.has(item):
|
|
return
|
|
_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 get_spawned_item(index: int) -> HoldableItem:
|
|
if index < 0 or index >= _spawned_items.size():
|
|
return null
|
|
return _spawned_items[index]
|
|
|
|
|
|
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[String]:
|
|
var ids: Array[String] = []
|
|
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)
|