2024-03-12 16:31:26 +00:00
|
|
|
extends Node
|
|
|
|
class_name LevelManager
|
|
|
|
|
2024-03-16 04:25:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
@export_category("References")
|
2024-03-14 04:17:00 +00:00
|
|
|
|
|
|
|
## The [LevelPlaylist] to use to load [GolfLevel]s from.
|
|
|
|
@export var playlist: LevelPlaylist = null
|
|
|
|
|
|
|
|
## The [PlayerNodeDirectory] to use to determine which players to spawn on clients.
|
|
|
|
@export var player_dir: PlayerNodeDirectory = null
|
|
|
|
|
|
|
|
|
2024-03-16 04:55:02 +00:00
|
|
|
## Emitted when the [GolfBall] for the local player was spawned in a level.
|
|
|
|
signal local_player_spawned(ball: GolfBall, level: GolfLevel)
|
|
|
|
|
2024-03-16 04:25:23 +00:00
|
|
|
## Emitted when the current level is about to be destroyed.
|
|
|
|
signal level_destroying(level: GolfLevel)
|
|
|
|
|
|
|
|
## Emitted when the next level has been determined by calling [LevelPlaylist.advance].
|
|
|
|
signal level_determined(scene: PackedScene)
|
|
|
|
|
|
|
|
## Emitted when the new level has been added to the tree, but not built.
|
|
|
|
signal level_created(level: GolfLevel)
|
|
|
|
|
|
|
|
## Emitted when a level has been completed.
|
|
|
|
signal level_completed(level: GolfLevel)
|
|
|
|
|
|
|
|
## Emitted when all levels in the [field playlist] have been exausted.
|
|
|
|
signal playlist_complete(playlist: LevelPlaylist)
|
|
|
|
|
|
|
|
|
|
|
|
## The blank [GolfLevel] to initialize on clients.
|
|
|
|
const base_scene: PackedScene = preload("res://scenes/golf_level.tscn")
|
|
|
|
|
2024-03-14 04:17:00 +00:00
|
|
|
## The currently instantiated [GolfLevel].
|
|
|
|
var level: GolfLevel = null
|
|
|
|
|
|
|
|
|
|
|
|
## Create the empty [GolfLevel] object everywhere.
|
|
|
|
@rpc("authority", "call_local", "reliable")
|
|
|
|
func rpc_next_level():
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Advancinng to the next level!")
|
2024-03-14 04:17:00 +00:00
|
|
|
# Destroy the current level
|
|
|
|
if level != null:
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Destroying the current level: %s" % level)
|
|
|
|
level_destroying.emit(level)
|
2024-03-14 04:17:00 +00:00
|
|
|
level.queue_free()
|
|
|
|
level = null
|
2024-03-16 04:25:23 +00:00
|
|
|
# Determine the next level
|
|
|
|
Log.peer(self, "Determining the next level...")
|
|
|
|
var next = playlist.advance()
|
|
|
|
Log.peer(self, "Determined the next level: %s" % next)
|
|
|
|
level_determined.emit(next)
|
|
|
|
## Make sure the playlist hasn't been exausted
|
|
|
|
if next == null:
|
|
|
|
Log.peer(self, "Playlist is complete, not doing anything.")
|
|
|
|
playlist_complete.emit(playlist)
|
|
|
|
return
|
2024-03-14 04:17:00 +00:00
|
|
|
# Create the new level
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Instantiating empty level template...")
|
2024-03-14 04:17:00 +00:00
|
|
|
level = base_scene.instantiate()
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Instantiated empty level template: %s" % level)
|
|
|
|
# Configure the new level
|
|
|
|
Log.peer(self, "Configuring level variables...")
|
2024-03-14 04:17:00 +00:00
|
|
|
level.player_dir = player_dir
|
2024-03-16 04:55:02 +00:00
|
|
|
level.local_player_spawned.connect(_on_local_player_spawned)
|
2024-03-15 18:57:15 +00:00
|
|
|
level.level_completed.connect(_on_level_completed)
|
2024-03-14 04:17:00 +00:00
|
|
|
if multiplayer.is_server():
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Instantiating the target level scene...")
|
|
|
|
level.target = next.instantiate()
|
|
|
|
Log.peer(self, "Instantiated the target level scene: %s" % level.target)
|
2024-03-14 04:17:00 +00:00
|
|
|
# Add the level to the tree
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Adding level to the tree...")
|
2024-03-15 18:57:15 +00:00
|
|
|
add_child(level, true)
|
2024-03-16 04:25:23 +00:00
|
|
|
level_created.emit(level)
|
2024-03-14 04:17:00 +00:00
|
|
|
# Start the replication
|
|
|
|
if multiplayer.is_server():
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Building level...")
|
2024-03-14 04:17:00 +00:00
|
|
|
level.build()
|
2024-03-15 18:57:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _on_level_completed() -> void:
|
2024-03-16 04:25:23 +00:00
|
|
|
Log.peer(self, "Level completed!")
|
|
|
|
level_completed.emit(level)
|
|
|
|
if is_multiplayer_authority():
|
2024-03-15 18:57:15 +00:00
|
|
|
rpc_next_level.rpc()
|
2024-03-16 04:55:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _on_local_player_spawned(ball: GolfBall) -> void:
|
|
|
|
Log.peer(self, "Local player spawned: %s" % ball)
|
|
|
|
local_player_spawned.emit(ball, level)
|