feat(character): add hand slot API (attach/detach/get_held_item/is_hand_free)

This commit is contained in:
Steven Wroblewski
2026-05-08 22:09:56 +02:00
parent 1a9d916293
commit 60fba44316
2 changed files with 100 additions and 0 deletions
+43
View File
@@ -87,6 +87,49 @@ func get_outfit(layer: int) -> String:
return data.outfit[layer - 1]
func attach_item(hand: String, item: Node2D) -> bool:
if hand != "left" and hand != "right":
return false
var slot: Node2D = get_node_or_null("Hand" + hand.capitalize()) as Node2D
if slot == null:
return false
if slot.get_child_count() > 0:
return false
var old_parent: Node = item.get_parent()
if old_parent != null:
old_parent.remove_child(item)
slot.add_child(item)
item.position = Vector2.ZERO
return true
func detach_item(hand: String) -> Node2D:
if hand != "left" and hand != "right":
return null
var slot: Node2D = get_node_or_null("Hand" + hand.capitalize()) as Node2D
if slot == null or slot.get_child_count() == 0:
return null
var item: Node2D = slot.get_child(0) as Node2D
slot.remove_child(item)
var scene_parent: Node = get_parent()
if scene_parent != null:
scene_parent.add_child(item)
return item
func get_held_item(hand: String) -> Node2D:
if hand != "left" and hand != "right":
return null
var slot: Node2D = get_node_or_null("Hand" + hand.capitalize()) as Node2D
if slot == null or slot.get_child_count() == 0:
return null
return slot.get_child(0) as Node2D
func is_hand_free(hand: String) -> bool:
return get_held_item(hand) == null
func _update_visual_state() -> void:
if data == null:
return
+57
View File
@@ -112,3 +112,60 @@ func test_set_outfit_invalid_layer_zero_is_noop() -> void:
func test_set_outfit_invalid_layer_four_is_noop() -> void:
_char.set_outfit(4, "white_coat", null)
assert_eq(_char.get_outfit(3), "")
func test_both_hands_free_initially() -> void:
assert_true(_char.is_hand_free("left"))
assert_true(_char.is_hand_free("right"))
func test_attach_item_to_left_hand() -> void:
var item: Node2D = Node2D.new()
add_child_autofree(item)
_char.attach_item("left", item)
assert_false(_char.is_hand_free("left"))
func test_get_held_item_returns_attached_item() -> void:
var item: Node2D = Node2D.new()
add_child_autofree(item)
_char.attach_item("right", item)
assert_eq(_char.get_held_item("right"), item)
func test_attach_to_occupied_hand_returns_false() -> void:
var item1: Node2D = Node2D.new()
var item2: Node2D = Node2D.new()
add_child_autofree(item1)
add_child_autofree(item2)
_char.attach_item("left", item1)
var result: bool = _char.attach_item("left", item2)
assert_false(result)
func test_attach_returns_true_on_success() -> void:
var item: Node2D = Node2D.new()
add_child_autofree(item)
var result: bool = _char.attach_item("right", item)
assert_true(result)
func test_detach_item_frees_hand() -> void:
var item: Node2D = Node2D.new()
add_child_autofree(item)
_char.attach_item("left", item)
_char.detach_item("left")
assert_true(_char.is_hand_free("left"))
func test_detach_returns_item() -> void:
var item: Node2D = Node2D.new()
add_child_autofree(item)
_char.attach_item("right", item)
var returned: Node2D = _char.detach_item("right")
assert_eq(returned, item)
func test_detach_from_empty_hand_returns_null() -> void:
var returned: Node2D = _char.detach_item("left")
assert_null(returned)