@icon("res://dvn/dvn.png") class_name DVNScene extends Node2D ## The DVNScene Node contains all of the built in functions of DVN, excluding those affecting text. ## Every scene in the DVN engine should extend DVNScene, imagine it as a base scene. ## Completely Invisible Color, if the alpha is increased it becomes [member Color.WHITE] const TRANS_WHITE = Color(1,1,1,0) ## Completely Invisible Color, if the alpha is increased it becomes [member Color.BLACK] const TRANS_BLACK = Color(0,0,0,0) ## Called when [method fade_out_sceen] has finished fading the screen. ## [br]NOTE: Will only be called if [param async] is false!!! signal screen_fade_out ## Called when [method fade_in_sceen] has finished fading the screen. ## [br]NOTE: Will only be called if [param async] is false!!! signal screen_fade_in ## Called when [method fade_out_bgm] has finished fading. ## [br]NOTE: Will only be called if [param async] is false!!! signal bgm_fade_out ## Called when [method fade_in_bgm] has finished fading. ## [br]NOTE: Will only be called if [param async] is false!!! signal bgm_fade_in ## Called when [method fade_bgm] has finished fading. ## [br]NOTE: Will only be called if [param async] is false!!! signal bgm_fade ## Called when [method delay] has counted all the way down. signal delay_ended ## Called when the sound created by [method play_sound] has finished playing. ## [br]NOTE: Will only be called if [param async] is false!!! signal sound_ended ## Default ballon to create with [method create_text_balloon] @export var Balloon: PackedScene = null ## Default ballon to start with [method create_text_balloon] @export var Dialogue: DialogueResource = null ## Set the current dialogue automation type. ## [br]see [enum DialogueAutomationTypes] for more info @export_enum("Manual", "Auto Text", "Auto Voice") var dialogue_automation_type: int ## [param] MANUAL is the default way of handling text. The next line of dialogue is not ## drawn until the user inputs a command. ## [br][param AUTO_TEXT] Automatically skips to the next text box after the [member auto_text_delay] timer is done counting down. ## [br][param AUTO_VOICE] Automatically skips to the next text box when the voice clip is done playing. enum DialogueAutomationTypes{MANUAL,AUTO_TEXT,AUTO_VOICE} ## The wait time until new text is drawn when [member dialogue_automation_type] is set to auto voice. @export var auto_text_delay:float = 1.0 ## Default time value for fading the screen @export var default_screen_fade_time: float = 2.0 ## Default time value for fading the BGM @export var default_bgm_fade_time: float = 2.0 ## Reference to BGM Player @onready var bgm = %BGM ## Reference to built in Animation Player @onready var animation_player = $DVN/AnimationPlayer ## The volume of the BGM set in the editor, used @onready var bgm_initial_volume = bgm.get_volume_db() ## The currently active text balloon, created from [method create_text_balloon] var current_balloon = null #region Text Functions ## Create a text balloon starting from [param title] func create_text_balloon(title:String): current_balloon = Balloon.instantiate() add_child(current_balloon) current_balloon.start(Dialogue,title) ## Wait a certain amount of [param time] until the next dialogue line is executed func delay(time:float = 2.0): await get_tree().create_timer(time).timeout emit_signal("delay_ended") screen_fade_out.connect(on_delay_ended) ## Switch the currently selected [DVNLabel] ## [br]If [param keep_text] is true than the previously selected [DVNLabel] will stay drawn func switch_label(label,keep_text: bool = false): if keep_text == false: current_balloon.dialogue_label.text = "" current_balloon.dialogue_label = label ## Move the selected [param label] to a specified [param position] func move_label(label:PackedScene,position:Vector2): current_balloon.dialogue_label.position = position ## Change the [param color] of the currently selected label func change_text_color(color:Color): current_balloon.dialogue_label.set_modulate(color) ## Set the current dialogue automation type. ## [br]see [enum DialogueAutomationTypes] for more info func set_dialogue_automation_type(type:int): dialogue_automation_type = type ## Set the text speed in seconds per step func set_text_speed(speed:float=0.02): current_balloon.dialogue_label.seconds_per_step = speed ## Called when the dialogue reaches an END block. func dialogue_ended(): pass #endregion #region Voice Functions ## Set the current voice line position. Useful if you have a lot of different branches ## and loops in dialogue. func set_voice_line(index:int): current_balloon.dialogue_label.current_voice_line = index ## Set if speech sounds should play at all. func set_can_speak(truefalse:bool=true): current_balloon.dialogue_label.can_speak = truefalse ## Set the volume of the currently selected [DVNLabel]'s talktone player in db func set_voice_volume(volume:float = 0.0): current_balloon.dialogue_label.talktone_player.set_volume_db(volume) #endregion #region Screen Fade Functions ## Fades in the screen. This is achieved by interpolating the alpha of [DVNScene]'s [ColorRect]. ## [br][br][param color] determines the color to fade in from. ## [br][param time] determines the amount of time for the fade to take. ## [br][param hold_time] determines the time to wait until the screen starts fading. ## [br]if [param async] is true, the fade will be performed alongside other actions, otherwise, other actions won't be performed until the fading is finished. func fade_in_screen(color:Color = Color.BLACK,time:float = default_screen_fade_time,hold_time:float = 0,async:bool = false): %FadeColor.color = color %FadeColor.color.a = 1.0 await get_tree().create_timer(hold_time).timeout var tween = get_tree().create_tween() tween.tween_property(%FadeColor, "color:a", 0.0, time).set_trans(Tween.TRANS_LINEAR) if !async: await get_tree().create_timer(time).timeout emit_signal("screen_fade_in") screen_fade_out.connect(on_screen_fade_in) ## Fades out the screen. This is achieved by interpolating the alpha of [DVNScene]'s [ColorRect]. ## [br][br][param color] determines the color to fade to. ## [br][param time] determines the amount of time for the fade to take. ## [br][param hold_time] determines the extra time to hold the faded color, until the fading is considered "finished". ## [br]if [param async] is true, the fade will be performed alongside other actions, otherwise, other actions won't be performed until the fading is finished. func fade_out_screen(color:Color = Color.BLACK,time:float = default_screen_fade_time,hold_time:float = 0,async:bool = false): %FadeColor.color = color %FadeColor.color.a = 0.0 var tween = get_tree().create_tween() tween.tween_property(%FadeColor, "color:a", 1.0, time).set_trans(Tween.TRANS_LINEAR) if !async: await get_tree().create_timer(time).timeout await get_tree().create_timer(hold_time).timeout emit_signal("screen_fade_in") screen_fade_out.connect(on_screen_fade_in) #endregion #region BGM Fade Functions ## Fades out BGM. This is achieved by interpolating the volume of [DVNScene]'s BGM [AudioStreamPlayer]. ## [br][br][param time] determines the amount of time for the fade to take. ## [br]if [param async] is true, the fade will be performed alongside other actions, otherwise, other actions won't be performed until the fading is finished. func fade_out_bgm(time:float = default_bgm_fade_time,async:bool = false): var tween = get_tree().create_tween() tween.tween_property(bgm, "volume_db", -80, time) if !async: await get_tree().create_timer(time).timeout emit_signal("bgm_fade_out") bgm_fade_in.connect(on_bgm_fade_in) ## Fades in BGM. This is achieved by interpolating the volume of [DVNScene]'s BGM [AudioStreamPlayer]. ## [br][br][param time] determines the amount of time for the fade to take. ## [br]if [param async] is true, the fade will be performed alongside other actions, otherwise, other actions won't be performed until the fading is finished. func fade_in_bgm(time:float = default_bgm_fade_time,async:bool = false): bgm.set_volume_db(-80) bgm.play() var tween = get_tree().create_tween() tween.tween_property(bgm, "volume_db", bgm_initial_volume, time) if !async: await get_tree().create_timer(time).timeout emit_signal("bgm_fade_in") bgm_fade_in.connect(on_bgm_fade_in) ## Fades the BGM from its current value to [param end_volume]. This is achieved by interpolating the volume of [DVNScene]'s BGM [AudioStreamPlayer]. ## [br][br][param time] determines the amount of time for the fade to take. ## [br]if [param async] is true, the fade will be performed alongside other actions, otherwise, other actions won't be performed until the fading is finished. func fade_bgm(end_volume:float = 0.0,time:float = default_bgm_fade_time,async:bool = false): var tween = get_tree().create_tween() tween.tween_property(bgm, "volume_db", end_volume, time) if !async: await get_tree().create_timer(time).timeout emit_signal("bgm_fade") bgm_fade.connect(on_bgm_fade) ## Change BGM to [param stream] func change_bgm(stream:AudioStream): bgm.stream = stream ## Pause/Resume BGM func pause_bgm(pause:bool = true): bgm.set_stream_paused(pause) ## STOP BGM. func stop_bgm(): bgm.stop() ## Play the BGM. ##[br]Different from setting [method pause_bgm] to false as this will start the stream from the beginning func play_bgm(): bgm.play() ## Set the BGM Volume in db. ## [br]Does not fade, volume change is abrupt. func set_bgm_volume(volume:float = 0.0): bgm.set_volume_db(volume) ## Skip to a spot in the BGM. see [method AudioStreamPlayer.seek] func seek_bgm(to_position:float = 0.0): bgm.seek(to_position) #endregion #region SFX Functions ## Play a sound effect. Achieved by creating an [AudioStreamPlayer] and freeing it when it's done playing. ## [br][br]The specific [param sound] can be changed, along with its [param volume] and [param pitch]. ## [br]if [param async] is true, the fade will be performed alongside other actions, otherwise, other actions won't be performed until the fading is finished. ## [br][br]The Sound effect will play from the SFX audio bus. func play_sound(sound:AudioStream,volume:float,pitch:float,async:bool = true): var sfx = load("res://dvn/sound_player/sound.tscn").instantiate() sfx.stream = sound sfx.set_volume_db(volume) sfx.pitch_scale = pitch add_child(sfx) sfx.play() if !async: await get_tree().create_timer(sound.get_length()).timeout emit_signal("sound_ended") sound_ended.connect(on_sound_ended) #endregion #region Animation Functions ## Sets an [AnimationPlayer]'s [param speed]. ## [br] by default this affects the [DVNScene]'s built in [AnimationPlayer] ## [br][br] see [method AnimationPlayer.set_speed_scale] func set_animation_speed(speed:float = 1.0,player:Node = animation_player): animation_player.set_speed_scale(1.0) ## Play an anim on your [AnimationPlayer]. ## [br] by default this affects the [DVNScene]'s built in [AnimationPlayer] ## [br][br] see [method AnimationPlayer.play] func play_animtion(animation:String,player = animation_player): player.play(animation) #endregion #region Scene Functions ## Go to the next [param scene] from a node's path. [param example: "res://dvn/dvn.tscn"] ## [br]can be used to change the current scene to anything, but you generally want ## to use it to move to the next specific "scene" or "level" func change_scene(scene:String): get_tree().change_scene_to_file(scene) ## Ends the scene with a screen and BGM fade out. When the screen and BGM are done fading, the scene switches to [param next_scene] ## [br][param screen_fade_time] and [param bgm_fade_time] can be adjusted, though by default they are set to [member default_screen_fade_time] and [member default_bgm_fade_time] ## [br]You can set the default fade times in [DVNScene]'s exports. ## [br]Ideally this is the kind of function you can use to smoothly end a scene in one line. func end_scene(next_scene:String,screen_fade_time:float = default_screen_fade_time,bgm_fade_time:float = default_bgm_fade_time): #Determine whether to end on bgm fade or screen fade var wait_time = 0.0 if bgm_fade_time > screen_fade_time: wait_time = bgm_fade_time else: wait_time = screen_fade_time #fade bgm and screen fade_out_bgm(bgm_fade_time) fade_out_screen(%FadeColor.color,screen_fade_time) await get_tree().create_timer(wait_time).timeout #wait for bgm and screen to finish fading change_scene(next_scene) #endregion #region Signals ## Called when [method delay] has counted all the way down. func on_delay_ended(): pass ## Called when [method fade_out_sceen] has finished fading the screen and [param hold_time] has counted all the way down. ## [br]NOTE: Will only be called if [param async] is false!!! func on_screen_fade_out(): pass ## Called when [method fade_in_sceen] has finished fading the screen. ## [br]NOTE: Will only be called if [param async] is false!!! func on_screen_fade_in(): pass ## Called when the sound created by [method play_sound] has finished playing. ## [br]NOTE: Will only be called if [param async] is false!!! func on_sound_ended(): pass ## Called when [method fade_out_bgm] has finished fading. ## [br]NOTE: Will only be called if [param async] is false!!! func on_bgm_fade_out(): pass ## Called when [method fade_in_bgm] has finished fading. ## [br]NOTE: Will only be called if [param async] is false!!! func on_bgm_fade_in(): pass ## Called when [method fade_bgm] has finished fading. ## [br]NOTE: Will only be called if [param async] is false!!! func on_bgm_fade(): pass ## Called when... when... when something happens. make good use of that [param anim_name]!!! func _on_animation_player_animation_finished(anim_name: StringName) -> void: pass # Replace with function body. #endregion