Implement speech style toolbar live-edit refinements and whole speech show controls

- Added a new specification for the speech style toolbar live-edit, detailing immediate style application, scoped effect demonstration, and hover feedback.
- Introduced refinements to the speech style toolbar, including improved chooser sizing, exclusive stage editing during speech composition, and removal of redundant controls.
- Documented new stage controls for managing how the whole speech shows, including options for bubble arrangement, word appearance, and bubble motion.
- Created a new log file for speech padding syntax to track engine versioning.
This commit is contained in:
2026-10-03 14:49:22 -04:00
parent 6a1359f244
commit 6666173c4f
42 changed files with 9163 additions and 165 deletions
+33
View File
@@ -410,6 +410,29 @@ func get_facing_profile() -> int:
return int(facing_profile)
func speech_head_geometry() -> Dictionary:
var head_visual: Node2D = _body_container.get_node_or_null(NodePath("Head")) as Node2D if _body_container != null and is_instance_valid(_body_container) else null
if state == RigState.RAGDOLL and _ragdoll_component != null and is_instance_valid(_ragdoll_component):
var body_nodes: Variant = _ragdoll_component.call("get_body_nodes")
if body_nodes is Array:
for raw_body: Variant in body_nodes as Array:
if not raw_body is RigidBody2D:
continue
var body: RigidBody2D = raw_body as RigidBody2D
if String(body.get_meta("part_name", "")) == "head":
var body_radius: float = float(body.get_meta("radius", 100.0))
var body_scale: Vector2 = body.global_scale.abs()
return {"center": to_local(body.global_position), "radius": body_radius * maxf(body_scale.x, body_scale.y)}
if head_visual != null and is_instance_valid(head_visual):
var raw_radius: Variant = head_visual.get("radius")
var radius: float = float(raw_radius) if raw_radius is int or raw_radius is float else 100.0
var head_scale: Vector2 = head_visual.global_scale.abs()
return {"center": to_local(head_visual.global_position), "radius": radius * maxf(head_scale.x, head_scale.y)}
if _head_bone != null and is_instance_valid(_head_bone):
return {"center": to_local(_head_bone.global_position), "radius": 100.0 * maxf(absf(_head_bone.global_scale.x), absf(_head_bone.global_scale.y))}
return {"center": Vector2(0.0, -310.0), "radius": 100.0}
func set_joint_bend_flipped(joint: String, flipped: bool) -> void:
match joint:
"LeftArm":
@@ -785,6 +808,16 @@ func speak(text: String, duration: float) -> void:
_action_runner_component.speak(text, duration)
func speak_action(action: Dictionary) -> void:
if _action_runner_component != null:
_action_runner_component.speak_action(action)
func set_speech_preview_suppressed(value: bool) -> void:
if _action_runner_component != null:
_action_runner_component.set_speech_preview_suppressed(value)
func _speak_overlay(text: String, duration: float) -> void:
if _action_runner_component != null:
_action_runner_component.speak_overlay(text, duration)