274 lines
7.8 KiB
GDScript
274 lines
7.8 KiB
GDScript
@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 |