progress
This commit is contained in:
196
cutscene/CutsceneManager.gd
Normal file → Executable file
196
cutscene/CutsceneManager.gd
Normal file → Executable file
@@ -1,14 +1,13 @@
|
||||
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
|
||||
# Action dependency graph
|
||||
var actions: Dictionary = {} # Map of action IDs to action instances
|
||||
var dependencies: Dictionary = {} # Map of action IDs to their dependency lists
|
||||
var dependents: Dictionary = {} # Map of action IDs to actions that depend on them
|
||||
var ready_actions: Array = [] # Actions that are ready to execute (all dependencies met)
|
||||
var active_actions: Array = [] # Currently running actions
|
||||
var completed_actions: Array = [] # Actions that have completed
|
||||
|
||||
# State management
|
||||
enum State {
|
||||
@@ -39,8 +38,16 @@ func start() -> void:
|
||||
is_active = true
|
||||
emit_signal("cutscene_started")
|
||||
|
||||
# Start first action
|
||||
_execute_next_action()
|
||||
# Find actions with no dependencies to start with
|
||||
_find_ready_actions()
|
||||
|
||||
# Start all ready actions
|
||||
for action_id in ready_actions:
|
||||
_execute_action(action_id)
|
||||
|
||||
# Check if there are no actions to execute
|
||||
if actions.size() == 0:
|
||||
_on_cutscene_completed()
|
||||
|
||||
func pause() -> void:
|
||||
# Pause the current cutscene
|
||||
@@ -56,67 +63,78 @@ func resume() -> void:
|
||||
|
||||
func stop() -> void:
|
||||
# Stop the current cutscene and reset
|
||||
if current_action != null:
|
||||
current_action.stop()
|
||||
current_action = null
|
||||
# Stop all active actions
|
||||
for action in active_actions:
|
||||
if action.state == action.State.RUNNING:
|
||||
action.stop()
|
||||
|
||||
# Stop all active parallel groups
|
||||
for group in active_parallel_groups:
|
||||
for action in group["actions"]:
|
||||
if action.state == action.State.RUNNING:
|
||||
action.stop()
|
||||
active_actions.clear()
|
||||
|
||||
_reset()
|
||||
|
||||
func add_action(action: Action) -> void:
|
||||
# Add a single action to the sequential queue
|
||||
func add_action(action_id: String, action: Action, deps: Array = []) -> void:
|
||||
# Add an action with its dependencies
|
||||
if state != State.IDLE:
|
||||
print("Warning: Cannot add actions while cutscene is running")
|
||||
return
|
||||
|
||||
sequential_actions.append(action)
|
||||
actions[action_id] = action
|
||||
dependencies[action_id] = deps
|
||||
# Build reverse dependency map (dependents)
|
||||
for dep_id in deps:
|
||||
if not dependents.has(dep_id):
|
||||
dependents[dep_id] = []
|
||||
dependents[dep_id].append(action_id)
|
||||
|
||||
# Internal methods
|
||||
func _process(delta: float) -> void:
|
||||
# Main update loop
|
||||
if state != State.RUNNING:
|
||||
return
|
||||
# Find actions with no dependencies to start with
|
||||
_find_ready_actions()
|
||||
|
||||
# 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)
|
||||
# Start all ready actions
|
||||
for action_id in ready_actions:
|
||||
_execute_action(action_id)
|
||||
|
||||
# Update all active actions
|
||||
for action in active_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
|
||||
func _find_ready_actions() -> void:
|
||||
# Find actions that are ready to execute (all dependencies met)
|
||||
ready_actions.clear()
|
||||
|
||||
var action_item = sequential_actions[action_index]
|
||||
action_index += 1
|
||||
print(action_item)
|
||||
# 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)
|
||||
for action_id in actions:
|
||||
# Skip if already completed or active
|
||||
if completed_actions.has(action_id) or active_actions.has(actions[action_id]):
|
||||
continue
|
||||
|
||||
# Check if all dependencies are met
|
||||
var all_deps_met = true
|
||||
for dep_id in dependencies[action_id]:
|
||||
if not completed_actions.has(dep_id):
|
||||
all_deps_met = false
|
||||
break
|
||||
|
||||
func _execute_single_action(action: Action) -> void:
|
||||
if all_deps_met:
|
||||
ready_actions.append(action_id)
|
||||
|
||||
func _execute_action(action_id: String) -> void:
|
||||
# Execute a single action
|
||||
current_action = action
|
||||
var action = actions[action_id]
|
||||
|
||||
# Remove from ready actions
|
||||
ready_actions.erase(action_id)
|
||||
|
||||
# Add to active actions
|
||||
active_actions.append(action)
|
||||
|
||||
# Connect to action signals
|
||||
if not action.is_connected("completed", _on_action_completed):
|
||||
action.connect("completed", _on_action_completed.bind(action))
|
||||
action.connect("completed", _on_action_completed.bind(action_id))
|
||||
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):
|
||||
@@ -126,72 +144,37 @@ func _execute_single_action(action: Action) -> void:
|
||||
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:
|
||||
func _on_action_completed(action_id: String) -> void:
|
||||
# Handle action completion
|
||||
if action == current_action:
|
||||
current_action = null
|
||||
emit_signal("action_completed", action)
|
||||
# Move to next action
|
||||
_execute_next_action()
|
||||
var action = actions[action_id]
|
||||
active_actions.erase(action)
|
||||
completed_actions.append(action_id)
|
||||
emit_signal("action_completed", action)
|
||||
|
||||
# Check if all actions are completed
|
||||
if completed_actions.size() == actions.size():
|
||||
_on_cutscene_completed()
|
||||
else:
|
||||
# Find newly ready actions
|
||||
_find_ready_actions()
|
||||
|
||||
# Start all newly ready actions
|
||||
for new_action_id in ready_actions:
|
||||
_execute_action(new_action_id)
|
||||
|
||||
func _on_action_failed(action: Action, error_message: String) -> void:
|
||||
# Handle action failure
|
||||
if action == current_action:
|
||||
current_action = null
|
||||
active_actions.erase(action)
|
||||
|
||||
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
|
||||
@@ -200,10 +183,11 @@ func _on_cutscene_completed() -> void:
|
||||
|
||||
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
|
||||
actions.clear()
|
||||
dependencies.clear()
|
||||
dependents.clear()
|
||||
ready_actions.clear()
|
||||
active_actions.clear()
|
||||
completed_actions.clear()
|
||||
state = State.IDLE
|
||||
is_active = false
|
||||
|
||||
Reference in New Issue
Block a user