Add prop interaction system and throw mechanics specification

- Introduced `stickman_prop_interactor.gd` to manage prop interactions.
- Created `phase_11_prop_interactions.md` detailing the design and implementation of prop pickup, drop, and throw mechanics.
- Defined interaction states, action lifecycles, and event triggers for prop handling.
- Specified constraints for throw actions, including target positioning and velocity calculations.
- Established acceptance criteria for prop interactions and lifecycle management.
This commit is contained in:
2026-09-25 23:42:26 -04:00
parent 730a9a966b
commit 6a1359f244
22 changed files with 3433 additions and 34 deletions
+42
View File
@@ -47,6 +47,29 @@ const ACTION_TEMPLATES := {
"params": [],
"reactive_role": ReactiveRole.TAKEOVER, "overlay_eligible": false,
},
"pick_up_prop": {
"label": "Pick Up Prop",
"icon": "🫴",
"params": [
{ "key": "target_prop_id", "type": "prop", "required": true },
{ "key": "hand", "type": "choice", "default": "auto", "choices": ["auto", "left", "right"] },
],
"reactive_role": ReactiveRole.SEQUENTIAL, "overlay_eligible": false,
},
"drop_prop": {
"label": "Drop Prop",
"icon": "⬇️",
"params": [],
"reactive_role": ReactiveRole.SEQUENTIAL, "overlay_eligible": false,
},
"throw_prop": {
"label": "Throw Prop",
"icon": "🏹",
"params": [
{ "key": "target_position", "type": "position", "required": true },
],
"reactive_role": ReactiveRole.SEQUENTIAL, "overlay_eligible": false,
},
}
@@ -102,6 +125,11 @@ static func to_rule_action(action: Dictionary, target_id: int) -> Dictionary:
params["stop_current"] = true
"wait":
params["duration"] = float(action.get("duration", 0.0))
"pick_up_prop":
params["target_prop_id"] = String(action.get("target_prop_id", ""))
params["hand"] = String(action.get("hand", "auto"))
"throw_prop":
params["target_position"] = action.get("target_position", Vector2.ZERO)
return {
"type": String(action.get("type", "")),
"target": target_id,
@@ -126,6 +154,12 @@ static func from_rule_action(rule_action: Dictionary) -> Dictionary:
return speak
"wait":
return { "type": "wait", "duration": float(params.get("duration", 0.0)) }
"pick_up_prop":
return { "type": "pick_up_prop", "target_prop_id": String(params.get("target_prop_id", "")), "hand": String(params.get("hand", "auto")) }
"drop_prop":
return { "type": "drop_prop" }
"throw_prop":
return { "type": "throw_prop", "target_position": params.get("target_position", Vector2.ZERO) }
_:
return { "type": String(rule_action.get("type", "")) }
@@ -155,6 +189,14 @@ static func summarize(action: Dictionary) -> String:
return "Ragdoll"
"recover":
return "Recover"
"pick_up_prop":
return "Pick Up Prop (%s)" % String(action.get("target_prop_id", params.get("target_prop_id", "")))
"drop_prop":
return "Drop Prop"
"throw_prop":
var raw_position: Variant = action.get("target_position", params.get("target_position", Vector2.ZERO))
var target_position: Vector2 = raw_position as Vector2 if raw_position is Vector2 else Vector2.ZERO
return "Throw Prop (%d, %d)" % [int(roundf(target_position.x)), int(roundf(target_position.y))]
_:
return type