316 lines
14 KiB
GDScript
316 lines
14 KiB
GDScript
@icon("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
|