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