Files
Cozypaw-Hospital/scripts/objects/holdable_item.gd
T
Steven Wroblewski ca1d20781e feat(items): add HoldableItem with hand slot detection, fix detach_item position
- Character registers in "characters" group on _ready for group scanning
- detach_item saves/restores global_position after reparenting
- New HoldableItem base class: scans "characters" group on drag_released,
  attaches to nearest free hand within 60px radius, detaches on pickup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:03:25 +02:00

74 lines
2.2 KiB
GDScript

## HoldableItem — Node2D that can be held in a Character's HandLeft or HandRight slot.
## Attach DragDropComponent as a child. On drag_released scans "characters" group for
## the nearest free hand slot within HAND_SLOT_RADIUS.
class_name HoldableItem extends Node2D
signal item_picked_up(item: HoldableItem)
signal item_placed(item: HoldableItem)
const HAND_SLOT_RADIUS: float = 60.0
@export var item_id: String = ""
func _ready() -> void:
var drag: DragDropComponent = get_node_or_null("DragDropComponent") as DragDropComponent
if drag != null:
drag.drag_picked_up.connect(_on_drag_picked_up)
drag.drag_released.connect(_on_drag_released)
func _on_drag_picked_up(_pos: Vector2) -> void:
if is_in_hand_slot():
_detach_from_hand_slot()
item_picked_up.emit(self)
func _on_drag_released(_pos: Vector2) -> void:
var result: Array = _find_nearest_free_hand_slot()
if not result.is_empty():
var character: Character = result[0] as Character
var hand: String = result[1] as String
character.attach_item(hand, self)
item_placed.emit(self)
func is_in_hand_slot() -> bool:
var p: Node = get_parent()
if p == null:
return false
return p.name == "HandLeft" or p.name == "HandRight"
func _detach_from_hand_slot() -> void:
var hand_slot: Node = get_parent()
var character: Character = hand_slot.get_parent() as Character
if character == null:
return
var hand: String = "left" if hand_slot.name == "HandLeft" else "right"
character.detach_item(hand)
func _find_nearest_free_hand_slot() -> Array:
var best_dist: float = HAND_SLOT_RADIUS
var best_character: Character = null
var best_hand: String = ""
for node: Node in get_tree().get_nodes_in_group("characters"):
var character: Character = node as Character
if character == null:
continue
for hand: String in ["left", "right"]:
if not character.is_hand_free(hand):
continue
var slot: Node2D = character.get_node_or_null("Hand" + hand.capitalize()) as Node2D
if slot == null:
continue
var dist: float = global_position.distance_to(slot.global_position)
if dist < best_dist:
best_dist = dist
best_character = character
best_hand = hand
if best_character == null:
return []
return [best_character, best_hand]