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:
@@ -11,6 +11,7 @@ extends RigidBody2D
|
||||
## friction/bounce (PhysicsMaterial), and themed visuals.
|
||||
|
||||
const PropVisuals := preload("res://scripts/prop_visuals.gd")
|
||||
const PropAnchorDataScript := preload("res://scripts/prop_anchor_data.gd")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Enums
|
||||
@@ -23,6 +24,13 @@ enum MaterialPreset { NONE, WOOD, RUBBER, CARDBOARD, METAL }
|
||||
## Stable library provenance used by Sandbox Stage scene files.
|
||||
var spawn_id: String = ""
|
||||
|
||||
## Stable identity of this placed prop in one Sandbox Stage scene. Unlike
|
||||
## spawn_id, this value is unique per instance and survives scene save/load.
|
||||
var stage_object_id: String = ""
|
||||
var interaction_anchors: Dictionary = {}
|
||||
var interaction_reserved_by: int = 0
|
||||
var interaction_owner_id: int = 0
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Child node names
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -126,6 +134,33 @@ func _ready() -> void:
|
||||
body_exited.connect(_on_body_exited)
|
||||
|
||||
|
||||
func set_interaction_anchors(value: Dictionary) -> void:
|
||||
interaction_anchors = PropAnchorDataScript.normalize_anchors(value)
|
||||
|
||||
|
||||
func get_interaction_anchors() -> Dictionary:
|
||||
return PropAnchorDataScript.normalize_anchors(interaction_anchors, false)
|
||||
|
||||
|
||||
func ensure_default_grip() -> void:
|
||||
var normalized := get_interaction_anchors()
|
||||
if not PropAnchorDataScript.ids_for_role(normalized, "grip").is_empty():
|
||||
interaction_anchors = normalized
|
||||
return
|
||||
var bounds := _visual_local_bounds
|
||||
if bounds.size == Vector2.ZERO:
|
||||
if shape_type == ShapeType.CIRCLE:
|
||||
bounds = Rect2(Vector2(-radius, -radius), Vector2(radius * 2.0, radius * 2.0))
|
||||
elif polygon_points.size() >= 3:
|
||||
var min_point := polygon_points[0]
|
||||
var max_point := polygon_points[0]
|
||||
for point: Vector2 in polygon_points:
|
||||
min_point = min_point.min(point)
|
||||
max_point = max_point.max(point)
|
||||
bounds = Rect2(min_point, max_point - min_point)
|
||||
interaction_anchors = PropAnchorDataScript.preset_layout("one_handed", bounds)
|
||||
|
||||
|
||||
func _on_body_entered(body: Node) -> void:
|
||||
var center: Vector2 = (body as Node2D).global_position if body is Node2D else global_position
|
||||
var normal: Vector2 = (center - global_position).normalized()
|
||||
@@ -277,6 +312,10 @@ func has_custom_shapes() -> bool:
|
||||
func get_visual_local_bounds() -> Rect2:
|
||||
return _visual_local_bounds
|
||||
|
||||
|
||||
func get_interaction_scale() -> Vector2:
|
||||
return _play_instance_scale if _play_scale_active else scale.abs()
|
||||
|
||||
## RigidBody2D transforms do not reliably retain scale during simulation. Move
|
||||
## the authored uniform scale into child visuals and collision geometry for
|
||||
## PLAY, then restore the root scale on return to EDIT for scene persistence.
|
||||
|
||||
Reference in New Issue
Block a user