Files
experiment-adventure-ai/addons/cutscene_editor/editor/CutsceneGenerator.gd
2025-07-31 18:00:00 -07:00

153 lines
4.6 KiB
GDScript

@tool
class_name CutsceneGenerator
extends Object
# System for generating executable cutscene actions from graph data
# Properties
var graph_nodes: Dictionary = {} # Map of node IDs to node data
var connections: Array = [] # List of connection data
# Generate a cutscene from graph data
func generate_cutscene(cutscene_resource: CutsceneResource) -> CutsceneManager:
# Clear previous data
graph_nodes.clear()
connections.clear()
# Load graph data
for node_data in cutscene_resource.nodes:
graph_nodes[node_data["id"]] = node_data
connections = cutscene_resource.connections
# Create CutsceneManager
var cutscene_manager = CutsceneManager.new()
# Find entry node
var entry_node = _find_entry_node()
if not entry_node:
printerr("No entry node found in cutscene")
return cutscene_manager
# Build action sequence starting from entry node
_build_action_sequence(entry_node, cutscene_manager)
return cutscene_manager
# Find the entry node in the graph
func _find_entry_node() -> Dictionary:
for node_id in graph_nodes:
var node_data = graph_nodes[node_id]
if node_data["type"] == "entry":
return node_data
return {}
# Build action sequence from graph data
func _build_action_sequence(start_node: Dictionary, cutscene_manager: CutsceneManager) -> void:
# Use a queue-based traversal to process nodes in order
var node_queue = []
var processed_nodes = {}
var next_connections = _get_outgoing_connections(start_node["id"])
# Add initial connections to queue
for conn in next_connections:
node_queue.append(conn["to_node"])
# Process nodes in order
while not node_queue.is_empty():
var current_node_id = node_queue.pop_front()
# Skip if already processed
if processed_nodes.has(current_node_id):
continue
# Mark as processed
processed_nodes[current_node_id] = true
# Get node data
var node_data = graph_nodes.get(current_node_id, {})
if node_data.is_empty():
continue
# Create action for regular nodes
var action = _create_action_from_node(node_data)
if action:
cutscene_manager.add_action(action)
# Add next nodes to queue
var outgoing_connections = _get_outgoing_connections(current_node_id)
for conn in outgoing_connections:
if not processed_nodes.has(conn["to_node"]):
node_queue.append(conn["to_node"])
# Create an action instance from node data
func _create_action_from_node(node_data: Dictionary):
var parameters = node_data["parameters"]
match node_data["type"]:
"move":
var character_path = parameters.get("character", "")
var target_x = parameters.get("target_x", 0.0)
var target_y = parameters.get("target_y", 0.0)
var speed = parameters.get("speed", 100.0)
# In a real implementation, we would resolve the character path to an actual node
# For now, we'll create a placeholder
var character_node = null # This would be resolved at runtime
var target_position = Vector2(target_x, target_y)
return MoveAction.new(character_node, target_position, speed)
"turn":
var character_path = parameters.get("character", "")
var target = parameters.get("target", "")
var turn_speed = parameters.get("turn_speed", 2.0)
# In a real implementation, we would resolve the paths to actual nodes
var character_node = null # This would be resolved at runtime
var target_node = null # This would be resolved at runtime
return TurnAction.new(character_node, target_node, turn_speed)
"dialogue":
var character_path = parameters.get("character", "")
var text = parameters.get("text", "")
var duration = parameters.get("duration", 0.0)
var character_node = null # This would be resolved at runtime
return DialogueAction.new(character_node, text, duration)
"animation":
var character_path = parameters.get("character", "")
var animation_name = parameters.get("animation_name", "")
var loop = parameters.get("loop", false)
var character_node = null # This would be resolved at runtime
return AnimationAction.new(character_node, animation_name, loop)
"wait":
var duration = parameters.get("duration", 1.0)
return WaitAction.new(duration)
_:
printerr("Unknown node type: %s" % node_data["type"])
return null
# Get outgoing connections from a node
func _get_outgoing_connections(node_id: String) -> Array:
var outgoing = []
for conn in connections:
if conn["from_node"] == node_id:
outgoing.append(conn)
return outgoing
# Get incoming connections to a node
func _get_incoming_connections(node_id: String) -> Array:
var incoming = []
for conn in connections:
if conn["to_node"] == node_id:
incoming.append(conn)
return incoming