Implement Phase 17a Prop Roles UI/UX Specification and associated functionality

- Added UI/UX specification for prop roles and set down mechanics in phase 17a.
- Created `PropStageRoles` script to manage normalized behavior for props, including depth, motion, and collision settings.
- Introduced `StagePhysicsPolicy` for shared physics configurations related to props and actors.
- Developed comprehensive tests for prop roles, including default settings, legacy migration, serialization, and runtime behavior.
- Ensured proper handling of set down actions, including clearance and orientation preservation.
This commit is contained in:
2026-10-09 23:11:34 -04:00
parent 3f66cc3195
commit 1d4a71525a
52 changed files with 20051 additions and 109 deletions
+13 -5
View File
@@ -120,6 +120,13 @@ func set_throw_target(pos: Vector2) -> void:
popup_centered()
func set_down_target(pos: Vector2) -> void:
_has_throw_target = true
_throw_target_pos = pos
_update_throw_target_label()
popup_centered()
func current_action_type() -> String:
return _current_type()
@@ -294,14 +301,14 @@ func _rebuild_params(type: String) -> void:
var hand_idx := ["auto", "left", "right"].find(String(_initial.get("hand", "auto")))
_hand_option.select(maxi(hand_idx, 0))
hand_row.add_child(_hand_option)
"throw_prop":
"throw_prop", "set_down_prop":
var throw_row := HBoxContainer.new()
_params_box.add_child(throw_row)
_target_label = Label.new()
_target_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
throw_row.add_child(_target_label)
_set_target_btn = Button.new()
_set_target_btn.text = "🎯 Click target…"
_set_target_btn.text = ("📍 Change release place" if _has_throw_target else "📍 Choose release place") if type == "set_down_prop" else ("🎯 Change target…" if _has_throw_target else "🎯 Click target…")
_set_target_btn.pressed.connect(func() -> void: target_requested.emit())
throw_row.add_child(_set_target_btn)
_update_throw_target_label()
@@ -410,10 +417,11 @@ func _update_prop_target_label() -> void:
func _update_throw_target_label() -> void:
if _target_label == null:
return
var label_prefix: String = "Release place" if _current_type() == "set_down_prop" else "Target"
if _has_throw_target:
_target_label.text = "Target: (%d, %d)" % [int(roundf(_throw_target_pos.x)), int(roundf(_throw_target_pos.y))]
_target_label.text = "%s: (%d, %d)" % [label_prefix, int(roundf(_throw_target_pos.x)), int(roundf(_throw_target_pos.y))]
else:
_target_label.text = "Target: not set"
_target_label.text = "%s: not set" % label_prefix
func _on_ok_pressed() -> void:
@@ -434,7 +442,7 @@ func _on_ok_pressed() -> void:
var hands: Array[String] = ["auto", "left", "right"]
action["target_prop_id"] = _prop_target_id
action["hand"] = hands[_hand_option.selected] if _hand_option != null and _hand_option.selected >= 0 else "auto"
"throw_prop":
"throw_prop", "set_down_prop":
if not _has_throw_target:
target_requested.emit()
return
@@ -0,0 +1,47 @@
class_name PropSettingsDepthCue
extends Control
## Small vector picture showing whether a prop is drawn behind or in front.
var _in_front: bool = false
var _stickman_color: Color = Color("#F5F7FA")
var _prop_color: Color = Color("#B7824D")
var _outline_color: Color = Color("#171B24")
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
custom_minimum_size = Vector2(40.0, 34.0)
queue_redraw()
func configure(in_front: bool, stickman_color: Color, prop_color: Color, outline_color: Color) -> void:
_in_front = in_front
_stickman_color = stickman_color
_prop_color = prop_color
_outline_color = outline_color
queue_redraw()
func _draw() -> void:
if _in_front:
_draw_stickman()
_draw_prop()
else:
_draw_prop()
_draw_stickman()
func _draw_prop() -> void:
var box := Rect2(Vector2(18.0, 10.0), Vector2(19.0, 19.0))
draw_rect(box, _prop_color)
draw_rect(box, _outline_color, false, 1.5)
func _draw_stickman() -> void:
var head := Vector2(17.0, 5.5)
draw_circle(head, 4.0, _stickman_color)
draw_line(Vector2(17.0, 10.0), Vector2(17.0, 21.0), _stickman_color, 2.5, true)
draw_line(Vector2(17.0, 13.5), Vector2(9.0, 18.0), _stickman_color, 2.5, true)
draw_line(Vector2(17.0, 13.5), Vector2(25.0, 17.5), _stickman_color, 2.5, true)
draw_line(Vector2(17.0, 21.0), Vector2(11.5, 30.0), _stickman_color, 2.5, true)
draw_line(Vector2(17.0, 21.0), Vector2(23.0, 30.0), _stickman_color, 2.5, true)
@@ -0,0 +1 @@
uid://dm8lgubovno3v
File diff suppressed because it is too large Load Diff