From 44d3f10875ecf5f5b53e2416bf557ff7cec07f2c Mon Sep 17 00:00:00 2001 From: Bryce Date: Fri, 1 Aug 2025 08:34:51 -0700 Subject: [PATCH] progress --- .gitattributes | 0 .gitignore | 0 addons/cutscene_editor/CHANGES.md | 0 .../cutscene_editor/CutsceneEditorPlugin.gd | 19 +- addons/cutscene_editor/README.md | 0 .../editor/CutsceneGenerator.gd | 63 ++-- .../editor/CutsceneGraphEdit.gd | 50 +--- .../cutscene_editor/editor/PreviewManager.gd | 274 ------------------ addons/cutscene_editor/editor/PreviewPanel.gd | 186 ------------ .../cutscene_editor/editor/UndoRedoManager.gd | 0 .../editor/nodes/AnimationActionNode.gd | 2 +- .../editor/nodes/AnimationActionNode.tscn | 0 .../editor/nodes/BaseGraphNode.gd | 2 +- .../editor/nodes/DialogueActionNode.gd | 2 +- .../editor/nodes/DialogueActionNode.tscn | 0 .../cutscene_editor/editor/nodes/EntryNode.gd | 2 +- .../editor/nodes/EntryNode.tscn | 14 +- .../cutscene_editor/editor/nodes/ExitNode.gd | 2 +- .../editor/nodes/ExitNode.tscn | 12 +- .../editor/nodes/MoveActionNode.gd | 12 +- .../editor/nodes/MoveActionNode.tscn | 4 +- .../editor/nodes/ParallelGroupNode.gd | 2 +- .../editor/nodes/TurnActionNode.gd | 2 +- .../editor/nodes/TurnActionNode.tscn | 0 .../editor/nodes/WaitActionNode.gd | 0 .../editor/nodes/WaitActionNode.tscn | 0 .../editor/resources/CutsceneResource.gd | 0 .../cutscene_editor/icons/icon_animation.svg | 0 .../icons/icon_animation.svg.import | 0 .../cutscene_editor/icons/icon_dialogue.svg | 0 .../icons/icon_dialogue.svg.import | 0 addons/cutscene_editor/icons/icon_entry.svg | 0 .../icons/icon_entry.svg.import | 0 addons/cutscene_editor/icons/icon_exit.svg | 0 .../icons/icon_exit.svg.import | 0 addons/cutscene_editor/icons/icon_move.svg | 0 .../icons/icon_move.svg.import | 0 .../cutscene_editor/icons/icon_parallel.svg | 0 .../icons/icon_parallel.svg.import | 0 addons/cutscene_editor/icons/icon_turn.svg | 0 .../icons/icon_turn.svg.import | 0 addons/cutscene_editor/icons/icon_wait.svg | 0 .../icons/icon_wait.svg.import | 0 addons/cutscene_editor/plugin.cfg | 0 .../tests/test_cutscene_resource.gd | 0 .../tests/test_cutscene_resource.tscn | 0 cutscene/Action.gd | 0 cutscene/CutsceneManager.gd | 196 ++++++------- cutscene/README.md | 0 cutscene/actions/AnimationAction.gd | 0 cutscene/actions/DialogueAction.gd | 0 cutscene/actions/MoveAction.gd | 1 - cutscene/actions/TurnAction.gd | 0 cutscene/actions/WaitAction.gd | 0 example_cutscene.tscn | 2 +- hello.tres | 34 --- icon.svg | 0 icon.svg.import | 0 main.tscn | 0 plans/cutscene_data_structure.md | 0 plans/cutscene_documentation_plan.md | 0 plans/cutscene_generator_changes.md | 0 plans/cutscene_graph_edit_changes.md | 0 plans/cutscene_resource_analysis.md | 0 plans/cutscene_resource_implementation.md | 0 ...utscene_resource_implementation_summary.md | 0 plans/cutscene_test_plan.md | 0 project.godot | 2 +- scripts/cutscene/CutsceneManager.gd | 0 tes2265.tmp | 18 ++ test_cutscene.tres | 101 +++++++ test_cutscene2.gd | 234 +++++++++++++++ test_cutscene2.tscn | 18 ++ test_dependency_cutscene.gd | 50 ++++ test_dependency_cutscene.tscn | 6 + test_resource_cutscene.gd | 8 +- test_resource_cutscene.tscn | 0 77 files changed, 605 insertions(+), 713 deletions(-) mode change 100644 => 100755 .gitattributes mode change 100644 => 100755 .gitignore mode change 100644 => 100755 addons/cutscene_editor/CHANGES.md mode change 100644 => 100755 addons/cutscene_editor/CutsceneEditorPlugin.gd mode change 100644 => 100755 addons/cutscene_editor/README.md mode change 100644 => 100755 addons/cutscene_editor/editor/CutsceneGenerator.gd mode change 100644 => 100755 addons/cutscene_editor/editor/CutsceneGraphEdit.gd delete mode 100644 addons/cutscene_editor/editor/PreviewManager.gd delete mode 100644 addons/cutscene_editor/editor/PreviewPanel.gd mode change 100644 => 100755 addons/cutscene_editor/editor/UndoRedoManager.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/AnimationActionNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/AnimationActionNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/BaseGraphNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/DialogueActionNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/DialogueActionNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/EntryNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/EntryNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/ExitNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/ExitNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/MoveActionNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/MoveActionNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/ParallelGroupNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/TurnActionNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/TurnActionNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/WaitActionNode.gd mode change 100644 => 100755 addons/cutscene_editor/editor/nodes/WaitActionNode.tscn mode change 100644 => 100755 addons/cutscene_editor/editor/resources/CutsceneResource.gd mode change 100644 => 100755 addons/cutscene_editor/icons/icon_animation.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_animation.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_dialogue.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_dialogue.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_entry.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_entry.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_exit.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_exit.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_move.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_move.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_parallel.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_parallel.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_turn.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_turn.svg.import mode change 100644 => 100755 addons/cutscene_editor/icons/icon_wait.svg mode change 100644 => 100755 addons/cutscene_editor/icons/icon_wait.svg.import mode change 100644 => 100755 addons/cutscene_editor/plugin.cfg mode change 100644 => 100755 addons/cutscene_editor/tests/test_cutscene_resource.gd mode change 100644 => 100755 addons/cutscene_editor/tests/test_cutscene_resource.tscn mode change 100644 => 100755 cutscene/Action.gd mode change 100644 => 100755 cutscene/CutsceneManager.gd mode change 100644 => 100755 cutscene/README.md mode change 100644 => 100755 cutscene/actions/AnimationAction.gd mode change 100644 => 100755 cutscene/actions/DialogueAction.gd mode change 100644 => 100755 cutscene/actions/MoveAction.gd mode change 100644 => 100755 cutscene/actions/TurnAction.gd mode change 100644 => 100755 cutscene/actions/WaitAction.gd mode change 100644 => 100755 example_cutscene.tscn delete mode 100644 hello.tres mode change 100644 => 100755 icon.svg mode change 100644 => 100755 icon.svg.import mode change 100644 => 100755 main.tscn mode change 100644 => 100755 plans/cutscene_data_structure.md mode change 100644 => 100755 plans/cutscene_documentation_plan.md mode change 100644 => 100755 plans/cutscene_generator_changes.md mode change 100644 => 100755 plans/cutscene_graph_edit_changes.md mode change 100644 => 100755 plans/cutscene_resource_analysis.md mode change 100644 => 100755 plans/cutscene_resource_implementation.md mode change 100644 => 100755 plans/cutscene_resource_implementation_summary.md mode change 100644 => 100755 plans/cutscene_test_plan.md mode change 100644 => 100755 project.godot delete mode 100644 scripts/cutscene/CutsceneManager.gd create mode 100755 tes2265.tmp create mode 100755 test_cutscene.tres create mode 100755 test_cutscene2.gd create mode 100755 test_cutscene2.tscn create mode 100755 test_dependency_cutscene.gd create mode 100755 test_dependency_cutscene.tscn mode change 100644 => 100755 test_resource_cutscene.gd mode change 100644 => 100755 test_resource_cutscene.tscn diff --git a/.gitattributes b/.gitattributes old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/CHANGES.md b/addons/cutscene_editor/CHANGES.md old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/CutsceneEditorPlugin.gd b/addons/cutscene_editor/CutsceneEditorPlugin.gd old mode 100644 new mode 100755 index ca34657..3a8258e --- a/addons/cutscene_editor/CutsceneEditorPlugin.gd +++ b/addons/cutscene_editor/CutsceneEditorPlugin.gd @@ -59,9 +59,6 @@ func _create_dock_panel() -> Control: graph_edit = _create_graph_edit() main_vbox.add_child(graph_edit) - # Set up preview system - _setup_preview_system() - # Set up undo/redo system _setup_undo_redo_system() @@ -113,13 +110,7 @@ func _create_toolbar() -> Control: # Separator var separator2 = VSeparator.new() toolbar.add_child(separator2) - - # Preview button - var preview_button = Button.new() - preview_button.text = "Preview" - preview_button.icon = get_editor_interface().get_base_control().get_theme_icon("Play", "EditorIcons") - preview_button.connect("pressed", _on_preview_pressed) - toolbar.add_child(preview_button) + return toolbar @@ -149,10 +140,6 @@ func _create_graph_edit() -> GraphEdit: return graph -func _setup_preview_system() -> void: - # Set up the preview system - if graph_edit: - graph_edit.setup_preview() func _setup_undo_redo_system() -> void: # Set up the undo/redo system @@ -209,7 +196,3 @@ func _on_undo_pressed() -> void: func _on_redo_pressed() -> void: if graph_edit: graph_edit.redo() - -func _on_preview_pressed() -> void: - if graph_edit: - graph_edit.start_preview() diff --git a/addons/cutscene_editor/README.md b/addons/cutscene_editor/README.md old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/CutsceneGenerator.gd b/addons/cutscene_editor/editor/CutsceneGenerator.gd old mode 100644 new mode 100755 index 1c648d7..1e56ad0 --- a/addons/cutscene_editor/editor/CutsceneGenerator.gd +++ b/addons/cutscene_editor/editor/CutsceneGenerator.gd @@ -9,7 +9,7 @@ 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: +func generate_cutscene(scene: Node, cutscene_resource: CutsceneResource) -> CutsceneManager: # Clear previous data graph_nodes.clear() connections.clear() @@ -30,7 +30,7 @@ func generate_cutscene(cutscene_resource: CutsceneResource) -> CutsceneManager: return cutscene_manager # Build action sequence starting from entry node - _build_action_sequence(entry_node, cutscene_manager) + _build_action_sequence(scene, entry_node, cutscene_manager) return cutscene_manager @@ -43,45 +43,42 @@ func _find_entry_node() -> Dictionary: 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"]) +func _build_action_sequence(scene: Node, start_node: Dictionary, cutscene_manager: CutsceneManager) -> void: + # First pass: Create all actions + var action_map = {} # Map of node IDs to action instances - # 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() + for node_id in graph_nodes: + var node_data = graph_nodes[node_id] - # 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(): + # Skip entry and exit nodes as they don't create actions + if node_data["type"] == "entry" or node_data["type"] == "exit": continue # Create action for regular nodes - var action = _create_action_from_node(node_data) + var action = _create_action_from_node(scene, node_data) if action: - cutscene_manager.add_action(action) + action_map[node_id] = action + + # Second pass: Add actions with their dependencies + for node_id in action_map: + print("setting up", node_id) + var action = action_map[node_id] - # 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"]) + # Get dependencies (incoming connections) + var deps = [] + var incoming_connections = _get_incoming_connections(node_id) + + for conn in incoming_connections: + # Only add as dependency if the source node creates an action + var from_node_data = graph_nodes.get(conn["from_node"], {}) + if not from_node_data.is_empty() and from_node_data["type"] != "entry": + deps.append(conn["from_node"]) + + # Add action with dependencies + cutscene_manager.add_action(node_id, action, deps) # Create an action instance from node data -func _create_action_from_node(node_data: Dictionary): +func _create_action_from_node(scene: Node, node_data: Dictionary): var parameters = node_data["parameters"] match node_data["type"]: @@ -93,7 +90,7 @@ func _create_action_from_node(node_data: Dictionary): # 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 character_node = scene.find_child(character_path) # This would be resolved at runtime var target_position = Vector2(target_x, target_y) return MoveAction.new(character_node, target_position, speed) diff --git a/addons/cutscene_editor/editor/CutsceneGraphEdit.gd b/addons/cutscene_editor/editor/CutsceneGraphEdit.gd old mode 100644 new mode 100755 index 6f69a72..e50f11e --- a/addons/cutscene_editor/editor/CutsceneGraphEdit.gd +++ b/addons/cutscene_editor/editor/CutsceneGraphEdit.gd @@ -16,9 +16,6 @@ var node_counter: int = 0 # For generating unique node IDs var current_cutscene: CutsceneResource # The cutscene being edited # Preview properties -var preview_manager: PreviewManager -var preview_panel: PreviewPanel - # Undo/Redo properties var undo_redo_manager: UndoRedoManager @@ -289,7 +286,7 @@ func _on_graph_node_deleted(node: BaseGraphNode) -> void: # Remove all connections to/from this node var connections = get_connection_list() for connection in connections: - if connection["from_node"] == node.node_id or connection["to_node"] == node.node_id: + if connection["from_node"] == node.name or connection["to_node"] == node.name: disconnect_node(connection["from_node"], connection["from_port"], connection["to_node"], connection["to_port"]) @@ -332,6 +329,9 @@ func clear_graph() -> void: # Emit signal emit_signal("graph_changed") +func get_graph_node_by_id(id: String): + return find_child(id) + # Load graph from cutscene resource func load_from_cutscene(cutscene: CutsceneResource) -> void: # Clear existing graph @@ -343,14 +343,16 @@ func load_from_cutscene(cutscene: CutsceneResource) -> void: # Create nodes from cutscene data for node_data in cutscene.nodes: var node = add_node(node_data["type"], Vector2(node_data["position"]["x"], node_data["position"]["y"])) + node.owner=self if node: - node.node_id = node_data["id"] + node.name = node_data["id"] # Set node parameters for param_name in node_data["parameters"]: node.set_parameter(param_name, node_data["parameters"][param_name]) # Create connections from cutscene data for connection_data in cutscene.connections: + print(get_graph_node_by_id(connection_data["from_node"])) connect_node(connection_data["from_node"], connection_data["from_port"], connection_data["to_node"], connection_data["to_port"]) @@ -370,7 +372,7 @@ func save_to_cutscene() -> CutsceneResource: for child in get_children(): if child is BaseGraphNode: var node_data = { - "id": child.node_id, + "id": str(child.name), "type": child.node_type, "position": { "x": child.position_offset.x, @@ -384,9 +386,9 @@ func save_to_cutscene() -> CutsceneResource: for connection in get_connection_list(): var connection_data = { "id": _generate_unique_connection_id(), - "from_node": connection["from_node"], + "from_node": str(connection["from_node"]), "from_port": connection["from_port"], - "to_node": connection["to_node"], + "to_node": str(connection["to_node"]), "to_port": connection["to_port"] } current_cutscene.connections.append(connection_data) @@ -398,39 +400,7 @@ func _generate_unique_connection_id() -> String: return "conn_" + str(Time.get_ticks_msec()) -# Set up preview system -func setup_preview() -> void: - # Create preview manager - preview_manager = PreviewManager.new() - add_child(preview_manager) - - # Create preview panel - preview_panel = PreviewPanel.new() - preview_panel.set_preview_manager(preview_manager) - preview_panel.set_graph_edit(self) - - # Add to editor interface (this would be added to the editor UI) - # For now, we'll just keep a reference to it -# Start preview -func start_preview() -> void: - if preview_manager: - preview_manager.start_preview() - -# Stop preview -func stop_preview() -> void: - if preview_manager: - preview_manager.stop_preview() - -# Pause preview -func pause_preview() -> void: - if preview_manager: - preview_manager.pause_preview() - -# Resume preview -func resume_preview() -> void: - if preview_manager: - preview_manager.resume_preview() # Set up undo/redo system func _setup_undo_redo() -> void: diff --git a/addons/cutscene_editor/editor/PreviewManager.gd b/addons/cutscene_editor/editor/PreviewManager.gd deleted file mode 100644 index 13700bc..0000000 --- a/addons/cutscene_editor/editor/PreviewManager.gd +++ /dev/null @@ -1,274 +0,0 @@ -@tool -class_name PreviewManager -extends Node - -# Manager for real-time cutscene preview - -# Signals -signal preview_started() -signal preview_stopped() -signal preview_paused() -signal preview_resumed() -signal preview_progress(progress: float) -signal node_activated(node_name: String) -signal node_completed(node_name: String) - -# Properties -var is_previewing: bool = false -var is_paused: bool = false -var current_cutscene: CutsceneManager -var preview_scene: Node2D # The scene being previewed -var preview_characters: Dictionary = {} # Map of character names to nodes -var graph_edit: CutsceneGraphEdit # Reference to the graph editor - -# Preview settings -var preview_speed: float = 1.0 -var show_debug_info: bool = true - -# Initialize the preview manager -func _init() -> void: - name = "PreviewManager" - -# Set up the preview with a graph editor -func setup_preview(graph: CutsceneGraphEdit) -> void: - graph_edit = graph - - # Connect to graph change signals - if graph_edit: - graph_edit.connect("graph_changed", _on_graph_changed) - -# Start the preview -func start_preview() -> void: - if is_previewing: - return - - # Create preview scene - _setup_preview_scene() - - # Generate cutscene from current graph - var cutscene_resource = graph_edit.save_to_cutscene() - var generator = CutsceneGenerator.new() - current_cutscene = generator.generate_cutscene(cutscene_resource) - - # Add cutscene to preview scene - if preview_scene and current_cutscene: - preview_scene.add_child(current_cutscene) - - # Connect to cutscene signals for feedback - _connect_cutscene_signals() - - # Start the cutscene - current_cutscene.start() - - # Update state - is_previewing = true - is_paused = false - emit_signal("preview_started") - -# Stop the preview -func stop_preview() -> void: - if not is_previewing: - return - - # Stop the cutscene - if current_cutscene: - current_cutscene.stop() - _disconnect_cutscene_signals() - - # Remove from preview scene - if current_cutscene.get_parent() == preview_scene: - preview_scene.remove_child(current_cutscene) - current_cutscene.queue_free() - - # Clean up preview scene - _cleanup_preview_scene() - - # Update state - is_previewing = false - is_paused = false - emit_signal("preview_stopped") - -# Pause the preview -func pause_preview() -> void: - if not is_previewing or is_paused: - return - - if current_cutscene: - current_cutscene.pause() - is_paused = true - emit_signal("preview_paused") - -# Resume the preview -func resume_preview() -> void: - if not is_previewing or not is_paused: - return - - if current_cutscene: - current_cutscene.resume() - is_paused = false - emit_signal("preview_resumed") - -# Set preview speed -func set_preview_speed(speed: float) -> void: - preview_speed = speed - # In a real implementation, this would affect the time scale - # of the preview scene - -# Set up the preview scene -func _setup_preview_scene() -> void: - # Create or reuse preview scene - if not preview_scene: - preview_scene = Node2D.new() - preview_scene.name = "PreviewScene" - add_child(preview_scene) - - # Set up characters for preview - _setup_preview_characters() - -# Set up characters for preview -func _setup_preview_characters() -> void: - # Clear existing characters - preview_characters.clear() - - # Create placeholder characters for preview - # In a real implementation, this would load actual character scenes - var character1 = _create_preview_character("Character1", Vector2(100, 100)) - var character2 = _create_preview_character("Character2", Vector2(200, 100)) - - preview_characters["Character1"] = character1 - preview_characters["Character2"] = character2 - - # Add to preview scene - if preview_scene: - preview_scene.add_child(character1) - preview_scene.add_child(character2) - -# Create a preview character -func _create_preview_character(name: String, position: Vector2) -> Node2D: - var character = Node2D.new() - character.name = name - character.position = position - - # Add a visual representation - var sprite = Polygon2D.new() - sprite.polygon = PackedVector2Array([ - Vector2(-10, -20), - Vector2(-30, 0), - Vector2(-10, 20), - Vector2(10, 20), - Vector2(30, 0), - Vector2(10, -20) - ]) - sprite.color = Color(0.5, 0.7, 1.0) - character.add_child(sprite) - - return character - -# Clean up the preview scene -func _cleanup_preview_scene() -> void: - # Remove characters - for char_name in preview_characters: - var character = preview_characters[char_name] - if character.get_parent() == preview_scene: - preview_scene.remove_child(character) - character.queue_free() - - preview_characters.clear() - -# Connect to cutscene signals for feedback -func _connect_cutscene_signals() -> void: - if not current_cutscene: - return - - # Disconnect existing connections - _disconnect_cutscene_signals() - - # Connect to signals - current_cutscene.connect("cutscene_started", _on_cutscene_started) - current_cutscene.connect("cutscene_completed", _on_cutscene_completed) - current_cutscene.connect("cutscene_paused", _on_cutscene_paused) - current_cutscene.connect("cutscene_resumed", _on_cutscene_resumed) - current_cutscene.connect("action_started", _on_action_started) - current_cutscene.connect("action_completed", _on_action_completed) - -# Disconnect from cutscene signals -func _disconnect_cutscene_signals() -> void: - if not current_cutscene: - return - - if current_cutscene.is_connected("cutscene_started", _on_cutscene_started): - current_cutscene.disconnect("cutscene_started", _on_cutscene_started) - if current_cutscene.is_connected("cutscene_completed", _on_cutscene_completed): - current_cutscene.disconnect("cutscene_completed", _on_cutscene_completed) - if current_cutscene.is_connected("cutscene_paused", _on_cutscene_paused): - current_cutscene.disconnect("cutscene_paused", _on_cutscene_paused) - if current_cutscene.is_connected("cutscene_resumed", _on_cutscene_resumed): - current_cutscene.disconnect("cutscene_resumed", _on_cutscene_resumed) - if current_cutscene.is_connected("action_started", _on_action_started): - current_cutscene.disconnect("action_started", _on_action_started) - if current_cutscene.is_connected("action_completed", _on_action_completed): - current_cutscene.disconnect("action_completed", _on_action_completed) - -# Handle graph changes -func _on_graph_changed() -> void: - # If we're previewing, restart the preview to reflect changes - if is_previewing: - stop_preview() - start_preview() - -# Handle cutscene started -func _on_cutscene_started() -> void: - emit_signal("preview_started") - -# Handle cutscene completed -func _on_cutscene_completed() -> void: - emit_signal("preview_stopped") - is_previewing = false - is_paused = false - -# Handle cutscene paused -func _on_cutscene_paused() -> void: - emit_signal("preview_paused") - is_paused = true - -# Handle cutscene resumed -func _on_cutscene_resumed() -> void: - emit_signal("preview_resumed") - is_paused = false - -# Handle action started -func _on_action_started(action: Action) -> void: - # Find the corresponding node in the graph and highlight it - var node_name = _find_node_for_action(action) - if node_name: - emit_signal("node_activated", node_name) - - # Update graph editor visualization - if graph_edit: - var node = graph_edit.get_node_or_null(node_name) - if node and node.has_method("set_state"): - node.set_state(BaseGraphNode.NodeState.ACTIVE) - -# Handle action completed -func _on_action_completed(action: Action) -> void: - # Find the corresponding node in the graph and mark as completed - var node_name = _find_node_for_action(action) - if node_name: - emit_signal("node_completed", node_name) - - # Update graph editor visualization - if graph_edit: - var node = graph_edit.get_node_or_null(node_name) - if node and node.has_method("set_state"): - node.set_state(BaseGraphNode.NodeState.COMPLETED) - -# Find node corresponding to an action -func _find_node_for_action(action: Action) -> String: - # This would need to map actions to nodes - # In a real implementation, we would store this mapping when generating the cutscene - # For now, we'll return a placeholder - return "" - -# Get the preview scene for display -func get_preview_scene() -> Node2D: - return preview_scene \ No newline at end of file diff --git a/addons/cutscene_editor/editor/PreviewPanel.gd b/addons/cutscene_editor/editor/PreviewPanel.gd deleted file mode 100644 index 2cfb9e0..0000000 --- a/addons/cutscene_editor/editor/PreviewPanel.gd +++ /dev/null @@ -1,186 +0,0 @@ -@tool -class_name PreviewPanel -extends PanelContainer - -# UI panel for displaying the preview - -# UI elements -var preview_viewport: SubViewport -var preview_texture: TextureRect -var controls_container: HBoxContainer -var play_button: Button -var pause_button: Button -var stop_button: Button -var speed_slider: HSlider -var progress_bar: ProgressBar -var debug_label: Label - -# Properties -var preview_manager: PreviewManager -var is_playing: bool = false - -# Initialize the preview panel -func _ready() -> void: - _setup_ui() - _setup_signals() - -# Set up the UI -func _setup_ui() -> void: - # Main container - var main_vbox = VBoxContainer.new() - main_vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL - main_vbox.size_flags_vertical = Control.SIZE_EXPAND_FILL - add_child(main_vbox) - - # Preview viewport - var viewport_container = AspectRatioContainer.new() - viewport_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL - viewport_container.size_flags_vertical = Control.SIZE_EXPAND_FILL - viewport_container.ratio = 16.0/9.0 - main_vbox.add_child(viewport_container) - - preview_viewport = SubViewport.new() - preview_viewport.size = Vector2i(800, 450) - preview_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS - viewport_container.add_child(preview_viewport) - - preview_texture = TextureRect.new() - preview_texture.expand = true - preview_texture.size_flags_horizontal = Control.SIZE_EXPAND_FILL - preview_texture.size_flags_vertical = Control.SIZE_EXPAND_FILL - preview_texture.texture = preview_viewport.get_texture() - viewport_container.add_child(preview_texture) - - # Controls - controls_container = HBoxContainer.new() - controls_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL - main_vbox.add_child(controls_container) - - play_button = Button.new() - play_button.text = "▶" - play_button.flat = true - controls_container.add_child(play_button) - - pause_button = Button.new() - pause_button.text = "⏸" - pause_button.flat = true - controls_container.add_child(pause_button) - - stop_button = Button.new() - stop_button.text = "⏹" - stop_button.flat = true - controls_container.add_child(stop_button) - - var speed_label = Label.new() - speed_label.text = "Speed:" - controls_container.add_child(speed_label) - - speed_slider = HSlider.new() - speed_slider.min = 0.1 - speed_slider.max = 2.0 - speed_slider.step = 0.1 - speed_slider.value = 1.0 - speed_slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL - controls_container.add_child(speed_slider) - - # Progress bar - progress_bar = ProgressBar.new() - progress_bar.size_flags_horizontal = Control.SIZE_EXPAND_FILL - progress_bar.percent_visible = true - main_vbox.add_child(progress_bar) - - # Debug info - debug_label = Label.new() - debug_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL - main_vbox.add_child(debug_label) - -# Set up signal connections -func _setup_signals() -> void: - play_button.connect("pressed", _on_play_pressed) - pause_button.connect("pressed", _on_pause_pressed) - stop_button.connect("pressed", _on_stop_pressed) - speed_slider.connect("value_changed", _on_speed_changed) - -# Set the preview manager -func set_preview_manager(manager: PreviewManager) -> void: - preview_manager = manager - - # Connect to preview manager signals - if preview_manager: - preview_manager.connect("preview_started", _on_preview_started) - preview_manager.connect("preview_stopped", _on_preview_stopped) - preview_manager.connect("preview_paused", _on_preview_paused) - preview_manager.connect("preview_resumed", _on_preview_resumed) - preview_manager.connect("preview_progress", _on_preview_progress) - preview_manager.connect("node_activated", _on_node_activated) - preview_manager.connect("node_completed", _on_node_completed) - -# Set the graph editor -func set_graph_edit(graph_edit: CutsceneGraphEdit) -> void: - if preview_manager: - preview_manager.setup_preview(graph_edit) - - # Add preview scene to viewport - var preview_scene = preview_manager.get_preview_scene() - if preview_scene and preview_scene.get_parent() != preview_viewport: - preview_viewport.add_child(preview_scene) - -# Handle play button press -func _on_play_pressed() -> void: - if preview_manager: - if is_playing: - preview_manager.resume_preview() - else: - preview_manager.start_preview() - -# Handle pause button press -func _on_pause_pressed() -> void: - if preview_manager: - preview_manager.pause_preview() - -# Handle stop button press -func _on_stop_pressed() -> void: - if preview_manager: - preview_manager.stop_preview() - -# Handle speed slider change -func _on_speed_changed(value: float) -> void: - if preview_manager: - preview_manager.set_preview_speed(value) - -# Handle preview started -func _on_preview_started() -> void: - is_playing = true - play_button.text = "⏸" - debug_label.text = "Preview started" - -# Handle preview stopped -func _on_preview_stopped() -> void: - is_playing = false - play_button.text = "▶" - progress_bar.value = 0 - debug_label.text = "Preview stopped" - -# Handle preview paused -func _on_preview_paused() -> void: - is_playing = false - play_button.text = "▶" - debug_label.text = "Preview paused" - -# Handle preview resumed -func _on_preview_resumed() -> void: - is_playing = true - play_button.text = "⏸" - debug_label.text = "Preview resumed" - -# Handle preview progress -func _on_preview_progress(progress: float) -> void: - progress_bar.value = progress * 100 - -# Handle node activated -func _on_node_activated(node_name: String) -> void: - debug_label.text = "Executing: %s" % node_name - -# Handle node completed -func _on_node_completed(node_name: String) -> void: - debug_label.text = "Completed: %s" % node_name \ No newline at end of file diff --git a/addons/cutscene_editor/editor/UndoRedoManager.gd b/addons/cutscene_editor/editor/UndoRedoManager.gd old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/nodes/AnimationActionNode.gd b/addons/cutscene_editor/editor/nodes/AnimationActionNode.gd old mode 100644 new mode 100755 index 8ca2817..b869380 --- a/addons/cutscene_editor/editor/nodes/AnimationActionNode.gd +++ b/addons/cutscene_editor/editor/nodes/AnimationActionNode.gd @@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd" func _init() -> void: node_type = "animation" - node_id = "animation_" + str(randi()) + name = "animation_" + str(randi()) title = "Animation" modulate = Color(0.8, 0.4, 0.8) # Purple diff --git a/addons/cutscene_editor/editor/nodes/AnimationActionNode.tscn b/addons/cutscene_editor/editor/nodes/AnimationActionNode.tscn old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/nodes/BaseGraphNode.gd b/addons/cutscene_editor/editor/nodes/BaseGraphNode.gd old mode 100644 new mode 100755 index f70d925..23e2c4d --- a/addons/cutscene_editor/editor/nodes/BaseGraphNode.gd +++ b/addons/cutscene_editor/editor/nodes/BaseGraphNode.gd @@ -20,7 +20,7 @@ enum NodeState { # Properties var node_type: String = "base" -var node_id: String # Unique identifier for the node + var action_parameters: Dictionary = {} # Stores parameter values var current_state: int = NodeState.IDLE var error_message: String = "" diff --git a/addons/cutscene_editor/editor/nodes/DialogueActionNode.gd b/addons/cutscene_editor/editor/nodes/DialogueActionNode.gd old mode 100644 new mode 100755 index 5c9e0d2..a5a2d77 --- a/addons/cutscene_editor/editor/nodes/DialogueActionNode.gd +++ b/addons/cutscene_editor/editor/nodes/DialogueActionNode.gd @@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd" func _init() -> void: node_type = "dialogue" - node_id = "dialogue_" + str(randi()) + name = "dialogue_" + str(randi()) title = "Dialogue" modulate = Color(1.0, 1.0, 0.5) # Yellow resizable=true diff --git a/addons/cutscene_editor/editor/nodes/DialogueActionNode.tscn b/addons/cutscene_editor/editor/nodes/DialogueActionNode.tscn old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/nodes/EntryNode.gd b/addons/cutscene_editor/editor/nodes/EntryNode.gd old mode 100644 new mode 100755 index 3e73b02..01e1e5c --- a/addons/cutscene_editor/editor/nodes/EntryNode.gd +++ b/addons/cutscene_editor/editor/nodes/EntryNode.gd @@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd" func _init() -> void: node_type = "entry" - node_id = "entry_" + str(randi()) + name = "entry_" + str(randi()) title = "Start" modulate = Color(0.5, 1.0, 0.5) # Light green diff --git a/addons/cutscene_editor/editor/nodes/EntryNode.tscn b/addons/cutscene_editor/editor/nodes/EntryNode.tscn old mode 100644 new mode 100755 index 32acc75..8828ca0 --- a/addons/cutscene_editor/editor/nodes/EntryNode.tscn +++ b/addons/cutscene_editor/editor/nodes/EntryNode.tscn @@ -1,15 +1,23 @@ -[gd_scene load_steps=2 format=3 uid="uid://entrynodetscn"] +[gd_scene load_steps=2 format=3 uid="uid://sfwelq3tmwkv"] + [ext_resource type="Script" path="res://addons/cutscene_editor/editor/nodes/EntryNode.gd" id="1_entry"] + [node name="EntryNode" type="GraphNode"] -modulate = Color(0.5, 1.0, 0.5, 1) +modulate = Color(0.5, 1, 0.5, 1) custom_minimum_size = Vector2(100, 0) title = "Start" slot/0/left_enabled = false slot/0/left_type = 0 slot/0/left_color = Color(0, 0, 0, 0) +slot/0/left_icon = null slot/0/right_enabled = true slot/0/right_type = 0 slot/0/right_color = Color(0, 0, 0, 1) slot/0/right_icon = null slot/0/draw_stylebox = true -script = ExtResource("1_entry") \ No newline at end of file +script = ExtResource("1_entry") + +[node name="Label" type="Label" parent="."] +layout_mode = 2 +text = "completed +" diff --git a/addons/cutscene_editor/editor/nodes/ExitNode.gd b/addons/cutscene_editor/editor/nodes/ExitNode.gd old mode 100644 new mode 100755 index b31100c..479911a --- a/addons/cutscene_editor/editor/nodes/ExitNode.gd +++ b/addons/cutscene_editor/editor/nodes/ExitNode.gd @@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd" func _init() -> void: node_type = "exit" - node_id = "exit_" + str(randi()) + name = "exit_" + str(randi()) title = "End" modulate = Color(1.0, 0.5, 0.5) # Light red diff --git a/addons/cutscene_editor/editor/nodes/ExitNode.tscn b/addons/cutscene_editor/editor/nodes/ExitNode.tscn old mode 100644 new mode 100755 index 9fe529a..e9107da --- a/addons/cutscene_editor/editor/nodes/ExitNode.tscn +++ b/addons/cutscene_editor/editor/nodes/ExitNode.tscn @@ -1,14 +1,22 @@ [gd_scene load_steps=2 format=3 uid="uid://exitnodetscn"] + [ext_resource type="Script" path="res://addons/cutscene_editor/editor/nodes/ExitNode.gd" id="1_exit"] + [node name="ExitNode" type="GraphNode"] -modulate = Color(1.0, 0.5, 0.5, 1) +modulate = Color(1, 0.5, 0.5, 1) custom_minimum_size = Vector2(100, 0) title = "End" slot/0/left_enabled = true slot/0/left_type = 0 slot/0/left_color = Color(0, 0, 0, 1) +slot/0/left_icon = null slot/0/right_enabled = false slot/0/right_type = 0 slot/0/right_color = Color(0, 0, 0, 0) +slot/0/right_icon = null slot/0/draw_stylebox = true -script = ExtResource("1_exit") \ No newline at end of file +script = ExtResource("1_exit") + +[node name="Label" type="Label" parent="."] +layout_mode = 2 +text = "Dependency" diff --git a/addons/cutscene_editor/editor/nodes/MoveActionNode.gd b/addons/cutscene_editor/editor/nodes/MoveActionNode.gd old mode 100644 new mode 100755 index d67a61a..5d7fbe1 --- a/addons/cutscene_editor/editor/nodes/MoveActionNode.gd +++ b/addons/cutscene_editor/editor/nodes/MoveActionNode.gd @@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd" func _init() -> void: node_type = "move" - node_id = "move_" + str(randi()) + name = "move_" + str(randi()) title = "Move" modulate = Color(0.4, 0.6, 1.0) # Blue @@ -22,6 +22,16 @@ func _ready() -> void: action_parameters["target_y"] = 0.0 action_parameters["speed"] = 100.0 +func set_parameter(pname, value) -> void: + super.set_parameter(name, value) + if pname == "character": + $VBoxContainer/CharacterEDit.text = value + elif pname == "target_x": + $VBoxContainer/HBoxContainer/x.text = value + elif pname == "target_y": + $VBoxContainer/HBoxContainer/y.text = value + elif pname == "speed": + $VBoxContainer/speed.text = value func _on_character_changed(new_text: String) -> void: set_parameter("character", new_text) diff --git a/addons/cutscene_editor/editor/nodes/MoveActionNode.tscn b/addons/cutscene_editor/editor/nodes/MoveActionNode.tscn old mode 100644 new mode 100755 index b966a1f..c837cce --- a/addons/cutscene_editor/editor/nodes/MoveActionNode.tscn +++ b/addons/cutscene_editor/editor/nodes/MoveActionNode.tscn @@ -23,7 +23,7 @@ layout_mode = 2 [node name="Character" type="Label" parent="VBoxContainer"] layout_mode = 2 -[node name="TextEdit" type="LineEdit" parent="VBoxContainer"] +[node name="CharacterEDit" type="LineEdit" parent="VBoxContainer"] custom_minimum_size = Vector2(0, 32.865) layout_mode = 2 text = "aoeu" @@ -49,7 +49,7 @@ text = "Speed" [node name="speed" type="LineEdit" parent="VBoxContainer"] layout_mode = 2 -[connection signal="text_changed" from="VBoxContainer/TextEdit" to="." method="_on_character_changed"] +[connection signal="text_changed" from="VBoxContainer/CharacterEDit" to="." method="_on_character_changed"] [connection signal="text_changed" from="VBoxContainer/HBoxContainer/x" to="." method="_on_target_x_changed"] [connection signal="text_changed" from="VBoxContainer/HBoxContainer/y" to="." method="_on_target_y_changed"] [connection signal="text_change_rejected" from="VBoxContainer/speed" to="." method="_on_speed_text_change_rejected"] diff --git a/addons/cutscene_editor/editor/nodes/ParallelGroupNode.gd b/addons/cutscene_editor/editor/nodes/ParallelGroupNode.gd old mode 100644 new mode 100755 index b781e19..6cf06d2 --- a/addons/cutscene_editor/editor/nodes/ParallelGroupNode.gd +++ b/addons/cutscene_editor/editor/nodes/ParallelGroupNode.gd @@ -14,7 +14,7 @@ var container_rect: PanelContainer # Visual container for child nodes func _init() -> void: node_type = "parallel" - node_id = "parallel_" + str(randi()) + name = "parallel_" + str(randi()) title = "Parallel Group" modulate = Color(1.0, 0.6, 0.2) # Orange diff --git a/addons/cutscene_editor/editor/nodes/TurnActionNode.gd b/addons/cutscene_editor/editor/nodes/TurnActionNode.gd old mode 100644 new mode 100755 index 102b4ca..ea26146 --- a/addons/cutscene_editor/editor/nodes/TurnActionNode.gd +++ b/addons/cutscene_editor/editor/nodes/TurnActionNode.gd @@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd" func _init() -> void: node_type = "turn" - node_id = "turn_" + str(randi()) + name = "turn_" + str(randi()) title = "Turn" modulate = Color(0.5, 1.0, 0.5) # Green diff --git a/addons/cutscene_editor/editor/nodes/TurnActionNode.tscn b/addons/cutscene_editor/editor/nodes/TurnActionNode.tscn old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/nodes/WaitActionNode.gd b/addons/cutscene_editor/editor/nodes/WaitActionNode.gd old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/nodes/WaitActionNode.tscn b/addons/cutscene_editor/editor/nodes/WaitActionNode.tscn old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/editor/resources/CutsceneResource.gd b/addons/cutscene_editor/editor/resources/CutsceneResource.gd old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_animation.svg b/addons/cutscene_editor/icons/icon_animation.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_animation.svg.import b/addons/cutscene_editor/icons/icon_animation.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_dialogue.svg b/addons/cutscene_editor/icons/icon_dialogue.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_dialogue.svg.import b/addons/cutscene_editor/icons/icon_dialogue.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_entry.svg b/addons/cutscene_editor/icons/icon_entry.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_entry.svg.import b/addons/cutscene_editor/icons/icon_entry.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_exit.svg b/addons/cutscene_editor/icons/icon_exit.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_exit.svg.import b/addons/cutscene_editor/icons/icon_exit.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_move.svg b/addons/cutscene_editor/icons/icon_move.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_move.svg.import b/addons/cutscene_editor/icons/icon_move.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_parallel.svg b/addons/cutscene_editor/icons/icon_parallel.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_parallel.svg.import b/addons/cutscene_editor/icons/icon_parallel.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_turn.svg b/addons/cutscene_editor/icons/icon_turn.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_turn.svg.import b/addons/cutscene_editor/icons/icon_turn.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_wait.svg b/addons/cutscene_editor/icons/icon_wait.svg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/icons/icon_wait.svg.import b/addons/cutscene_editor/icons/icon_wait.svg.import old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/plugin.cfg b/addons/cutscene_editor/plugin.cfg old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/tests/test_cutscene_resource.gd b/addons/cutscene_editor/tests/test_cutscene_resource.gd old mode 100644 new mode 100755 diff --git a/addons/cutscene_editor/tests/test_cutscene_resource.tscn b/addons/cutscene_editor/tests/test_cutscene_resource.tscn old mode 100644 new mode 100755 diff --git a/cutscene/Action.gd b/cutscene/Action.gd old mode 100644 new mode 100755 diff --git a/cutscene/CutsceneManager.gd b/cutscene/CutsceneManager.gd old mode 100644 new mode 100755 index 549f7d6..f9d15f6 --- a/cutscene/CutsceneManager.gd +++ b/cutscene/CutsceneManager.gd @@ -1,14 +1,13 @@ class_name CutsceneManager extends Node -# Action queues -var sequential_actions: Array = [] # Actions that run one after another -var current_action: Action = null # The action currently being executed -var action_index: int = 0 # Index of the next sequential action - -# Parallel actions -var parallel_groups: Array = [] # Groups of actions running simultaneously -var active_parallel_groups: Array = [] # Currently running parallel action groups +# Action dependency graph +var actions: Dictionary = {} # Map of action IDs to action instances +var dependencies: Dictionary = {} # Map of action IDs to their dependency lists +var dependents: Dictionary = {} # Map of action IDs to actions that depend on them +var ready_actions: Array = [] # Actions that are ready to execute (all dependencies met) +var active_actions: Array = [] # Currently running actions +var completed_actions: Array = [] # Actions that have completed # State management enum State { @@ -39,8 +38,16 @@ func start() -> void: is_active = true emit_signal("cutscene_started") - # Start first action - _execute_next_action() + # Find actions with no dependencies to start with + _find_ready_actions() + + # Start all ready actions + for action_id in ready_actions: + _execute_action(action_id) + + # Check if there are no actions to execute + if actions.size() == 0: + _on_cutscene_completed() func pause() -> void: # Pause the current cutscene @@ -56,67 +63,78 @@ func resume() -> void: func stop() -> void: # Stop the current cutscene and reset - if current_action != null: - current_action.stop() - current_action = null + # Stop all active actions + for action in active_actions: + if action.state == action.State.RUNNING: + action.stop() - # Stop all active parallel groups - for group in active_parallel_groups: - for action in group["actions"]: - if action.state == action.State.RUNNING: - action.stop() + active_actions.clear() _reset() -func add_action(action: Action) -> void: - # Add a single action to the sequential queue +func add_action(action_id: String, action: Action, deps: Array = []) -> void: + # Add an action with its dependencies if state != State.IDLE: print("Warning: Cannot add actions while cutscene is running") return - sequential_actions.append(action) + actions[action_id] = action + dependencies[action_id] = deps + # Build reverse dependency map (dependents) + for dep_id in deps: + if not dependents.has(dep_id): + dependents[dep_id] = [] + dependents[dep_id].append(action_id) # Internal methods func _process(delta: float) -> void: # Main update loop if state != State.RUNNING: return + # Find actions with no dependencies to start with + _find_ready_actions() - # Update current sequential action - if current_action != null and current_action.state == current_action.State.RUNNING: - current_action.update(delta) - - # Update active parallel groups - for group in active_parallel_groups: - for action in group["actions"]: - if action.state == action.State.RUNNING: - action.update(delta) + # Start all ready actions + for action_id in ready_actions: + _execute_action(action_id) + + # Update all active actions + for action in active_actions: + if action.state == action.State.RUNNING: + action.update(delta) -func _execute_next_action() -> void: - # Start executing the next sequential action - if action_index >= sequential_actions.size(): - # No more actions, cutscene complete - _on_cutscene_completed() - return +func _find_ready_actions() -> void: + # Find actions that are ready to execute (all dependencies met) + ready_actions.clear() - var action_item = sequential_actions[action_index] - action_index += 1 - print(action_item) - # Check if this is a parallel group or single action - if typeof(action_item) == TYPE_DICTIONARY and action_item.has("actions"): - # This is a parallel group - _execute_parallel_group(action_item) - else: - # This is a single action - _execute_single_action(action_item) + for action_id in actions: + # Skip if already completed or active + if completed_actions.has(action_id) or active_actions.has(actions[action_id]): + continue + + # Check if all dependencies are met + var all_deps_met = true + for dep_id in dependencies[action_id]: + if not completed_actions.has(dep_id): + all_deps_met = false + break -func _execute_single_action(action: Action) -> void: + if all_deps_met: + ready_actions.append(action_id) + +func _execute_action(action_id: String) -> void: # Execute a single action - current_action = action + var action = actions[action_id] + + # Remove from ready actions + ready_actions.erase(action_id) + + # Add to active actions + active_actions.append(action) # Connect to action signals if not action.is_connected("completed", _on_action_completed): - action.connect("completed", _on_action_completed.bind(action)) + action.connect("completed", _on_action_completed.bind(action_id)) if not action.is_connected("failed", _on_action_failed): action.connect("failed", _on_action_failed.bind(action)) if not action.is_connected("started", _on_action_started): @@ -126,72 +144,37 @@ func _execute_single_action(action: Action) -> void: emit_signal("action_started", action) action.start() -func _execute_parallel_group(group: Dictionary) -> void: - # Execute a group of parallel actions - var actions = group["actions"] - - # Reset completion count - group["completed_count"] = 0 - - # Add to active parallel groups - active_parallel_groups.append(group) - - # Connect to each action's signals - for action in actions: - if not action.is_connected("completed", _on_parallel_action_completed): - action.connect("completed", _on_parallel_action_completed.bind(group, action)) - if not action.is_connected("failed", _on_parallel_action_failed): - action.connect("failed", _on_parallel_action_failed.bind(group, action)) - if not action.is_connected("started", _on_action_started): - action.connect("started", _on_action_started.bind(action)) - - # Emit started signal and start action - emit_signal("action_started", action) - action.start() - func _on_action_started(action: Action) -> void: # Handle action started emit_signal("action_started", action) -func _on_action_completed(action: Action) -> void: +func _on_action_completed(action_id: String) -> void: # Handle action completion - if action == current_action: - current_action = null - emit_signal("action_completed", action) - # Move to next action - _execute_next_action() + var action = actions[action_id] + active_actions.erase(action) + completed_actions.append(action_id) + emit_signal("action_completed", action) + + # Check if all actions are completed + if completed_actions.size() == actions.size(): + _on_cutscene_completed() + else: + # Find newly ready actions + _find_ready_actions() + + # Start all newly ready actions + for new_action_id in ready_actions: + _execute_action(new_action_id) func _on_action_failed(action: Action, error_message: String) -> void: # Handle action failure - if action == current_action: - current_action = null + active_actions.erase(action) emit_signal("action_failed", action, error_message) print("Action failed: %s - %s" % [action.name, error_message]) # Stop the cutscene stop() -func _on_parallel_action_completed(group: Dictionary, action: Action) -> void: - # Increment completed count - group["completed_count"] += 1 - - emit_signal("action_completed", action) - - # Check if all actions in group are completed - if group["completed_count"] >= group["total_count"]: - # Remove from active groups - active_parallel_groups.erase(group) - - # Continue with next sequential action - _execute_next_action() - -func _on_parallel_action_failed(group: Dictionary, action: Action, error_message: String) -> void: - # Handle parallel action failure - emit_signal("action_failed", action, error_message) - print("Parallel action failed: %s - %s" % [action.name, error_message]) - # Stop the cutscene - stop() - func _on_cutscene_completed() -> void: # Handle cutscene completion state = State.IDLE @@ -200,10 +183,11 @@ func _on_cutscene_completed() -> void: func _reset() -> void: # Reset the manager to initial state - sequential_actions.clear() - parallel_groups.clear() - active_parallel_groups.clear() - current_action = null - action_index = 0 + actions.clear() + dependencies.clear() + dependents.clear() + ready_actions.clear() + active_actions.clear() + completed_actions.clear() state = State.IDLE is_active = false diff --git a/cutscene/README.md b/cutscene/README.md old mode 100644 new mode 100755 diff --git a/cutscene/actions/AnimationAction.gd b/cutscene/actions/AnimationAction.gd old mode 100644 new mode 100755 diff --git a/cutscene/actions/DialogueAction.gd b/cutscene/actions/DialogueAction.gd old mode 100644 new mode 100755 diff --git a/cutscene/actions/MoveAction.gd b/cutscene/actions/MoveAction.gd old mode 100644 new mode 100755 index 5c12a23..709a0d8 --- a/cutscene/actions/MoveAction.gd +++ b/cutscene/actions/MoveAction.gd @@ -30,7 +30,6 @@ func start() -> void: self._set_running() func update(delta: float) -> void: - print ("updating") if state != State.RUNNING: return diff --git a/cutscene/actions/TurnAction.gd b/cutscene/actions/TurnAction.gd old mode 100644 new mode 100755 diff --git a/cutscene/actions/WaitAction.gd b/cutscene/actions/WaitAction.gd old mode 100644 new mode 100755 diff --git a/example_cutscene.tscn b/example_cutscene.tscn old mode 100644 new mode 100755 index 513a2bd..7d1bb5b --- a/example_cutscene.tscn +++ b/example_cutscene.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=2 format=3 uid="uid://bi4gojo71c7jt"] +[gd_scene load_steps=2 format=3 uid="uid://bi2c4ph8txa4y"] [sub_resource type="GDScript" id="GDScript_e7tbc"] script/source = "extends Node2D diff --git a/hello.tres b/hello.tres deleted file mode 100644 index bfffb2e..0000000 --- a/hello.tres +++ /dev/null @@ -1,34 +0,0 @@ -[gd_resource type="Resource" script_class="CutsceneResource" load_steps=2 format=3 uid="uid://ci8lt4jyxcysx"] - -[ext_resource type="Script" path="res://addons/cutscene_editor/editor/resources/CutsceneResource.gd" id="1_as4bh"] - -[resource] -script = ExtResource("1_as4bh") -nodes = [{ -"id": "entry_1227949280", -"parameters": {}, -"position": { -"x": 300.0, -"y": 160.0 -}, -"type": "entry" -}, { -"id": "move_3555857962", -"parameters": { -"character": "", -"speed": 100.0, -"target_x": 0.0, -"target_y": 0.0 -}, -"position": { -"x": 763.0, -"y": 168.0 -}, -"type": "move" -}] -connections = [] -metadata = { -"created": 1.75399e+09, -"modified": 1.75399e+09, -"version": "2.0" -} diff --git a/icon.svg b/icon.svg old mode 100644 new mode 100755 diff --git a/icon.svg.import b/icon.svg.import old mode 100644 new mode 100755 diff --git a/main.tscn b/main.tscn old mode 100644 new mode 100755 diff --git a/plans/cutscene_data_structure.md b/plans/cutscene_data_structure.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_documentation_plan.md b/plans/cutscene_documentation_plan.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_generator_changes.md b/plans/cutscene_generator_changes.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_graph_edit_changes.md b/plans/cutscene_graph_edit_changes.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_resource_analysis.md b/plans/cutscene_resource_analysis.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_resource_implementation.md b/plans/cutscene_resource_implementation.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_resource_implementation_summary.md b/plans/cutscene_resource_implementation_summary.md old mode 100644 new mode 100755 diff --git a/plans/cutscene_test_plan.md b/plans/cutscene_test_plan.md old mode 100644 new mode 100755 diff --git a/project.godot b/project.godot old mode 100644 new mode 100755 index 011324c..d906fb4 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="adventure-ai" run/main_scene="res://main.tscn" -config/features=PackedStringArray("4.3", "Forward Plus") +config/features=PackedStringArray("4.2", "Forward Plus") config/icon="res://icon.svg" [editor_plugins] diff --git a/scripts/cutscene/CutsceneManager.gd b/scripts/cutscene/CutsceneManager.gd deleted file mode 100644 index e69de29..0000000 diff --git a/tes2265.tmp b/tes2265.tmp new file mode 100755 index 0000000..a423584 --- /dev/null +++ b/tes2265.tmp @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://vlh0eb7qn72o"] + +[ext_resource type="Script" path="res://test_resource_cutscene.gd" id="1"] + +[node name="Node2D" type="Node2D"] +script = ExtResource("1") + +[node name="Character1" type="Node2D" parent="."] +position = Vector2(100, 100) + +[node name="Polygon2D" type="Polygon2D" parent="Character1"] +polygon = PackedVector2Array(33, -74, -67, 4, -20, 33, 45, 2) + +[node name="Character2" type="Node2D" parent="."] +position = Vector2(200, 200) + +[node name="Polygon2D" type="Polygon2D" parent="Character2"] +polygon = PackedVector2Array(21, -54, -56, 23, 2, 59, 63, -16, 58, -69) diff --git a/test_cutscene.tres b/test_cutscene.tres new file mode 100755 index 0000000..38a9588 --- /dev/null +++ b/test_cutscene.tres @@ -0,0 +1,101 @@ +[gd_resource type="Resource" script_class="CutsceneResource" load_steps=2 format=3 uid="uid://bfngefj7emehe"] + +[ext_resource type="Script" path="res://addons/cutscene_editor/editor/resources/CutsceneResource.gd" id="1_p6huk"] + +[resource] +script = ExtResource("1_p6huk") +nodes = [{ +"id": "entry_476938218", +"parameters": {}, +"position": { +"x": 262.0, +"y": 155.0 +}, +"type": "entry" +}, { +"id": "move_3499731826", +"parameters": { +"character": "", +"move_3499731826": 700.0, +"speed": 100.0, +"target_x": 0.0, +"target_y": 0.0 +}, +"position": { +"x": 380.0, +"y": 40.0 +}, +"type": "move" +}, { +"id": "exit_1710964436", +"parameters": {}, +"position": { +"x": 1020.0, +"y": 140.0 +}, +"type": "exit" +}, { +"id": "move_2800650428", +"parameters": { +"character": "", +"move_2800650428": 91.0, +"speed": 100.0, +"target_x": 0.0, +"target_y": 0.0 +}, +"position": { +"x": 640.0, +"y": 60.0 +}, +"type": "move" +}, { +"id": "MoveActionNode", +"parameters": { +"MoveActionNode": 50.0, +"character": "", +"speed": 100.0, +"target_x": 0.0, +"target_y": 0.0 +}, +"position": { +"x": 520.0, +"y": 340.0 +}, +"type": "move" +}] +connections = [{ +"from_node": "entry_476938218", +"from_port": 0, +"id": "conn_4022396", +"to_node": "move_3499731826", +"to_port": 0 +}, { +"from_node": "move_3499731826", +"from_port": 0, +"id": "conn_4022396", +"to_node": "move_2800650428", +"to_port": 0 +}, { +"from_node": "move_2800650428", +"from_port": 0, +"id": "conn_4022396", +"to_node": "exit_1710964436", +"to_port": 0 +}, { +"from_node": "move_3499731826", +"from_port": 0, +"id": "conn_4022396", +"to_node": "MoveActionNode", +"to_port": 0 +}, { +"from_node": "MoveActionNode", +"from_port": 0, +"id": "conn_4022396", +"to_node": "exit_1710964436", +"to_port": 0 +}] +metadata = { +"created": 1.75402e+09, +"modified": 1.75402e+09, +"version": "2.0" +} diff --git a/test_cutscene2.gd b/test_cutscene2.gd new file mode 100755 index 0000000..aca285d --- /dev/null +++ b/test_cutscene2.gd @@ -0,0 +1,234 @@ +extends Node2D + +# Test script for the new resource-based cutscene system + +# Character nodes +@onready var character1: Node2D = $Character1 +@onready var character2: Node2D = $Character2 + +# Cutscene manager +var cutscene_manager: CutsceneManager + +func _ready() -> void: + # Initialize the cutscene system + setup_cutscene() + + # Start the cutscene after a short delay to see the initial positions + var start_timer = Timer.new() + start_timer.wait_time = 1.0 + start_timer.one_shot = true + start_timer.connect("timeout", start_cutscene) + add_child(start_timer) + start_timer.start() + +func setup_cutscene() -> void: + # Create the cutscene manager + cutscene_manager = CutsceneManager.new() + add_child(cutscene_manager) + + # Connect to cutscene signals + cutscene_manager.connect("cutscene_started", _on_cutscene_started) + cutscene_manager.connect("cutscene_completed", _on_cutscene_completed) + cutscene_manager.connect("action_started", _on_action_started) + cutscene_manager.connect("action_completed", _on_action_completed) + + # Create a cutscene resource with the same sequence as the original example + var cutscene_resource = preload("res://test_cutscene.tres") + + # Generate actions from the resource + var generator = CutsceneGenerator.new() + cutscene_manager = generator.generate_cutscene(self, cutscene_resource) + + # Add the cutscene manager to the scene + add_child(cutscene_manager) + + # Connect to cutscene signals + cutscene_manager.connect("cutscene_started", _on_cutscene_started) + cutscene_manager.connect("cutscene_completed", _on_cutscene_completed) + cutscene_manager.connect("action_started", _on_action_started) + cutscene_manager.connect("action_completed", _on_action_completed) + +func create_test_cutscene_resource() -> CutsceneResource: + # Create a new cutscene resource + var resource = CutsceneResource.new() + + # Create nodes for the cutscene + var entry_node = { + "id": "entry_1", + "type": "entry", + "position": {"x": 100, "y": 100}, + "parameters": {} + } + + var move1_node = { + "id": "move_1", + "type": "move", + "position": {"x": 250, "y": 100}, + "parameters": { + "character": "Character1", + "target_x": 234, + "target_y": 591, + "speed": 100.0 + } + } + + var move2_node = { + "id": "move_2", + "type": "move", + "position": {"x": 250, "y": 150}, + "parameters": { + "character": "Character2", + "target_x": 912, + "target_y": 235, + "speed": 100.0 + } + } + + var turn_node = { + "id": "turn_1", + "type": "turn", + "position": {"x": 400, "y": 100}, + "parameters": { + "character": "character2", + "target": "character1", + "turn_speed": 1.0 + } + } + + var dialogue1_node = { + "id": "dialogue_1", + "type": "dialogue", + "position": {"x": 550, "y": 100}, + "parameters": { + "character": "character2", + "text": "Hello there, friend!", + "duration": 2.0 + } + } + + var wait_node = { + "id": "wait_1", + "type": "wait", + "position": {"x": 700, "y": 100}, + "parameters": { + "duration": 1.0 + } + } + + var dialogue2_node = { + "id": "dialogue_2", + "type": "dialogue", + "position": {"x": 850, "y": 100}, + "parameters": { + "character": "character1", + "text": "That was surprising!", + "duration": 2.0 + } + } + + var exit_node = { + "id": "exit_1", + "type": "exit", + "position": {"x": 1000, "y": 100}, + "parameters": {} + } + + # Add nodes to resource + resource.add_node(entry_node) + resource.add_node(move1_node) + resource.add_node(move2_node) + resource.add_node(turn_node) + resource.add_node(dialogue1_node) + resource.add_node(wait_node) + resource.add_node(dialogue2_node) + resource.add_node(exit_node) + + # Create connections + var connections = [ + { + "id": "conn_1", + "from_node": "entry_1", + "from_port": 0, + "to_node": "move_1", + "to_port": 0 + }, + { + "id": "conn_2", + "from_node": "entry_1", + "from_port": 0, + "to_node": "move_2", + "to_port": 0 + }, + { + "id": "conn_3", + "from_node": "move_1", + "from_port": 0, + "to_node": "turn_node", + "to_port": 0 + }, + { + "id": "conn_4", + "from_node": "move_2", + "from_port": 0, + "to_node": "turn_node", + "to_port": 0 + }, + { + "id": "conn_5", + "from_node": "turn_node", + "from_port": 0, + "to_node": "dialogue_1", + "to_port": 0 + }, + { + "id": "conn_6", + "from_node": "dialogue_1", + "from_port": 0, + "to_node": "wait_node", + "to_port": 0 + }, + { + "id": "conn_7", + "from_node": "wait_node", + "from_port": 0, + "to_node": "dialogue_2", + "to_port": 0 + }, + { + "id": "conn_8", + "from_node": "dialogue_2", + "from_port": 0, + "to_node": "exit_1", + "to_port": 0 + } + ] + + # Add connections to resource + for conn in connections: + resource.add_connection(conn) + + return resource + +func start_cutscene() -> void: + print("Starting cutscene...") + cutscene_manager.start() + +func _on_cutscene_started() -> void: + print("Cutscene started!") + +func _on_cutscene_completed() -> void: + print("Cutscene completed!") + print("Final positions:") + print("Character1: %s" % character1.position) + print("Character2: %s" % character2.position) + +func _on_action_started(action: Action) -> void: + print("Action started: %s, %s" % action.name) + +func _on_action_completed(action: Action) -> void: + print("Action completed: %s, %s" % action.name) + +# Clean up when the node is removed +func _exit_tree() -> void: + if cutscene_manager: + cutscene_manager.queue_free() diff --git a/test_cutscene2.tscn b/test_cutscene2.tscn new file mode 100755 index 0000000..1e25c0d --- /dev/null +++ b/test_cutscene2.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://bb0vnntvwbuff"] + +[ext_resource type="Script" path="res://test_cutscene2.gd" id="1_6nibr"] + +[node name="Node2D" type="Node2D"] +script = ExtResource("1_6nibr") + +[node name="Character1" type="Node2D" parent="."] +position = Vector2(100, 100) + +[node name="Polygon2D" type="Polygon2D" parent="Character1"] +polygon = PackedVector2Array(33, -74, -67, 4, -20, 33, 45, 2) + +[node name="Character2" type="Node2D" parent="."] +position = Vector2(200, 200) + +[node name="Polygon2D" type="Polygon2D" parent="Character2"] +polygon = PackedVector2Array(21, -54, -56, 23, 2, 59, 63, -16, 58, -69) diff --git a/test_dependency_cutscene.gd b/test_dependency_cutscene.gd new file mode 100755 index 0000000..c6f7134 --- /dev/null +++ b/test_dependency_cutscene.gd @@ -0,0 +1,50 @@ +extends Node + +# Test script for the new dependency-based cutscene system + +func _ready(): + # Create a simple test cutscene + _test_dependency_system() + +func _test_dependency_system(): + print("Testing dependency-based cutscene system") + + # Create cutscene manager + var cutscene_manager = CutsceneManager.new() + add_child(cutscene_manager) + + # Create some test actions + var wait1 = preload("res://cutscene/actions/WaitAction.gd").new(1.0) + wait1.name = "Wait1" + + var wait2 = preload("res://cutscene/actions/WaitAction.gd").new(2.0) + wait2.name = "Wait2" + + var wait3 = preload("res://cutscene/actions/WaitAction.gd").new(1.5) + wait3.name = "Wait3" + + # Add actions with dependencies + # wait1 and wait2 can run in parallel (no dependencies) + # wait3 depends on wait1 + cutscene_manager.add_action("wait1", wait1, []) + cutscene_manager.add_action("wait2", wait2, []) + cutscene_manager.add_action("wait3", wait3, ["wait1"]) + + # Connect to signals + cutscene_manager.connect("cutscene_completed", _on_cutscene_completed) + cutscene_manager.connect("action_started", _on_action_started) + cutscene_manager.connect("action_completed", _on_action_completed) + + # Start the cutscene + cutscene_manager.start() + + print("Cutscene started with dependency-based execution") + +func _on_cutscene_completed(): + print("Cutscene completed successfully!") + +func _on_action_started(action): + print("Action started: %s" % action.name) + +func _on_action_completed(action): + print("Action completed: %s" % action.name) diff --git a/test_dependency_cutscene.tscn b/test_dependency_cutscene.tscn new file mode 100755 index 0000000..bed3541 --- /dev/null +++ b/test_dependency_cutscene.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[node name="Node" type="Node"] +script = ExtResource( 1 ) + +[resource] \ No newline at end of file diff --git a/test_resource_cutscene.gd b/test_resource_cutscene.gd old mode 100644 new mode 100755 index ba09117..3ff5c52 --- a/test_resource_cutscene.gd +++ b/test_resource_cutscene.gd @@ -37,7 +37,7 @@ func setup_cutscene() -> void: # Generate actions from the resource var generator = CutsceneGenerator.new() - cutscene_manager = generator.generate_cutscene(cutscene_resource) + cutscene_manager = generator.generate_cutscene(self, cutscene_resource) # Add the cutscene manager to the scene add_child(cutscene_manager) @@ -77,7 +77,7 @@ func create_test_cutscene_resource() -> CutsceneResource: "type": "move", "position": {"x": 250, "y": 150}, "parameters": { - "character": "character2", + "character": "Character2", "target_x": 912, "target_y": 235, "speed": 100.0 @@ -223,10 +223,10 @@ func _on_cutscene_completed() -> void: print("Character2: %s" % character2.position) func _on_action_started(action: Action) -> void: - print("Action started: %s" % action.name) + print("Action started: %s, %s" % action.name) func _on_action_completed(action: Action) -> void: - print("Action completed: %s" % action.name) + print("Action completed: %s, %s" % action.name) # Clean up when the node is removed func _exit_tree() -> void: diff --git a/test_resource_cutscene.tscn b/test_resource_cutscene.tscn old mode 100644 new mode 100755