feat(items): add chest-return priority to HoldableItem and GameState v3 chest states

- HoldableItem._try_return_to_chest() snaps item back if within CHEST_RETURN_RADIUS (80px)
- _on_drag_released checks chest return before hand-slot fallback
- OutfitItem._on_drag_released checks chest return before outfit/hand-slot logic
- GameState: _chest_states dict + get/set/clear_chest_state methods
- GameState.get_save_data() bumped to version 3, includes chest_states
- GameState.apply_save_data() restores chest_states from save data
This commit is contained in:
Steven Wroblewski
2026-05-09 01:09:47 +02:00
parent 4f1766834a
commit 96ec053331
5 changed files with 102 additions and 2 deletions
+21 -1
View File
@@ -8,6 +8,7 @@ var _character_positions: Dictionary = {}
var _character_outfits: Dictionary = {}
var _character_held_items: Dictionary = {}
var _object_states: Dictionary = {}
var _chest_states: Dictionary = {}
var current_room: String = "reception"
var music_volume: float = 0.6
var sfx_volume: float = 1.0
@@ -58,17 +59,32 @@ func set_object_state(id: String, state: String) -> void:
state_changed.emit()
func get_chest_state(chest_id: String) -> Array:
return _chest_states.get(chest_id, [])
func set_chest_state(chest_id: String, spawned_item_ids: Array) -> void:
_chest_states[chest_id] = spawned_item_ids
state_changed.emit()
func clear_chest_state(chest_id: String) -> void:
_chest_states.erase(chest_id)
state_changed.emit()
func get_save_data() -> Dictionary:
var positions: Dictionary = {}
for key: String in _character_positions:
var pos: Vector2 = _character_positions[key]
positions[key] = [pos.x, pos.y]
return {
"version": 2,
"version": 3,
"character_positions": positions,
"character_outfits": _character_outfits.duplicate(true),
"character_held_items": _character_held_items.duplicate(true),
"object_states": _object_states,
"chest_states": _chest_states.duplicate(true),
"current_room": current_room,
"music_volume": music_volume,
"sfx_volume": sfx_volume,
@@ -98,3 +114,7 @@ func apply_save_data(data: Dictionary) -> void:
music_volume = data["music_volume"]
if data.has("sfx_volume"):
sfx_volume = data["sfx_volume"]
if data.has("chest_states"):
_chest_states = data["chest_states"].duplicate(true)
else:
_chest_states = {}
+12
View File
@@ -7,6 +7,7 @@ signal item_picked_up(item: HoldableItem)
signal item_placed(item: HoldableItem)
const HAND_SLOT_RADIUS: float = 60.0
const CHEST_RETURN_RADIUS: float = 80.0
@export var item_id: String = ""
@@ -27,6 +28,8 @@ func _on_drag_picked_up(_pos: Vector2) -> void:
func _on_drag_released(_pos: Vector2) -> void:
if _try_return_to_chest():
return
var result: Array = _find_nearest_free_hand_slot()
if not result.is_empty():
var character: Character = result[0] as Character
@@ -35,6 +38,15 @@ func _on_drag_released(_pos: Vector2) -> void:
item_placed.emit(self)
func _try_return_to_chest() -> bool:
if home_chest == null:
return false
if global_position.distance_to(home_chest.global_position) >= CHEST_RETURN_RADIUS:
return false
(home_chest as RoomChest).receive_item(self)
return true
func is_in_hand_slot() -> bool:
var p: Node = get_parent()
if p == null:
+2
View File
@@ -10,6 +10,8 @@ const OUTFIT_APPLY_RADIUS: float = 80.0
func _on_drag_released(_pos: Vector2) -> void:
if _try_return_to_chest():
return
var character: Character = _find_nearest_character()
if character != null:
character.apply_outfit_item(outfit_layer, item_id, outfit_sprite, self)