initial
This commit is contained in:
228
cutscene/CutsceneManager.gd
Normal file
228
cutscene/CutsceneManager.gd
Normal file
@@ -0,0 +1,228 @@
|
||||
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
|
||||
|
||||
# State management
|
||||
enum State {
|
||||
IDLE, # Not running any cutscene
|
||||
RUNNING, # Currently executing a cutscene
|
||||
PAUSED # Cutscene is paused
|
||||
}
|
||||
|
||||
var state: int = State.IDLE
|
||||
var is_active: bool = false
|
||||
|
||||
# Signals
|
||||
signal cutscene_started()
|
||||
signal cutscene_completed()
|
||||
signal cutscene_paused()
|
||||
signal cutscene_resumed()
|
||||
signal action_started(action)
|
||||
signal action_completed(action)
|
||||
signal action_failed(action, error_message)
|
||||
|
||||
# Public methods
|
||||
func start() -> void:
|
||||
# Start executing the cutscene
|
||||
if state != State.IDLE:
|
||||
return
|
||||
|
||||
state = State.RUNNING
|
||||
is_active = true
|
||||
emit_signal("cutscene_started")
|
||||
|
||||
# Start first action
|
||||
_execute_next_action()
|
||||
|
||||
func pause() -> void:
|
||||
# Pause the current cutscene
|
||||
if state == State.RUNNING:
|
||||
state = State.PAUSED
|
||||
emit_signal("cutscene_paused")
|
||||
|
||||
func resume() -> void:
|
||||
# Resume a paused cutscene
|
||||
if state == State.PAUSED:
|
||||
state = State.RUNNING
|
||||
emit_signal("cutscene_resumed")
|
||||
|
||||
func stop() -> void:
|
||||
# Stop the current cutscene and reset
|
||||
if current_action != null:
|
||||
current_action.stop()
|
||||
current_action = null
|
||||
|
||||
# Stop all active parallel groups
|
||||
for group in active_parallel_groups:
|
||||
for action in group["actions"]:
|
||||
if action.state == action.State.RUNNING:
|
||||
action.stop()
|
||||
|
||||
_reset()
|
||||
|
||||
func add_action(action: Action) -> void:
|
||||
# Add a single action to the sequential queue
|
||||
if state != State.IDLE:
|
||||
print("Warning: Cannot add actions while cutscene is running")
|
||||
return
|
||||
|
||||
sequential_actions.append(action)
|
||||
|
||||
func add_parallel_actions(actions: Array) -> void:
|
||||
# Add a group of actions to run in parallel
|
||||
if state != State.IDLE:
|
||||
print("Warning: Cannot add actions while cutscene is running")
|
||||
return
|
||||
|
||||
if actions.size() == 0:
|
||||
return
|
||||
|
||||
# Create a parallel action group
|
||||
var group = {
|
||||
"actions": actions,
|
||||
"completed_count": 0,
|
||||
"total_count": actions.size()
|
||||
}
|
||||
|
||||
# Add to sequential actions as a single item
|
||||
sequential_actions.append(group)
|
||||
|
||||
# Internal methods
|
||||
func _process(delta: float) -> void:
|
||||
# Main update loop
|
||||
if state != State.RUNNING:
|
||||
return
|
||||
|
||||
# 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)
|
||||
|
||||
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
|
||||
|
||||
var action_item = sequential_actions[action_index]
|
||||
action_index += 1
|
||||
|
||||
# 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)
|
||||
|
||||
func _execute_single_action(action: Action) -> void:
|
||||
# Execute a single action
|
||||
current_action = action
|
||||
|
||||
# Connect to action signals
|
||||
if not action.is_connected("completed", _on_action_completed):
|
||||
action.connect("completed", _on_action_completed.bind(action))
|
||||
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):
|
||||
action.connect("started", _on_action_started.bind(action))
|
||||
|
||||
# Start the action
|
||||
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:
|
||||
# Handle action completion
|
||||
if action == current_action:
|
||||
current_action = null
|
||||
emit_signal("action_completed", action)
|
||||
# Move to next action
|
||||
_execute_next_action()
|
||||
|
||||
func _on_action_failed(action: Action, error_message: String) -> void:
|
||||
# Handle action failure
|
||||
if action == current_action:
|
||||
current_action = null
|
||||
|
||||
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
|
||||
is_active = false
|
||||
emit_signal("cutscene_completed")
|
||||
|
||||
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
|
||||
state = State.IDLE
|
||||
is_active = false
|
||||
Reference in New Issue
Block a user