This repository has been archived on 2024-04-19. You can view files and clone it, but cannot push or open issues or pull requests.
Jessist/Scripts/GameController.gd

485 lines
18 KiB
GDScript3
Raw Permalink Normal View History

2022-06-18 13:05:48 +02:00
######################
### Jessist Script ###
######################
# This script is part of Jessist
# Jessist is licensed under GNU GPLv3
#
# This script manages basically all important and shared functions and variables
# used throughout Jessist.
# It currently contains:
# - a logger,
# - scene switcher with fade transition,
# - music player,
# - crash function,
# - dialog manager
# NOTE: This code is pretty much imported from documentation with a few modifications « Bullshit
# Link: https://docs.godotengine.org/en/stable/tutorials/scripting/singletons_autoload.html « Bullshit
extends Node
var currentDialog = null
var dialogBalloon = ResourceLoader.load("res://Dialog/dialog/dialog.tscn").instance()
var currentScene = null
var loadingScene = ResourceLoader.load("res://Scenes/LoadingScene.tscn").instance()
var transitionScene = ResourceLoader.load("res://Scenes/Transition.tscn").instance()
var countersScene = ResourceLoader.load("res://Scenes/Modules/Counters.tscn").instance()
var crashScene = ResourceLoader.load("res://Scenes/CrashHandler.tscn").instance()
var debugConsoleScene = ResourceLoader.load("res://Scenes/Modules/DebugConsole.tscn").instance()
var transitionState = 0
var music = AudioStreamPlayer.new()
var sound = AudioStreamPlayer.new()
export (bool) var debuggingMode = OS.is_debug_build()
export (bool) var enableVerbosity = true
export (bool) var enableVelocityMessages = true
export (bool) var enableFunctionCalls = true
export (bool) var enableCounters = false
export (bool) var logger = true
export (bool) var loggerInfo = true
export (bool) var loggerWarn = true
export (bool) var loggerError = true
export (bool) var gamePaused = false
export (float, -60, -5) var musicVolumeDefault = -5
export (float, -60, -5) var musicVolumePaused = -15
export (float, -60, -5) var musicVolumeLoad = -40
export (float) var musicVolume = 0
export (String, "Rocket") var musicPlaying = "Rocket"
export (AudioStreamOGGVorbis) var musicStream = null
export (String) var soundPlaying = null
export (AudioStreamOGGVorbis) var soundStream = null
export (bool) var soundAllow = true
export (bool) var musicAllow = true
export (bool) var allowCheats = true
export (bool) var crashed = false
var thread = null
var threadMusic = null
var threadMusicPlay = null
var threadSound = null
var threadSoundPlay = null
var transitionThread = null
var logSchema = "[%logtype%] [%script% | %function%] %message%"
var sessionLog = Array()
enum logTypes {CALL,ERRO,WARN,INFO,VERB,VEPO}
func _ready():
if debuggingMode:
logInfo("GameController","_ready","Developer Mode is activated. If this should be a production build, DISABLE debuggingMode IN GameController.gd NOW.")
else:
pass
#enableVerbosity = false
#enableVelocityMessages = false
#enableFunctionCalls = false
#enableCounters = false
if not enableVerbosity:
enableVelocityMessages = false
enableFunctionCalls = false
if not logger:
loggerInfo = false
loggerWarn = false
loggerError = false
currentScene = get_tree().get_root().get_child(get_tree().get_root().get_child_count() - 1)
logInfo("GameController","_ready","Initialization done")
func _process(_delta):
if Input.is_action_just_pressed("debug_console") and debuggingMode:
get_tree().get_root().add_child(debugConsoleScene)
func switchToMainScreen(loadGame):
logInfo("GameController","switchToMainScreen","Request for scene switch to MainScreen accepted")
logInfo("GameController","switchScene","GCSC Waiting for all threads to finish execution")
if loadGame:
call_deferred("_switchScene_deferred", "res://Scenes/MainScreen.tscn", false)
else:
call_deferred("_switchScene_deferred", "res://Scenes/MainScreen.tscn", false)
func switchScene(path):
logInfo("GameController","switchScene","Request for scene switch accepted")
gamePaused = true
logInfo("GameController","switchScene","Waiting for all threads to finish execution")
call_deferred("_switchScene_deferred", path, false)
func _switchScene_deferred(path, isMainScreen):
logInfo("GameController","_switchScene_deferred","Threads finished execution")
_transition_start()
while true:
yield(get_tree().create_timer(0.01), "timeout")
if transitionState == 1:
continue
else:
break
logInfo("GameController","_switchScene_deferred","Removing scenes")
for child in get_tree().get_root().get_children():
if child.name == "gameController" or child.name == "sp" or child.name == "gd" or child.name == "scene_manager" or child.name == "Transition" or child.name == music.name or child.name == "CrashHandler":
continue
logInfo("GameController","_switchScene_deferred","Removing child " + child.name)
get_tree().get_root().remove_child(child)
if currentScene != null:
logInfo("GameController","_switchScene_deferred","Freeing currentScene")
currentScene.free()
logInfo("GameController","_switchScene_deferred","Displaying loading scene")
get_tree().get_root().add_child(loadingScene)
get_tree().set_current_scene(loadingScene)
transitionState = 2
while true:
yield(get_tree().create_timer(0.01), "timeout")
if transitionState == 3:
continue
else:
break
while true:
yield(get_tree().create_timer(0.01), "timeout")
if transitionState == 2:
continue
else:
break
var waitnum = 0
if isMainScreen:
waitnum = 8.25
else:
waitnum = 1.25
logInfo("GameController","_switchScene_deferred","Waiting " + str(waitnum) + "s")
yield(get_tree().create_timer(waitnum),"timeout")
logInfo("GameController","_switchScene_deferred","Starting thread")
thread = Thread.new()
thread.start(self, "_switchScene_thread_start", path)
func _switchScene_thread_start(path):
logInfo("GameController","_switchScene_thread_start","Loading and instancing scene")
var loader = ResourceLoader.load_interactive(path)
while true:
if loader.poll() == ERR_FILE_EOF:
currentScene = loader.get_resource().instance()
break
call_deferred("_switchScene_thread_end")
func _switchScene_thread_end():
_transition_start()
while true:
yield(get_tree().create_timer(0.01), "timeout")
if transitionState == 1:
continue
else:
break
logInfo("GameController","_switchScene_thread_end","Displaying scene " + currentScene.name)
get_tree().get_root().add_child(currentScene)
get_tree().set_current_scene(currentScene)
if enableCounters:
logInfo("GameController","_switchScene_thread_end","Adding counters")
get_tree().get_root().add_child(countersScene)
logInfo("GameController","_switchScene_thread_end","Removing loading scene")
for child in get_tree().get_root().get_children():
if child.name == "LoadingScene":
get_tree().get_root().remove_child(child)
transitionState = 2
gamePaused = false
while true:
yield(get_tree().create_timer(0.01), "timeout")
if transitionState == 3:
continue
else:
break
logInfo("GameController","_switchScene_thread_end","Execution done")
func transitionSwitch():
logInfo("GameController","transitionSwitch","Call to transitionSwitch() detected. Please remove that line from your script.")
func _transition_start():
changeVolume("volumePaused")
logInfo("GameController","_transition_start","Adding TransitionScene")
get_tree().get_root().add_child(transitionScene)
var transition = get_node("/root/Transition")
logInfo("GameController","_transition_start","Starting FADEIN transition")
transitionState = 1
transition.startTransition(transition.transitionStates.FADEIN)
yield(get_tree().create_timer(0.5), "timeout")
logInfo("GameController","_transition_start","FADEIN transition done")
transitionState = 3
transitionThread = Thread.new()
transitionThread.start(self,"_transition_start_thread",transition)
func _transition_start_thread(transition):
logInfo("GameController","_transition_start","Waiting for FADEOUT allowance")
while true:
yield(get_tree().create_timer(0.01), "timeout")
if transitionState == 2:
break
else:
continue
logInfo("GameController","_transition_start","Starting FADEOUT transition")
transition.startTransition(transition.transitionStates.FADEOUT)
yield(get_tree().create_timer(0.5), "timeout")
logInfo("GameController","_transition_start","FADEOUT transition done")
changeVolume("volumeDefault")
_transition_end()
func _transition_end():
for child in get_tree().get_root().get_children():
if child.name == "Transition":
logInfo("GameController","_transition_end","Removing TransitionScene")
get_tree().get_root().remove_child(child)
transitionState = 0
func _logger(logtype,script,function,message):
if logger:
if logtype == logTypes.CALL:
logtype = "CALL"
elif logtype == logTypes.ERRO:
logtype = "ERRO"
elif logtype == logTypes.INFO:
logtype = "INFO"
elif logtype == logTypes.WARN:
logtype = "WARN"
elif logtype == logTypes.VERB:
logtype = "VERB"
elif logtype == logTypes.VEPO:
logtype = "VEPO"
print(logSchema.replace("%logtype%",logtype).replace("%script%",script).replace("%function%",function).replace("%message%",message))
sessionLog.append(logSchema.replace("%logtype%",logtype).replace("%script%",script).replace("%function%",function).replace("%message%",message))
func logCall(script,function,args):
if not enableFunctionCalls:
return
if function == "_ready":
_logger(logTypes.CALL,script,function,"Starting initialization of script " + script)
return
args = str(args)
if args == "" or args == null or args == "Null":
_logger(logTypes.CALL,script,function,"Function was called")
else:
_logger(logTypes.CALL,script,function,"Function was called with arguments " + args)
func logInfo(script,function,message):
if not loggerInfo:
return
_logger(logTypes.INFO,script,function,message)
func logWarn(script,function,message):
if not loggerWarn:
return
_logger(logTypes.WARN,script,function,message)
func logError(script,function,message):
if not loggerError:
return
_logger(logTypes.ERRO,script,function,message)
func logVerbose(script,function,message):
if not enableVerbosity:
return
_logger(logTypes.VERB,script,function,message)
func logVelocity(script,function,messageVelocityPosition):
if not enableVelocityMessages:
return
var message = null
if typeof(messageVelocityPosition) == typeof(Vector2(0,0)):
message = "VELO/POS » X: " + str(messageVelocityPosition.x) + " | Y: " + str(messageVelocityPosition.y)
else:
message = str(messageVelocityPosition)
_logger(logTypes.VEPO,script,function,message)
func loadSound(effect):
if not soundAllow:
return
if effect == null or effect == "":
logInfo("GameController","loadSound","Argument is null")
soundPlaying = effect
logInfo("GameController","loadSound","Loading sound " + soundPlaying)
soundStream = load("res://Sounds/" + soundPlaying + ".ogg")
sound.stream = soundStream
sound.volume_db = 0
get_tree().get_root().add_child(sound)
func playSound(delay):
if not soundAllow:
return
if soundStream == null:
logInfo("GameController","playSound","Sound stream is not loaded")
return
threadSoundPlay = Thread.new()
threadSoundPlay.start(self, "_playSound_thread",delay)
func _playSound_thread(delay):
yield(get_tree().create_timer(delay), "timeout")
for child in get_tree().get_root().get_children():
if child.name == sound.name:
logInfo("GameController","playSound","Starting playback")
child.play(0)
func stopSound(wildcardOrSound):
for child in get_tree().get_root().get_children():
if typeof(wildcardOrSound) == typeof(true):
if wildcardOrSound:
if child.name == sound.name:
logInfo("GameController","stopSound","Stopping playback of every sound")
get_tree().get_root().remove_child(child)
else:
logInfo("GameController","stopSound","Wildcard is disabled")
else:
if child.name == sound.name and sound.stream.resource_path == "res://Sounds/" + sound + ".ogg":
logInfo("GameController","stopSound","Stopping playback of sound " + sound)
get_tree().get_root().remove_child(child)
func loadMusic(song):
if not musicAllow:
return
if song == null or song == "":
logInfo("GameController","loadMusic","Argument is null")
stopMusic()
musicPlaying = song
logInfo("GameController","loadMusic","Loading music " + musicPlaying)
musicStream = load("res://Sounds/Music/" + musicPlaying + ".ogg")
music.stream = musicStream
music.volume_db = musicVolumeLoad
musicVolume = musicVolumeLoad
get_tree().get_root().add_child(music)
func playMusic(delay):
if not musicAllow:
return
if musicStream == null:
logInfo("GameController","playMusic","Music stream is not loaded")
return
threadMusicPlay = Thread.new()
threadMusicPlay.start(self,"_playMusic_thread",delay)
func _playMusic_thread(delay):
if not delay == null:
yield(get_tree().create_timer(delay), "timeout")
for child in get_tree().get_root().get_children():
if child.name == music.name:
logInfo("GameController","playMusic","Starting playback")
child.play(0)
func stopMusic():
for child in get_tree().get_root().get_children():
if child.name == music.name:
logInfo("GameController","stopMusic","Stopping playback")
get_tree().get_root().remove_child(child)
func pauseMusic():
for child in get_tree().get_root().get_children():
if child.name == music.name:
if child.playing:
logInfo("GameController","pauseMusic","Pausing playback")
child.playing = false
func continueMusic():
for child in get_tree().get_root().get_children():
if child.name == music.name:
if not child.playing:
logInfo("GameController","continueMusic","Continuing playback")
child.playing = true
func changeVolume(valueOrSetValue):
logInfo("GameController","changeVolume","Changing volume")
if typeof(valueOrSetValue) == typeof(""):
if valueOrSetValue == "volumeDefault":
threadMusic = Thread.new()
threadMusic.start(self, "_changeVolume_thread", musicVolumeDefault)
elif valueOrSetValue == "volumePaused":
threadMusic = Thread.new()
threadMusic.start(self, "_changeVolume_thread", musicVolumePaused)
else:
logInfo("GameController","changeVolume","Invalid SetValue. Please use volumeDefault, volumePaused or a custom number")
return
elif typeof(valueOrSetValue) == typeof(float(0)):
threadMusic = Thread.new()
threadMusic.start(self, "_changeVolume_thread", valueOrSetValue)
else:
logInfo("GameController","changeVolume","Invalid argument type. Please use a volumeDefault, volumePaused or a custom number")
return
func _changeVolume_thread(volume):
var musicplayer = null
for child in get_tree().get_root().get_children():
if child.name == music.name:
musicplayer = child
if musicplayer == null:
logInfo("GameController","changeVolume","Music player not found")
return
while true:
if volume == musicplayer.volume_db:
break
elif volume >= musicplayer.volume_db:
musicplayer.volume_db += 1
elif volume <= musicplayer.volume_db:
musicplayer.volume_db -= 1
logInfo("GameController","changeVolume","Volume: " + str(musicplayer.volume_db))
musicVolume = musicplayer.volume_db
yield(get_tree().create_timer(0.05), "timeout")
func isMusicPlaying():
for child in get_tree().get_root().get_children():
if child.name == music.name:
return child.playing
func crashJessist(script,function,debugInfo):
if crashed:
return
crashed = true
logInfo("GameController","crashJessist","Pausing game")
gamePaused = true
logInfo("GameController","crashJessist","Loading CrashHandler scene")
crashScene.debuggingInformation = [script,function,debugInfo]
get_tree().get_root().add_child(crashScene)
get_tree().set_current_scene(crashScene)
logInfo("GameController","crashJessist","Waiting for all threads to finish execution")
call_deferred("_crashJessist_deferred")
func _crashJessist_deferred():
logInfo("GameController","_crashJessist_deferred","Killing scenes")
for child in get_tree().get_root().get_children():
if child.name == "gameController" or child.name == "sp" or child.name == "gd" or child.name == "scene_manager" or child.name == "Transition" or child.name == music.name or child.name == "CrashHandler":
continue
logInfo("GameController","_crashJessist_deferred","Removing child " + child.name)
get_tree().get_root().remove_child(child)
if currentScene != null:
currentScene.free()
func getFullLog():
logInfo("GameController","getFullLog","Collecting full log file")
var sessionLogTmp = sessionLog
sessionLogTmp.append("LOGSESSIONEND")
var logfile = str(sessionLogTmp)
logfile = logfile.replace("[LOGSESSIONSTART, ","")
logfile = logfile.replace(", LOGSESSIONEND]","")
logfile = logfile.replace(", ","\n")
logInfo("GameController","getFullLog","Collected full log file")
return logfile
func getLog(lines):
logInfo("GameController","getFullLog","Collecting last " + str(lines) + " lines of the log file")
var sessionLogTmp = Array()
sessionLogTmp.append("LOGSESSIONSTART")
sessionLogTmp.append_array(sessionLog.slice(sessionLog.size() - lines, sessionLog.size()))
sessionLogTmp.append("LOGSESSIONEND")
var logfile = str(sessionLogTmp)
logfile = logfile.replace("[LOGSESSIONSTART, ","")
logfile = logfile.replace(", LOGSESSIONEND]","")
logfile = logfile.replace(", ","\n")
logInfo("GameController","getFullLog","Collected " + str(lines))
return logfile
func dialog(diag,entrypoint):
logInfo("GameController","dialog","Dialog request aknowledged")
var res = null
if diag == "Timeleton":
res = preload("res://Dialog/Timeleton.tres")
elif diag == "GameEnd":
res = preload("res://Dialog/GameEnd.tres")
else:
logError("GameController","dialogStart","Can't start dialog, invalid dialog specified")
return
logInfo("GameController","dialog","Displaying dialog")
_showDiag(entrypoint, res)
func _showDiag(title: String, resource: DialogueResource) -> void:
var dialogue = yield(DialogueManager.get_next_dialogue_line(title, resource), "completed")
if dialogue != null:
var balloon = dialogBalloon
balloon.dialogue = dialogue
add_child(balloon)
# Dialogue might have response options so we have to wait and see
# what the player chose. "actioned" is emitted and passes the "next_id"
# once the player has made their choice.
_showDiag(yield(balloon, "actioned"), resource)