progress.
This commit is contained in:
284
addons/cutscene_editor/editor/nodes/BaseGraphNode.gd
Normal file
284
addons/cutscene_editor/editor/nodes/BaseGraphNode.gd
Normal file
@@ -0,0 +1,284 @@
|
||||
@tool
|
||||
class_name BaseGraphNode
|
||||
extends GraphNode
|
||||
|
||||
# Base class for all cutscene graph nodes
|
||||
|
||||
# Signals
|
||||
signal node_selected2(node)
|
||||
signal node_deleted(node)
|
||||
signal parameter_changed(node, parameter_name, new_value)
|
||||
|
||||
# Node states
|
||||
enum NodeState {
|
||||
IDLE,
|
||||
ACTIVE,
|
||||
COMPLETED,
|
||||
ERROR,
|
||||
PAUSED
|
||||
}
|
||||
|
||||
# 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 = ""
|
||||
var property_editors: Dictionary = {} # Map of property names to editors
|
||||
|
||||
# Visual feedback elements
|
||||
var state_border: ColorRect
|
||||
var overlay_icon: TextureRect
|
||||
var checkmark_texture: Texture2D
|
||||
var error_texture: Texture2D
|
||||
var pause_texture: Texture2D
|
||||
|
||||
# Called when the node is ready
|
||||
func _ready() -> void:
|
||||
# Set up common node properties
|
||||
connect("dragged", _on_node_dragged)
|
||||
connect("selected", _on_node_selected)
|
||||
|
||||
# Add close butto
|
||||
|
||||
# Set up visual feedback elements
|
||||
_setup_visual_feedback()
|
||||
|
||||
# Add parameter fields based on node type
|
||||
_setup_parameter_fields()
|
||||
|
||||
# Set up visual feedback elements
|
||||
func _setup_visual_feedback() -> void:
|
||||
# Create state border
|
||||
state_border = ColorRect.new()
|
||||
state_border.name = "StateBorder"
|
||||
state_border.anchor_right = 1
|
||||
state_border.anchor_bottom = 1
|
||||
state_border.margin_left = -2
|
||||
state_border.margin_top = -2
|
||||
state_border.margin_right = 2
|
||||
state_border.margin_bottom = 2
|
||||
state_border.color = Color(0, 0, 0, 0) # Transparent by default
|
||||
state_border.z_index = -1 # Behind the node
|
||||
add_child(state_border)
|
||||
|
||||
# Create overlay icon container
|
||||
var overlay_container = CenterContainer.new()
|
||||
overlay_container.name = "OverlayContainer"
|
||||
overlay_container.anchor_right = 1
|
||||
overlay_container.anchor_bottom = 1
|
||||
overlay_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
add_child(overlay_container)
|
||||
|
||||
# Create overlay icon
|
||||
overlay_icon = TextureRect.new()
|
||||
overlay_icon.name = "OverlayIcon"
|
||||
overlay_icon.expand = true
|
||||
overlay_icon.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
overlay_icon.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
overlay_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
overlay_container.add_child(overlay_icon)
|
||||
|
||||
# Load textures (these would be actual textures in a real implementation)
|
||||
# checkmark_texture = preload("res://addons/cutscene_editor/icons/checkmark.png")
|
||||
# error_texture = preload("res://addons/cutscene_editor/icons/error.png")
|
||||
# pause_texture = preload("res://addons/cutscene_editor/icons/pause.png")
|
||||
|
||||
# Set up parameter fields based on node type
|
||||
func _setup_parameter_fields() -> void:
|
||||
# This method should be overridden by subclasses
|
||||
pass
|
||||
|
||||
# Set node state and update visual feedback
|
||||
func set_state(new_state: int, error_msg: String = "") -> void:
|
||||
current_state = new_state
|
||||
error_message = error_msg
|
||||
_update_visual_feedback()
|
||||
|
||||
# Update visual feedback based on current state
|
||||
func _update_visual_feedback() -> void:
|
||||
match current_state:
|
||||
NodeState.IDLE:
|
||||
_set_idle_state()
|
||||
NodeState.ACTIVE:
|
||||
_set_active_state()
|
||||
NodeState.COMPLETED:
|
||||
_set_completed_state()
|
||||
NodeState.ERROR:
|
||||
_set_error_state()
|
||||
NodeState.PAUSED:
|
||||
_set_paused_state()
|
||||
|
||||
# Set idle state visuals
|
||||
func _set_idle_state() -> void:
|
||||
# Reset to default appearance
|
||||
state_border.color = Color(0, 0, 0, 0)
|
||||
overlay_icon.texture = null
|
||||
modulate = Color(1, 1, 1, 1)
|
||||
scale = Vector2(1, 1)
|
||||
|
||||
# Stop any animations
|
||||
_stop_animations()
|
||||
|
||||
# Set active state visuals
|
||||
func _set_active_state() -> void:
|
||||
# White border highlight
|
||||
state_border.color = Color(1, 1, 1, 1)
|
||||
state_border.size = Vector2(2, 2)
|
||||
|
||||
# Clear overlay
|
||||
overlay_icon.texture = null
|
||||
|
||||
# Start pulsing animation
|
||||
_start_pulsing_animation()
|
||||
|
||||
# Slight scale increase
|
||||
scale = Vector2(1.05, 1.05)
|
||||
|
||||
# Set completed state visuals
|
||||
func _set_completed_state() -> void:
|
||||
# Green border
|
||||
state_border.color = Color(0, 1, 0, 0.5)
|
||||
state_border.size = Vector2(2, 2)
|
||||
|
||||
# Checkmark overlay
|
||||
overlay_icon.texture = checkmark_texture
|
||||
overlay_icon.modulate = Color(0, 1, 0, 0.7)
|
||||
|
||||
# Slight transparency
|
||||
modulate = Color(1, 1, 1, 0.8)
|
||||
|
||||
# Stop animations
|
||||
_stop_animations()
|
||||
|
||||
# Set error state visuals
|
||||
func _set_error_state() -> void:
|
||||
# Red border
|
||||
state_border.color = Color(1, 0, 0, 1)
|
||||
state_border.size = Vector2(3, 3)
|
||||
|
||||
# Error icon overlay
|
||||
overlay_icon.texture = error_texture
|
||||
overlay_icon.modulate = Color(1, 0, 0, 1)
|
||||
|
||||
# Red tint
|
||||
modulate = Color(1, 0.7, 0.7, 1)
|
||||
|
||||
# Start shake animation
|
||||
_start_shake_animation()
|
||||
|
||||
# Set paused state visuals
|
||||
func _set_paused_state() -> void:
|
||||
# Yellow border
|
||||
state_border.color = Color(1, 1, 0, 1)
|
||||
state_border.size = Vector2(2, 2)
|
||||
|
||||
# Pause icon overlay
|
||||
overlay_icon.texture = pause_texture
|
||||
overlay_icon.modulate = Color(1, 1, 0, 1)
|
||||
|
||||
# Stop animations
|
||||
_stop_animations()
|
||||
|
||||
# Animation functions
|
||||
func _start_pulsing_animation() -> void:
|
||||
# Create animation player for pulsing effect
|
||||
var anim_player = AnimationPlayer.new()
|
||||
anim_player.name = "StateAnimationPlayer"
|
||||
|
||||
# Remove existing animation player if present
|
||||
var existing_player = get_node_or_null("StateAnimationPlayer")
|
||||
if existing_player:
|
||||
remove_child(existing_player)
|
||||
existing_player.queue_free()
|
||||
|
||||
add_child(anim_player)
|
||||
|
||||
# Create pulsing animation
|
||||
var animation = Animation.new()
|
||||
animation.name = "pulse"
|
||||
animation.length = 1.0
|
||||
animation.loop_mode = Animation.LOOP_LINEAR
|
||||
|
||||
# Scale property track
|
||||
var scale_track = animation.add_track(Animation.TYPE_VALUE)
|
||||
animation.track_set_path(scale_track, ".:scale")
|
||||
animation.track_insert_key(scale_track, 0.0, Vector2(1.05, 1.05))
|
||||
animation.track_insert_key(scale_track, 0.5, Vector2(1.1, 1.1))
|
||||
animation.track_insert_key(scale_track, 1.0, Vector2(1.05, 1.05))
|
||||
|
||||
anim_player.add_animation("pulse", animation)
|
||||
anim_player.play("pulse")
|
||||
|
||||
func _start_shake_animation() -> void:
|
||||
# Create animation player for shake effect
|
||||
var anim_player = AnimationPlayer.new()
|
||||
anim_player.name = "StateAnimationPlayer"
|
||||
|
||||
# Remove existing animation player if present
|
||||
var existing_player = get_node_or_null("StateAnimationPlayer")
|
||||
if existing_player:
|
||||
remove_child(existing_player)
|
||||
existing_player.queue_free()
|
||||
|
||||
add_child(anim_player)
|
||||
|
||||
# Create shake animation
|
||||
var animation = Animation.new()
|
||||
animation.name = "shake"
|
||||
animation.length = 0.5
|
||||
animation.loop_mode = Animation.LOOP_LINEAR
|
||||
|
||||
# Position property track
|
||||
var position_track = animation.add_track(Animation.TYPE_VALUE)
|
||||
animation.track_set_path(position_track, ".:position_offset")
|
||||
animation.track_insert_key(position_track, 0.0, position_offset)
|
||||
animation.track_insert_key(position_track, 0.1, position_offset + Vector2(2, 0))
|
||||
animation.track_insert_key(position_track, 0.2, position_offset + Vector2(-2, 0))
|
||||
animation.track_insert_key(position_track, 0.3, position_offset + Vector2(0, 2))
|
||||
animation.track_insert_key(position_track, 0.4, position_offset + Vector2(0, -2))
|
||||
animation.track_insert_key(position_track, 0.5, position_offset)
|
||||
|
||||
anim_player.add_animation("shake", animation)
|
||||
anim_player.play("shake")
|
||||
|
||||
func _stop_animations() -> void:
|
||||
var anim_player = get_node_or_null("StateAnimationPlayer")
|
||||
if anim_player:
|
||||
anim_player.stop()
|
||||
|
||||
# Update parameter value
|
||||
func set_parameter(parameter_name: String, value) -> void:
|
||||
action_parameters[parameter_name] = value
|
||||
|
||||
# Update editor if it exists
|
||||
if property_editors.has(parameter_name):
|
||||
var editor = property_editors[parameter_name]
|
||||
editor.set_value(value)
|
||||
|
||||
emit_signal("parameter_changed", self, parameter_name, value)
|
||||
|
||||
# Get parameter value
|
||||
func get_parameter(parameter_name: String):
|
||||
return action_parameters.get(parameter_name, null)
|
||||
|
||||
# Handle node dragging
|
||||
func _on_node_dragged(from: Vector2, to: Vector2) -> void:
|
||||
# Update position
|
||||
position_offset = to
|
||||
|
||||
# Handle node selection
|
||||
func _on_node_selected() -> void:
|
||||
emit_signal("node_selected2", self)
|
||||
|
||||
|
||||
# Clear parameter fields
|
||||
func _clear_parameter_fields() -> void:
|
||||
# Remove existing editors
|
||||
for param_name in property_editors:
|
||||
var editor = property_editors[param_name]
|
||||
if editor.get_parent() == self:
|
||||
remove_child(editor)
|
||||
editor.queue_free()
|
||||
|
||||
property_editors.clear()
|
||||
Reference in New Issue
Block a user