Files
experiment-adventure-ai/cutscene/actions/TurnAction.gd
2025-08-01 08:34:51 -07:00

70 lines
1.8 KiB
GDScript
Executable File

class_name TurnAction
extends "res://cutscene/Action.gd"
# Properties
var character: Node2D # The character to turn
var target: Variant # Either a Vector2 position or another Node2D
var turn_speed: float = 2.0 # Rotation speed (radians/second)
func _init(character_node: Node2D, turn_target: Variant, speed: float = 2.0) -> void:
character = character_node
target = turn_target
turn_speed = speed
name = "TurnAction"
func start() -> void:
if character == null:
self._set_failed("Character is null")
return
self._set_running()
func update(delta: float) -> void:
if state != State.RUNNING:
return
if character == null:
self._set_failed("Character was destroyed during action")
return
# Calculate target rotation
var target_position: Vector2
if target is Vector2:
target_position = target
elif target is Node2D:
target_position = target.position
else:
self._set_failed("Invalid target type")
return
var direction = target_position - character.position
var target_rotation = atan2(direction.y, direction.x)
# Rotate toward target
var angle_diff = _angle_difference(character.rotation, target_rotation)
# If we're close enough, complete the action
if abs(angle_diff) < 0.01:
character.rotation = target_rotation
self._set_completed()
return
# Rotate based on turn speed
var rotation_amount = sign(angle_diff) * turn_speed * delta
if abs(rotation_amount) > abs(angle_diff):
character.rotation = target_rotation
self._set_completed()
else:
character.rotation += rotation_amount
func is_completed() -> bool:
return state == State.COMPLETED
# Helper function to calculate angle difference
func _angle_difference(from: float, to: float) -> float:
var diff = fmod(to - from, 2.0 * PI)
if diff < -PI:
diff += 2.0 * PI
elif diff > PI:
diff -= 2.0 * PI
return diff