cutscene progress.
This commit is contained in:
73
a.tres
Normal file
73
a.tres
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
[gd_resource type="Resource" script_class="CutsceneResource" load_steps=2 format=3 uid="uid://cusqvt64lirrh"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/cutscene_editor/editor/resources/CutsceneResource.gd" id="1_f8git"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_f8git")
|
||||||
|
nodes = [{
|
||||||
|
"id": "entry_1197916315",
|
||||||
|
"parameters": {},
|
||||||
|
"position": {
|
||||||
|
"x": 286.0,
|
||||||
|
"y": 192.0
|
||||||
|
},
|
||||||
|
"type": "entry"
|
||||||
|
}, {
|
||||||
|
"id": "move_1772978113",
|
||||||
|
"parameters": {
|
||||||
|
"MoveActionNode": 100.0,
|
||||||
|
"character": "Character1",
|
||||||
|
"speed": 100.0,
|
||||||
|
"target_x": 101.0,
|
||||||
|
"target_y": 501.0
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 500.0,
|
||||||
|
"y": 198.0
|
||||||
|
},
|
||||||
|
"type": "move"
|
||||||
|
}, {
|
||||||
|
"id": "exit_1709333016",
|
||||||
|
"parameters": {},
|
||||||
|
"position": {
|
||||||
|
"x": 1220.0,
|
||||||
|
"y": 220.0
|
||||||
|
},
|
||||||
|
"type": "exit"
|
||||||
|
}, {
|
||||||
|
"id": "turn_360286729",
|
||||||
|
"parameters": {
|
||||||
|
"character": "Character1",
|
||||||
|
"target": "Character2",
|
||||||
|
"turn_speed": 4.0
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 880.0,
|
||||||
|
"y": 220.0
|
||||||
|
},
|
||||||
|
"type": "turn"
|
||||||
|
}]
|
||||||
|
connections = [{
|
||||||
|
"from_node": "entry_1197916315",
|
||||||
|
"from_port": 0,
|
||||||
|
"id": "conn_529457",
|
||||||
|
"to_node": "move_1772978113",
|
||||||
|
"to_port": 0
|
||||||
|
}, {
|
||||||
|
"from_node": "move_1772978113",
|
||||||
|
"from_port": 0,
|
||||||
|
"id": "conn_529457",
|
||||||
|
"to_node": "turn_360286729",
|
||||||
|
"to_port": 0
|
||||||
|
}, {
|
||||||
|
"from_node": "turn_360286729",
|
||||||
|
"from_port": 0,
|
||||||
|
"id": "conn_529457",
|
||||||
|
"to_node": "exit_1709333016",
|
||||||
|
"to_port": 0
|
||||||
|
}]
|
||||||
|
metadata = {
|
||||||
|
"created": 1.75402e+09,
|
||||||
|
"modified": 1.75402e+09,
|
||||||
|
"version": "2.0"
|
||||||
|
}
|
||||||
4
addons/cutscene_editor/editor/CutsceneGenerator.gd
Executable file → Normal file
4
addons/cutscene_editor/editor/CutsceneGenerator.gd
Executable file → Normal file
@@ -101,8 +101,8 @@ func _create_action_from_node(scene: Node, node_data: Dictionary):
|
|||||||
var turn_speed = parameters.get("turn_speed", 2.0)
|
var turn_speed = parameters.get("turn_speed", 2.0)
|
||||||
|
|
||||||
# In a real implementation, we would resolve the paths to actual nodes
|
# In a real implementation, we would resolve the paths to actual nodes
|
||||||
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_node = null # This would be resolved at runtime
|
var target_node = scene.find_child(target) # This would be resolved at runtime
|
||||||
|
|
||||||
return TurnAction.new(character_node, target_node, turn_speed)
|
return TurnAction.new(character_node, target_node, turn_speed)
|
||||||
|
|
||||||
|
|||||||
19
addons/cutscene_editor/editor/CutsceneGraphEdit.gd
Executable file → Normal file
19
addons/cutscene_editor/editor/CutsceneGraphEdit.gd
Executable file → Normal file
@@ -85,7 +85,6 @@ func add_node(node_type: String, position: Vector2) -> BaseGraphNode:
|
|||||||
# Emit signal
|
# Emit signal
|
||||||
emit_signal("node_added", new_node)
|
emit_signal("node_added", new_node)
|
||||||
emit_signal("graph_changed")
|
emit_signal("graph_changed")
|
||||||
|
|
||||||
return new_node
|
return new_node
|
||||||
|
|
||||||
# Handle connection requests
|
# Handle connection requests
|
||||||
@@ -349,6 +348,7 @@ func load_from_cutscene(cutscene: CutsceneResource) -> void:
|
|||||||
# Set node parameters
|
# Set node parameters
|
||||||
for param_name in node_data["parameters"]:
|
for param_name in node_data["parameters"]:
|
||||||
node.set_parameter(param_name, node_data["parameters"][param_name])
|
node.set_parameter(param_name, node_data["parameters"][param_name])
|
||||||
|
node._parameters_to_view()
|
||||||
|
|
||||||
# Create connections from cutscene data
|
# Create connections from cutscene data
|
||||||
for connection_data in cutscene.connections:
|
for connection_data in cutscene.connections:
|
||||||
@@ -356,6 +356,7 @@ func load_from_cutscene(cutscene: CutsceneResource) -> void:
|
|||||||
connect_node(connection_data["from_node"], connection_data["from_port"],
|
connect_node(connection_data["from_node"], connection_data["from_port"],
|
||||||
connection_data["to_node"], connection_data["to_port"])
|
connection_data["to_node"], connection_data["to_port"])
|
||||||
|
|
||||||
|
|
||||||
# Emit signal
|
# Emit signal
|
||||||
emit_signal("graph_changed")
|
emit_signal("graph_changed")
|
||||||
|
|
||||||
@@ -372,7 +373,7 @@ func save_to_cutscene() -> CutsceneResource:
|
|||||||
for child in get_children():
|
for child in get_children():
|
||||||
if child is BaseGraphNode:
|
if child is BaseGraphNode:
|
||||||
var node_data = {
|
var node_data = {
|
||||||
"id": str(child.name),
|
"id": str(child.node_id),
|
||||||
"type": child.node_type,
|
"type": child.node_type,
|
||||||
"position": {
|
"position": {
|
||||||
"x": child.position_offset.x,
|
"x": child.position_offset.x,
|
||||||
@@ -380,15 +381,25 @@ func save_to_cutscene() -> CutsceneResource:
|
|||||||
},
|
},
|
||||||
"parameters": child.action_parameters
|
"parameters": child.action_parameters
|
||||||
}
|
}
|
||||||
|
print(node_data)
|
||||||
current_cutscene.nodes.append(node_data)
|
current_cutscene.nodes.append(node_data)
|
||||||
|
|
||||||
# Save connections
|
# Save connections
|
||||||
for connection in get_connection_list():
|
for connection in get_connection_list():
|
||||||
|
|
||||||
|
# Get actual node instances from node names to access node_id
|
||||||
|
var from_node_instance = get_node_or_null(str(connection["from_node"]))
|
||||||
|
var to_node_instance = get_node_or_null(str(connection["to_node"]))
|
||||||
|
|
||||||
|
# Skip if nodes don't exist (shouldn't happen, but safety check)
|
||||||
|
if not from_node_instance or not to_node_instance:
|
||||||
|
continue
|
||||||
|
|
||||||
var connection_data = {
|
var connection_data = {
|
||||||
"id": _generate_unique_connection_id(),
|
"id": _generate_unique_connection_id(),
|
||||||
"from_node": str(connection["from_node"]),
|
"from_node": str(from_node_instance.node_id),
|
||||||
"from_port": connection["from_port"],
|
"from_port": connection["from_port"],
|
||||||
"to_node": str(connection["to_node"]),
|
"to_node": str(to_node_instance.node_id),
|
||||||
"to_port": connection["to_port"]
|
"to_port": connection["to_port"]
|
||||||
}
|
}
|
||||||
current_cutscene.connections.append(connection_data)
|
current_cutscene.connections.append(connection_data)
|
||||||
|
|||||||
2
addons/cutscene_editor/editor/nodes/AnimationActionNode.gd
Executable file → Normal file
2
addons/cutscene_editor/editor/nodes/AnimationActionNode.gd
Executable file → Normal file
@@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "animation"
|
node_type = "animation"
|
||||||
name = "animation_" + str(randi())
|
node_id = "animation_" + str(randi())
|
||||||
title = "Animation"
|
title = "Animation"
|
||||||
modulate = Color(0.8, 0.4, 0.8) # Purple
|
modulate = Color(0.8, 0.4, 0.8) # Purple
|
||||||
|
|
||||||
|
|||||||
3
addons/cutscene_editor/editor/nodes/BaseGraphNode.gd
Executable file → Normal file
3
addons/cutscene_editor/editor/nodes/BaseGraphNode.gd
Executable file → Normal file
@@ -21,6 +21,7 @@ enum NodeState {
|
|||||||
# Properties
|
# Properties
|
||||||
var node_type: String = "base"
|
var node_type: String = "base"
|
||||||
|
|
||||||
|
var node_id: String
|
||||||
var action_parameters: Dictionary = {} # Stores parameter values
|
var action_parameters: Dictionary = {} # Stores parameter values
|
||||||
var current_state: int = NodeState.IDLE
|
var current_state: int = NodeState.IDLE
|
||||||
var error_message: String = ""
|
var error_message: String = ""
|
||||||
@@ -282,3 +283,5 @@ func _clear_parameter_fields() -> void:
|
|||||||
editor.queue_free()
|
editor.queue_free()
|
||||||
|
|
||||||
property_editors.clear()
|
property_editors.clear()
|
||||||
|
func _parameters_to_view() -> void:
|
||||||
|
pass
|
||||||
|
|||||||
2
addons/cutscene_editor/editor/nodes/DialogueActionNode.gd
Executable file → Normal file
2
addons/cutscene_editor/editor/nodes/DialogueActionNode.gd
Executable file → Normal file
@@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "dialogue"
|
node_type = "dialogue"
|
||||||
name = "dialogue_" + str(randi())
|
node_id = "dialogue_" + str(randi())
|
||||||
title = "Dialogue"
|
title = "Dialogue"
|
||||||
modulate = Color(1.0, 1.0, 0.5) # Yellow
|
modulate = Color(1.0, 1.0, 0.5) # Yellow
|
||||||
resizable=true
|
resizable=true
|
||||||
|
|||||||
2
addons/cutscene_editor/editor/nodes/EntryNode.gd
Executable file → Normal file
2
addons/cutscene_editor/editor/nodes/EntryNode.gd
Executable file → Normal file
@@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "entry"
|
node_type = "entry"
|
||||||
name = "entry_" + str(randi())
|
node_id = "entry_" + str(randi())
|
||||||
title = "Start"
|
title = "Start"
|
||||||
modulate = Color(0.5, 1.0, 0.5) # Light green
|
modulate = Color(0.5, 1.0, 0.5) # Light green
|
||||||
|
|
||||||
|
|||||||
2
addons/cutscene_editor/editor/nodes/ExitNode.gd
Executable file → Normal file
2
addons/cutscene_editor/editor/nodes/ExitNode.gd
Executable file → Normal file
@@ -6,7 +6,7 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "exit"
|
node_type = "exit"
|
||||||
name = "exit_" + str(randi())
|
node_id = "exit_" + str(randi())
|
||||||
title = "End"
|
title = "End"
|
||||||
modulate = Color(1.0, 0.5, 0.5) # Light red
|
modulate = Color(1.0, 0.5, 0.5) # Light red
|
||||||
|
|
||||||
|
|||||||
31
addons/cutscene_editor/editor/nodes/MoveActionNode.gd
Executable file → Normal file
31
addons/cutscene_editor/editor/nodes/MoveActionNode.gd
Executable file → Normal file
@@ -6,46 +6,43 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "move"
|
node_type = "move"
|
||||||
name = "move_" + str(randi())
|
node_id = "move_" + str(randi())
|
||||||
title = "Move"
|
title = "Move"
|
||||||
modulate = Color(0.4, 0.6, 1.0) # Blue
|
modulate = Color(0.4, 0.6, 1.0) # Blue
|
||||||
|
|
||||||
# One input and one output connection
|
# One input and one output connection
|
||||||
var slot = 0
|
var slot = 0
|
||||||
set_slot(slot, true, 0, Color(0, 0, 0), true, 0, Color(0, 0, 0))
|
set_slot(slot, true, 0, Color(0, 0, 0), true, 0, Color(0, 0, 0))
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
super._ready()
|
|
||||||
# Initialize default parameters
|
# Initialize default parameters
|
||||||
action_parameters["character"] = ""
|
action_parameters["character"] = ""
|
||||||
action_parameters["target_x"] = 0.0
|
action_parameters["target_x"] = 0.0
|
||||||
action_parameters["target_y"] = 0.0
|
action_parameters["target_y"] = 0.0
|
||||||
action_parameters["speed"] = 100.0
|
action_parameters["speed"] = 100.0
|
||||||
|
|
||||||
func set_parameter(pname, value) -> void:
|
func _ready() -> void:
|
||||||
super.set_parameter(name, value)
|
super._ready()
|
||||||
if pname == "character":
|
func _parameters_to_view() -> void:
|
||||||
$VBoxContainer/CharacterEDit.text = value
|
$VBoxContainer/CharacterEDit.text = action_parameters["character"]
|
||||||
elif pname == "target_x":
|
$VBoxContainer/HBoxContainer/x.text = str(action_parameters["target_x"])
|
||||||
$VBoxContainer/HBoxContainer/x.text = value
|
$VBoxContainer/HBoxContainer/y.text = str(action_parameters["target_y"])
|
||||||
elif pname == "target_y":
|
$VBoxContainer/speed.text = str(action_parameters["speed"])
|
||||||
$VBoxContainer/HBoxContainer/y.text = value
|
|
||||||
elif pname == "speed":
|
|
||||||
$VBoxContainer/speed.text = value
|
|
||||||
func _on_character_changed(new_text: String) -> void:
|
func _on_character_changed(new_text: String) -> void:
|
||||||
|
print("character" , new_text)
|
||||||
set_parameter("character", new_text)
|
set_parameter("character", new_text)
|
||||||
|
|
||||||
func _on_target_x_changed(new_text: String) -> void:
|
func _on_target_x_changed(new_text: String) -> void:
|
||||||
|
print("target x" , new_text)
|
||||||
var value = float(new_text) if new_text.is_valid_float() else 0.0
|
var value = float(new_text) if new_text.is_valid_float() else 0.0
|
||||||
set_parameter("target_x", value)
|
set_parameter("target_x", value)
|
||||||
|
|
||||||
func _on_target_y_changed(new_text: String) -> void:
|
func _on_target_y_changed(new_text: String) -> void:
|
||||||
print("toarget y")
|
print("toarget y" , new_text)
|
||||||
var value = float(new_text) if new_text.is_valid_float() else 0.0
|
var value = float(new_text) if new_text.is_valid_float() else 0.0
|
||||||
set_parameter("target_y", value)
|
set_parameter("target_y", value)
|
||||||
|
|
||||||
func _on_speed_changed(new_text: String) -> void:
|
func _on_speed_changed(new_text: String) -> void:
|
||||||
|
print("speed", new_text)
|
||||||
print("speed")
|
|
||||||
var value = float(new_text) if new_text.is_valid_float() else 100.0
|
var value = float(new_text) if new_text.is_valid_float() else 100.0
|
||||||
set_parameter("speed", value)
|
set_parameter("speed", value)
|
||||||
|
|||||||
0
addons/cutscene_editor/editor/nodes/MoveActionNode.tscn
Executable file → Normal file
0
addons/cutscene_editor/editor/nodes/MoveActionNode.tscn
Executable file → Normal file
@@ -1,126 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name ParallelGroupNode
|
|
||||||
extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|
||||||
|
|
||||||
# Node for grouping parallel actions
|
|
||||||
|
|
||||||
# Special properties for parallel groups
|
|
||||||
var input_connections: int = 3 # Number of input connection points
|
|
||||||
var child_nodes: Array = [] # Child nodes contained within this group
|
|
||||||
var is_container: bool = true # Flag to indicate this is a container node
|
|
||||||
|
|
||||||
# Visual properties
|
|
||||||
var container_rect: PanelContainer # Visual container for child nodes
|
|
||||||
|
|
||||||
func _init() -> void:
|
|
||||||
node_type = "parallel"
|
|
||||||
name = "parallel_" + str(randi())
|
|
||||||
title = "Parallel Group"
|
|
||||||
modulate = Color(1.0, 0.6, 0.2) # Orange
|
|
||||||
|
|
||||||
# Set up slots for connections
|
|
||||||
_setup_slots()
|
|
||||||
|
|
||||||
# Set up container for child nodes
|
|
||||||
_setup_container()
|
|
||||||
|
|
||||||
# Set up connection slots
|
|
||||||
func _setup_slots() -> void:
|
|
||||||
# Multiple input connections for parallel actions
|
|
||||||
for i in range(input_connections):
|
|
||||||
set_slot(i, true, 0, Color(0, 0, 0), false, 0, Color(0, 0, 0, 0))
|
|
||||||
|
|
||||||
# Single output connection for sequential continuation
|
|
||||||
var output_slot = input_connections
|
|
||||||
set_slot(output_slot, false, 0, Color(0, 0, 0, 0), true, 0, Color(0, 0, 0))
|
|
||||||
|
|
||||||
# Set up visual container for child nodes
|
|
||||||
func _setup_container() -> void:
|
|
||||||
# Create container panel
|
|
||||||
container_rect = PanelContainer.new()
|
|
||||||
container_rect.name = "Container"
|
|
||||||
container_rect.anchor_right = 1
|
|
||||||
container_rect.anchor_bottom = 1
|
|
||||||
container_rect.margin_top = 30 # Leave space for title bar
|
|
||||||
container_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
||||||
|
|
||||||
# Set container style
|
|
||||||
var style = StyleBoxFlat.new()
|
|
||||||
style.bg_color = Color(0.9, 0.9, 0.9, 0.3)
|
|
||||||
style.border_color = Color(0.5, 0.5, 0.5, 0.5)
|
|
||||||
style.border_width_left = 1
|
|
||||||
style.border_width_top = 1
|
|
||||||
style.border_width_right = 1
|
|
||||||
style.border_width_bottom = 1
|
|
||||||
container_rect.add_theme_stylebox_override("panel", style)
|
|
||||||
|
|
||||||
add_child(container_rect)
|
|
||||||
|
|
||||||
# Create container for child nodes
|
|
||||||
var child_container = VBoxContainer.new()
|
|
||||||
child_container.name = "ChildContainer"
|
|
||||||
child_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
||||||
container_rect.add_child(child_container)
|
|
||||||
|
|
||||||
# Add a child node to this parallel group
|
|
||||||
func add_child_node(child_node: BaseGraphNode) -> void:
|
|
||||||
# Add to child nodes array
|
|
||||||
child_nodes.append(child_node)
|
|
||||||
|
|
||||||
# Add as child in scene tree
|
|
||||||
if container_rect and container_rect.has_node("ChildContainer"):
|
|
||||||
container_rect.get_node("ChildContainer").add_child(child_node)
|
|
||||||
|
|
||||||
# Update visual representation
|
|
||||||
_update_container_size()
|
|
||||||
|
|
||||||
# Remove a child node from this parallel group
|
|
||||||
func remove_child_node(child_node: BaseGraphNode) -> void:
|
|
||||||
# Remove from child nodes array
|
|
||||||
child_nodes.erase(child_node)
|
|
||||||
|
|
||||||
# Remove from scene tree
|
|
||||||
if child_node.get_parent() == container_rect.get_node("ChildContainer"):
|
|
||||||
container_rect.get_node("ChildContainer").remove_child(child_node)
|
|
||||||
|
|
||||||
# Update visual representation
|
|
||||||
_update_container_size()
|
|
||||||
|
|
||||||
# Update container size based on child nodes
|
|
||||||
func _update_container_size() -> void:
|
|
||||||
# Calculate required size based on child nodes
|
|
||||||
var required_height = 20 # Minimum height
|
|
||||||
|
|
||||||
if container_rect and container_rect.has_node("ChildContainer"):
|
|
||||||
var child_container = container_rect.get_node("ChildContainer")
|
|
||||||
for child in child_container.get_children():
|
|
||||||
if child is BaseGraphNode:
|
|
||||||
required_height += child.size.y + 5 # Add spacing
|
|
||||||
|
|
||||||
# Update container size
|
|
||||||
container_rect.custom_minimum_size.y = required_height
|
|
||||||
|
|
||||||
# Handle node dragging
|
|
||||||
func _on_node_dragged(from: Vector2, to: Vector2) -> void:
|
|
||||||
# Update position
|
|
||||||
position_offset = to
|
|
||||||
|
|
||||||
# Update child nodes if they're positioned relative to this node
|
|
||||||
for child in child_nodes:
|
|
||||||
# Child nodes should move with the parallel group
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Add more input connections if needed
|
|
||||||
func add_input_connection() -> void:
|
|
||||||
var slot_index = input_connections
|
|
||||||
set_slot(slot_index, true, 0, Color(0, 0, 0), false, 0, Color(0, 0, 0, 0))
|
|
||||||
input_connections += 1
|
|
||||||
|
|
||||||
# Get the output slot index
|
|
||||||
func get_output_slot_index() -> int:
|
|
||||||
return input_connections
|
|
||||||
|
|
||||||
# Check if a node can be added as a child
|
|
||||||
func can_add_child_node(node: BaseGraphNode) -> bool:
|
|
||||||
# Can't add entry, exit, or other parallel groups as children
|
|
||||||
return node.node_type != "entry" and node.node_type != "exit" and node.node_type != "parallel"
|
|
||||||
16
addons/cutscene_editor/editor/nodes/TurnActionNode.gd
Executable file → Normal file
16
addons/cutscene_editor/editor/nodes/TurnActionNode.gd
Executable file → Normal file
@@ -6,21 +6,27 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "turn"
|
node_type = "turn"
|
||||||
name = "turn_" + str(randi())
|
node_id = "turn_" + str(randi())
|
||||||
title = "Turn"
|
title = "Turn"
|
||||||
modulate = Color(0.5, 1.0, 0.5) # Green
|
modulate = Color(0.5, 1.0, 0.5) # Green
|
||||||
|
|
||||||
# One input and one output connection
|
# One input and one output connection
|
||||||
var slot = 0
|
var slot = 0
|
||||||
set_slot(slot, true, 0, Color(0, 0, 0), true, 0, Color(0, 0, 0))
|
set_slot(slot, true, 0, Color(0, 0, 0), true, 0, Color(0, 0, 0))
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
super._ready()
|
|
||||||
# Initialize default parameters
|
|
||||||
action_parameters["character"] = ""
|
action_parameters["character"] = ""
|
||||||
action_parameters["target"] = ""
|
action_parameters["target"] = ""
|
||||||
action_parameters["turn_speed"] = 2.0
|
action_parameters["turn_speed"] = 2.0
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
super._ready()
|
||||||
|
# Initialize default parameters
|
||||||
|
|
||||||
|
|
||||||
|
func _parameters_to_view() -> void:
|
||||||
|
$VBoxContainer/character.text = action_parameters["character"]
|
||||||
|
$VBoxContainer/target.text = action_parameters["target"]
|
||||||
|
$VBoxContainer/turn_speed.text = str(action_parameters["turn_speed"])
|
||||||
|
|
||||||
func _on_character_changed(new_text: String) -> void:
|
func _on_character_changed(new_text: String) -> void:
|
||||||
set_parameter("character", new_text)
|
set_parameter("character", new_text)
|
||||||
|
|
||||||
|
|||||||
18
addons/cutscene_editor/editor/nodes/TurnActionNode.tscn
Executable file → Normal file
18
addons/cutscene_editor/editor/nodes/TurnActionNode.tscn
Executable file → Normal file
@@ -1,37 +1,49 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://turnactionnodetscn"]
|
[gd_scene load_steps=2 format=3 uid="uid://dlndt313nnatt"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/cutscene_editor/editor/nodes/TurnActionNode.gd" id="1_turn"]
|
[ext_resource type="Script" path="res://addons/cutscene_editor/editor/nodes/TurnActionNode.gd" id="1_turn"]
|
||||||
|
|
||||||
[node name="TurnActionNode" type="GraphNode"]
|
[node name="TurnActionNode" type="GraphNode"]
|
||||||
modulate = Color(0.5, 1.0, 0.5, 1)
|
modulate = Color(0.5, 1, 0.5, 1)
|
||||||
custom_minimum_size = Vector2(150, 0)
|
custom_minimum_size = Vector2(150, 0)
|
||||||
title = "Turn"
|
title = "Turn"
|
||||||
slot/0/left_enabled = true
|
slot/0/left_enabled = true
|
||||||
slot/0/left_type = 0
|
slot/0/left_type = 0
|
||||||
slot/0/left_color = Color(0, 0, 0, 1)
|
slot/0/left_color = Color(0, 0, 0, 1)
|
||||||
|
slot/0/left_icon = null
|
||||||
slot/0/right_enabled = true
|
slot/0/right_enabled = true
|
||||||
slot/0/right_type = 0
|
slot/0/right_type = 0
|
||||||
slot/0/right_color = Color(0, 0, 0, 1)
|
slot/0/right_color = Color(0, 0, 0, 1)
|
||||||
|
slot/0/right_icon = null
|
||||||
slot/0/draw_stylebox = true
|
slot/0/draw_stylebox = true
|
||||||
script = ExtResource("1_turn")
|
script = ExtResource("1_turn")
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="Character" type="Label" parent="VBoxContainer"]
|
[node name="Character" type="Label" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Character"
|
text = "Character"
|
||||||
|
|
||||||
[node name="character" type="LineEdit" parent="VBoxContainer"]
|
[node name="character" type="LineEdit" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
placeholder_text = "Character name"
|
placeholder_text = "Character name"
|
||||||
|
|
||||||
[node name="Target" type="Label" parent="VBoxContainer"]
|
[node name="Target" type="Label" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Target"
|
text = "Target"
|
||||||
|
|
||||||
[node name="target" type="LineEdit" parent="VBoxContainer"]
|
[node name="target" type="LineEdit" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
placeholder_text = "Target name"
|
placeholder_text = "Target name"
|
||||||
|
|
||||||
[node name="TurnSpeed" type="Label" parent="VBoxContainer"]
|
[node name="TurnSpeed" type="Label" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Turn Speed"
|
text = "Turn Speed"
|
||||||
|
|
||||||
[node name="turn_speed" type="LineEdit" parent="VBoxContainer"]
|
[node name="turn_speed" type="LineEdit" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
placeholder_text = "Turn speed"
|
placeholder_text = "Turn speed"
|
||||||
|
|
||||||
[connection signal="text_changed" from="VBoxContainer/character" to="." method="_on_character_changed"]
|
[connection signal="text_changed" from="VBoxContainer/character" to="." method="_on_character_changed"]
|
||||||
[connection signal="text_changed" from="VBoxContainer/target" to="." method="_on_target_changed"]
|
[connection signal="text_changed" from="VBoxContainer/target" to="." method="_on_target_changed"]
|
||||||
[connection signal="text_changed" from="VBoxContainer/turn_speed" to="." method="_on_turn_speed_changed"]
|
[connection signal="text_changed" from="VBoxContainer/turn_speed" to="." method="_on_turn_speed_changed"]
|
||||||
|
|||||||
3
addons/cutscene_editor/editor/nodes/WaitActionNode.gd
Executable file → Normal file
3
addons/cutscene_editor/editor/nodes/WaitActionNode.gd
Executable file → Normal file
@@ -6,10 +6,9 @@ extends "res://addons/cutscene_editor/editor/nodes/BaseGraphNode.gd"
|
|||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
node_type = "wait"
|
node_type = "wait"
|
||||||
node_id = "wait_" + str(randi())
|
|
||||||
title = "Wait"
|
title = "Wait"
|
||||||
modulate = Color(0.7, 0.7, 0.7) # Gray
|
modulate = Color(0.7, 0.7, 0.7) # Gray
|
||||||
|
node_id= "wait_" + str(randi())
|
||||||
# One input and one output connection
|
# One input and one output connection
|
||||||
var slot = 0
|
var slot = 0
|
||||||
set_slot(slot, true, 0, Color(0, 0, 0), true, 0, Color(0, 0, 0))
|
set_slot(slot, true, 0, Color(0, 0, 0), true, 0, Color(0, 0, 0))
|
||||||
|
|||||||
0
addons/cutscene_editor/icons/icon_animation.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_animation.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_dialogue.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_dialogue.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_entry.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_entry.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_exit.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_exit.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_move.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_move.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_parallel.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_parallel.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_turn.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_turn.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_wait.svg.import
Executable file → Normal file
0
addons/cutscene_editor/icons/icon_wait.svg.import
Executable file → Normal file
@@ -91,7 +91,8 @@ func _process(delta: float) -> void:
|
|||||||
# Main update loop
|
# Main update loop
|
||||||
if state != State.RUNNING:
|
if state != State.RUNNING:
|
||||||
return
|
return
|
||||||
# Find actions with no dependencies to start with
|
|
||||||
|
# Find actions with no dependencies to start with
|
||||||
_find_ready_actions()
|
_find_ready_actions()
|
||||||
|
|
||||||
# Start all ready actions
|
# Start all ready actions
|
||||||
@@ -143,10 +144,44 @@ func _execute_action(action_id: String) -> void:
|
|||||||
# Start the action
|
# Start the action
|
||||||
emit_signal("action_started", action)
|
emit_signal("action_started", action)
|
||||||
action.start()
|
action.start()
|
||||||
|
|
||||||
|
_debug_state()
|
||||||
|
|
||||||
func _on_action_started(action: Action) -> void:
|
func _on_action_started(action: Action) -> void:
|
||||||
# Handle action started
|
# Handle action started
|
||||||
emit_signal("action_started", action)
|
emit_signal("action_started", action)
|
||||||
|
_debug_state()
|
||||||
|
|
||||||
|
func _debug_state() -> void:
|
||||||
|
# Print debug information about all actions and their dependencies
|
||||||
|
print("=== Cutscene Manager Debug State ===")
|
||||||
|
print("State: %s" % ["IDLE", "RUNNING", "PAUSED"][state])
|
||||||
|
print("Actions count: %d" % actions.size())
|
||||||
|
print("Ready actions: %d" % ready_actions.size())
|
||||||
|
print("Active actions: %d" % active_actions.size())
|
||||||
|
print("Completed actions: %d" % completed_actions.size())
|
||||||
|
|
||||||
|
for action_id in actions:
|
||||||
|
var action = actions[action_id]
|
||||||
|
var action_state = ["PENDING", "RUNNING", "COMPLETED", "FAILED"][action.state]
|
||||||
|
|
||||||
|
# Get dependencies for this action
|
||||||
|
var deps = dependencies.get(action_id, [])
|
||||||
|
var deps_status = []
|
||||||
|
for dep_id in deps:
|
||||||
|
if completed_actions.has(dep_id):
|
||||||
|
deps_status.append("%s:COMPLETED" % dep_id)
|
||||||
|
elif active_actions.has(actions[dep_id]):
|
||||||
|
# Check if the dependency action is actually running
|
||||||
|
deps_status.append("%s:RUNNING" % dep_id)
|
||||||
|
else:
|
||||||
|
deps_status.append("%s:PENDING" % dep_id)
|
||||||
|
|
||||||
|
var deps_str = ", ".join(deps_status) if deps_status.size() > 0 else "None"
|
||||||
|
|
||||||
|
print("Action '%s': %s (deps: %s)" % [action_id, action_state, deps_str])
|
||||||
|
|
||||||
|
print("====================================")
|
||||||
|
|
||||||
func _on_action_completed(action_id: String) -> void:
|
func _on_action_completed(action_id: String) -> void:
|
||||||
# Handle action completion
|
# Handle action completion
|
||||||
@@ -165,6 +200,8 @@ func _on_action_completed(action_id: String) -> void:
|
|||||||
# Start all newly ready actions
|
# Start all newly ready actions
|
||||||
for new_action_id in ready_actions:
|
for new_action_id in ready_actions:
|
||||||
_execute_action(new_action_id)
|
_execute_action(new_action_id)
|
||||||
|
|
||||||
|
_debug_state()
|
||||||
|
|
||||||
func _on_action_failed(action: Action, error_message: String) -> void:
|
func _on_action_failed(action: Action, error_message: String) -> void:
|
||||||
# Handle action failure
|
# Handle action failure
|
||||||
|
|||||||
0
cutscene/actions/MoveAction.gd
Executable file → Normal file
0
cutscene/actions/MoveAction.gd
Executable file → Normal file
0
example_cutscene.tscn
Executable file → Normal file
0
example_cutscene.tscn
Executable file → Normal file
0
icon.svg.import
Executable file → Normal file
0
icon.svg.import
Executable file → Normal file
2
project.godot
Executable file → Normal file
2
project.godot
Executable file → Normal file
@@ -12,7 +12,7 @@ config_version=5
|
|||||||
|
|
||||||
config/name="adventure-ai"
|
config/name="adventure-ai"
|
||||||
run/main_scene="res://main.tscn"
|
run/main_scene="res://main.tscn"
|
||||||
config/features=PackedStringArray("4.2", "Forward Plus")
|
config/features=PackedStringArray("4.3", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|||||||
90
test_cutscene.tres
Executable file → Normal file
90
test_cutscene.tres
Executable file → Normal file
@@ -1,97 +1,69 @@
|
|||||||
[gd_resource type="Resource" script_class="CutsceneResource" load_steps=2 format=3 uid="uid://bfngefj7emehe"]
|
[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"]
|
[ext_resource type="Script" path="res://addons/cutscene_editor/editor/resources/CutsceneResource.gd" id="1_bldsf"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_p6huk")
|
script = ExtResource("1_bldsf")
|
||||||
nodes = [{
|
nodes = [{
|
||||||
"id": "entry_476938218",
|
"id": "entry_3571283853",
|
||||||
"parameters": {},
|
"parameters": {},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 262.0,
|
"x": 286.0,
|
||||||
"y": 155.0
|
"y": 192.0
|
||||||
},
|
},
|
||||||
"type": "entry"
|
"type": "entry"
|
||||||
}, {
|
}, {
|
||||||
"id": "move_3499731826",
|
"id": "move_189049872",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"character": "",
|
"MoveActionNode": 100.0,
|
||||||
"move_3499731826": 700.0,
|
"character": "Character1",
|
||||||
"speed": 100.0,
|
"speed": 100.0,
|
||||||
"target_x": 0.0,
|
"target_x": 101.0,
|
||||||
"target_y": 0.0
|
"target_y": 501.0
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 380.0,
|
"x": 500.0,
|
||||||
"y": 40.0
|
"y": 198.0
|
||||||
},
|
},
|
||||||
"type": "move"
|
"type": "move"
|
||||||
}, {
|
}, {
|
||||||
"id": "exit_1710964436",
|
"id": "exit_1874420853",
|
||||||
"parameters": {},
|
"parameters": {},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 1020.0,
|
"x": 1220.0,
|
||||||
"y": 140.0
|
"y": 220.0
|
||||||
},
|
},
|
||||||
"type": "exit"
|
"type": "exit"
|
||||||
}, {
|
}, {
|
||||||
"id": "move_2800650428",
|
"id": "turn_299006216",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"character": "",
|
"character": "Character2",
|
||||||
"move_2800650428": 91.0,
|
"target": "a",
|
||||||
"speed": 100.0,
|
"turn_speed": 200.0
|
||||||
"target_x": 0.0,
|
|
||||||
"target_y": 0.0
|
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 640.0,
|
"x": 880.0,
|
||||||
"y": 60.0
|
"y": 220.0
|
||||||
},
|
},
|
||||||
"type": "move"
|
"type": "turn"
|
||||||
}, {
|
|
||||||
"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 = [{
|
connections = [{
|
||||||
"from_node": "entry_476938218",
|
"from_node": "entry_3571283853",
|
||||||
"from_port": 0,
|
"from_port": 0,
|
||||||
"id": "conn_4022396",
|
"id": "conn_179030",
|
||||||
"to_node": "move_3499731826",
|
"to_node": "move_189049872",
|
||||||
"to_port": 0
|
"to_port": 0
|
||||||
}, {
|
}, {
|
||||||
"from_node": "move_3499731826",
|
"from_node": "move_189049872",
|
||||||
"from_port": 0,
|
"from_port": 0,
|
||||||
"id": "conn_4022396",
|
"id": "conn_179030",
|
||||||
"to_node": "move_2800650428",
|
"to_node": "turn_299006216",
|
||||||
"to_port": 0
|
"to_port": 0
|
||||||
}, {
|
}, {
|
||||||
"from_node": "move_2800650428",
|
"from_node": "turn_299006216",
|
||||||
"from_port": 0,
|
"from_port": 0,
|
||||||
"id": "conn_4022396",
|
"id": "conn_179030",
|
||||||
"to_node": "exit_1710964436",
|
"to_node": "exit_1874420853",
|
||||||
"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
|
"to_port": 0
|
||||||
}]
|
}]
|
||||||
metadata = {
|
metadata = {
|
||||||
|
|||||||
2
test_cutscene2.gd
Executable file → Normal file
2
test_cutscene2.gd
Executable file → Normal file
@@ -33,7 +33,7 @@ func setup_cutscene() -> void:
|
|||||||
cutscene_manager.connect("action_completed", _on_action_completed)
|
cutscene_manager.connect("action_completed", _on_action_completed)
|
||||||
|
|
||||||
# Create a cutscene resource with the same sequence as the original example
|
# Create a cutscene resource with the same sequence as the original example
|
||||||
var cutscene_resource = preload("res://test_cutscene.tres")
|
var cutscene_resource = preload("res://a.tres")
|
||||||
|
|
||||||
# Generate actions from the resource
|
# Generate actions from the resource
|
||||||
var generator = CutsceneGenerator.new()
|
var generator = CutsceneGenerator.new()
|
||||||
|
|||||||
0
test_cutscene2.tscn
Executable file → Normal file
0
test_cutscene2.tscn
Executable file → Normal file
@@ -1,50 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[gd_scene load_steps=2 format=2]
|
|
||||||
|
|
||||||
[node name="Node" type="Node"]
|
|
||||||
script = ExtResource( 1 )
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
0
test_resource_cutscene.tscn
Executable file → Normal file
0
test_resource_cutscene.tscn
Executable file → Normal file
Reference in New Issue
Block a user