Files
experiment-adventure-ai/addons/cutscene_editor/editor/nodes/ParallelGroupNode.gd
2025-07-31 09:27:26 -07:00

127 lines
4.1 KiB
GDScript

@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"
node_id = "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"