Issue 377 (#383)

* feat: Implements speech fixes #377

* docs: Automatic update of API docs

* chore: Updated speech translation.

Co-authored-by: Dennis Ploeger <develop@dieploegers.de>
Co-authored-by: dploeger <dploeger@users.noreply.github.com>
This commit is contained in:
Dennis Ploeger
2021-09-06 08:52:16 +02:00
committed by GitHub
parent 3dc779311c
commit c8958e7454
54 changed files with 279 additions and 85 deletions

View File

@@ -0,0 +1,21 @@
[gd_resource type="AudioBusLayout" format=2]
[resource]
bus/1/name = "SFX"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = "Master"
bus/2/name = "Music"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = "Master"
bus/3/name = "Speech"
bus/3/solo = false
bus/3/mute = false
bus/3/bypass_fx = false
bus/3/volume_db = 0.0
bus/3/send = "Master"

View File

@@ -1,7 +1,7 @@
# `play_snd file [player]`
#
# Plays the sound specificed with the "file" parameter on the sound player
# `player`, without blocking. (player defaults to bg_sound)
# `player`, without blocking. (player defaults to _sound)
#
# @ESC
extends ESCBaseCommand
@@ -13,7 +13,7 @@ func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
[TYPE_STRING, TYPE_STRING],
[null, "bg_sound"]
[null, "_sound"]
)

View File

@@ -72,14 +72,10 @@ func run(command_params: Array) -> int:
)
return ESCExecution.RC_ERROR
var _line = command_params[1]
if ":" in _line:
_line = tr(_line.split(":")[0])
escoria.dialog_player.say(
command_params[0],
dialog_scene_name,
_line
command_params[1]
)
yield(escoria.dialog_player, "dialog_line_finished")
return ESCExecution.RC_OK

View File

@@ -2,7 +2,7 @@
#
# Change the sound playing on `player` to `sound` with optional looping if
# `loop` is true.
# Valid players are "bg_music" and "bg_sound".
# Valid players are "_music" and "_sound".
# Aside from paths to sound or music files, the values *off* and *default*.
# *default* is the default value.
# are also valid for `sound`
@@ -23,7 +23,7 @@ func configure() -> ESCCommandArgumentDescriptor:
# Validate wether the given arguments match the command descriptor
func validate(arguments: Array):
if not arguments[0] in ["bg_music", "bg_sound"]:
if not arguments[0] in ["_music", "_sound", "_speech"]:
escoria.logger.report_errors(
"SetSoundStateCommand.validate: invalid player",
[
@@ -45,6 +45,6 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
escoria.main.get_node(command_params[0])\
escoria.object_manager.get_object(command_params[0]).node\
.set_state(command_params[1], command_params[2])
return ESCExecution.RC_OK

View File

@@ -4,8 +4,9 @@ class_name ESCObjectManager
const RESERVED_OBJECTS = [
"bg_music",
"bg_sound"
"_music",
"_sound",
"_speech"
]

View File

@@ -75,7 +75,7 @@ func get_save_data() -> Dictionary:
save_data["last_deg"] = wrapi(self.node._movable._get_angle() + 1, 0, 360)
save_data["last_dir"] = self.node._movable.last_dir
if (self.global_id == "bg_music" or self.global_id == "bg_sound") \
if (self.global_id == "_music" or self.global_id == "_sound") \
and self.node.get("state"):
save_data["state"] = self.node.get("state")

View File

@@ -162,7 +162,7 @@ func load_game(id: int):
save_game.objects[object_global_id]["last_deg"]])
)
if object_global_id == "bg_music" or object_global_id == "bg_sound":
if object_global_id == "_music" or object_global_id == "_sound":
load_statements.append(ESCCommand.new("set_sound_state %s %s true" \
% [object_global_id,
save_game.objects[object_global_id]["state"]])
@@ -185,7 +185,7 @@ func save_settings():
settings_res.master_volume = escoria.settings.master_volume
settings_res.music_volume = escoria.settings.music_volume
settings_res.sfx_volume = escoria.settings.sfx_volume
settings_res.voice_volume = escoria.settings.voice_volume
settings_res.speech_volume = escoria.settings.speech_volume
settings_res.fullscreen = escoria.settings.fullscreen
settings_res.skip_dialog = escoria.settings.skip_dialog

View File

@@ -6,10 +6,14 @@ class_name ESCSaveSettings
export var escoria_version: String
# Language of displayed text
export var text_lang: String = ProjectSettings.get_setting("escoria/main/text_lang")
export var text_lang: String = ProjectSettings.get_setting(
"escoria/main/text_lang"
)
# Language of voice speech
export var voice_lang: String = ProjectSettings.get_setting("escoria/main/voice_lang")
export var voice_lang: String = ProjectSettings.get_setting(
"escoria/main/voice_lang"
)
# Whether speech is enabled
export var speech_enabled: bool = ProjectSettings.get_setting(
@@ -24,10 +28,12 @@ export var music_volume: float = ProjectSettings.get_setting(
"escoria/sound/music_volume")
# Volume of SFX only
export var sfx_volume: float = ProjectSettings.get_setting("escoria/sound/sfx_volume")
export var sfx_volume: float = ProjectSettings.get_setting(
"escoria/sound/sfx_volume"
)
# Voice volume only
export var voice_volume: float = ProjectSettings.get_setting(
# Speech volume only
export var speech_volume: float = ProjectSettings.get_setting(
"escoria/sound/speech_volume")
# True if game has to be fullscreen

View File

@@ -267,6 +267,10 @@ func _on_settings_loaded(p_settings: ESCSaveSettings) -> void:
AudioServer.set_bus_volume_db(
AudioServer.get_bus_index("Music"),
linear2db(settings.music_volume)
)
AudioServer.set_bus_volume_db(
AudioServer.get_bus_index("Speech"),
linear2db(settings.speech_volume)
)
TranslationServer.set_locale(settings.text_lang)

View File

@@ -17,10 +17,6 @@ var current_scene: Node
# The Escoria context currently in wait state
var wait_level
# Reference to the ESCBackgroundMusic node
onready var bg_music = $bg_music
# Reference to the scene transition node
onready var scene_transition = $layers/curtain/scene_transition

View File

@@ -1,10 +1,11 @@
[gd_scene load_steps=6 format=2]
[gd_scene load_steps=7 format=2]
[ext_resource path="res://addons/escoria-core/game/main.gd" type="Script" id=1]
[ext_resource path="res://addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/bg_music.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/esc_music_player.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/escoria-core/game/scenes/transitions/transition.tscn" type="PackedScene" id=4]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/bg_sound.tscn" type="PackedScene" id=5]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/esc_sound_player.tscn" type="PackedScene" id=5]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/esc_speech_player.tscn" type="PackedScene" id=6]
[node name="main" type="Node"]
script = ExtResource( 1 )
@@ -27,3 +28,5 @@ layer = 20
[node name="bg_music" parent="." instance=ExtResource( 3 )]
[node name="bg_sound" parent="." instance=ExtResource( 5 )]
[node name="speech" parent="." instance=ExtResource( 6 )]

View File

@@ -50,6 +50,31 @@ func _input(event):
if event is InputEventMouseButton and \
event.pressed:
finish_fast()
func _get_voice_file(key: String, start: String = "") -> String:
if start == "":
start = ProjectSettings.get("escoria/sound/speech_folder")
var _dir = Directory.new()
if _dir.open(start) == OK:
_dir.list_dir_begin(true, true)
var file_name = _dir.get_next()
while file_name != "":
if _dir.current_is_dir():
var _voice_file = _get_voice_file(
key,
start.plus_file(file_name)
)
if _voice_file != "":
return _voice_file
else:
if file_name == "%s.%s" % [
key,
ProjectSettings.get("escoria/sound/speech_extension")
]:
return start.plus_file(file_name)
file_name = _dir.get_next()
return ""
# A short one line dialog
@@ -63,7 +88,15 @@ func say(character: String, ui: String, line: String) -> void:
is_speaking = true
_dialog_ui = get_resource(ui).instance()
get_parent().add_child(_dialog_ui)
_dialog_ui.say(character, line)
var _key_line = line.split(":")
if _key_line.size() == 2:
var _speech_resource = _get_voice_file(_key_line[0])
if _speech_resource != "":
(
escoria.object_manager.get_object("_speech").node\
as ESCSpeechPlayer
).set_state(_speech_resource)
_dialog_ui.say(character, _key_line[1])
yield(_dialog_ui, "dialog_line_finished")
is_speaking = false
emit_signal("dialog_line_finished")

View File

@@ -2,7 +2,7 @@
[ext_resource path="res://game/ui/commons/dialogs/dialog_label.tscn" type="PackedScene" id=1]
[ext_resource path="res://game/ui/commons/dialogs/text_dialog_choice.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/dialog_player.gd" type="Script" id=3]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/esc_dialog_player.gd" type="Script" id=3]
[ext_resource path="res://game/ui/commons/dialogs/dialog_box_inset.tscn" type="PackedScene" id=4]
[node name="dialog_player" type="ResourcePreloader"]

View File

@@ -1,10 +1,10 @@
# Background music player
extends Control
class_name ESCBackgroundMusic
class_name ESCMusicPlayer
# Global id of the background music player
export var global_id: String = "bg_music"
export var global_id: String = "_music"
# The state of the music player. "default" or "off" disable music

View File

@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/bg_music.gd" type="Script" id=1]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/esc_music_player.gd" type="Script" id=1]
[node name="bg_music" type="Control"]
anchor_right = 1.0

View File

@@ -1,10 +1,10 @@
# Background sound player
extends Control
class_name ESCBackgroundSound
class_name ESCSoundPlayer
# Global id of the background sound player
export var global_id: String = "bg_sound"
export var global_id: String = "_sound"
# The state of the sound player. "default" or "off" disable sound

View File

@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/bg_sound.gd" type="Script" id=1]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/esc_sound_player.gd" type="Script" id=1]
[node name="bg_sound" type="Control"]
anchor_right = 1.0

View File

@@ -0,0 +1,44 @@
# Speech player
extends Control
class_name ESCSpeechPlayer
# Global id of the background music player
export var global_id: String = "_speech"
# Set the state of this player
#
# #### Parameters
#
# - p_state: New state to use
# - p_force: Override the existing state even if the stream is still playing
func set_state(p_state: String, p_force: bool = false) -> void:
# If speech is disabled, return
if not escoria.settings.speech_enabled:
return
# If state is "off"/"default", turn off speech
if p_state in ["off", "default"]:
$AudioStreamPlayer.stream = null
return
var resource = load(p_state)
$AudioStreamPlayer.stream = resource
if $AudioStreamPlayer.stream:
resource.set_loop(false)
$AudioStreamPlayer.play()
# Register to the object registry
func _ready():
escoria.object_manager.register_object(
ESCObject.new(global_id, self),
true
)
func _on_AudioStreamPlayer_finished() -> void:
set_state("off")

View File

@@ -0,0 +1,17 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/escoria-core/game/scenes/sound/esc_speech_player.gd" type="Script" id=1]
[node name="Control" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
bus = "Speech"
[connection signal="finished" from="AudioStreamPlayer" to="." method="_on_AudioStreamPlayer_finished"]

View File

@@ -23,6 +23,10 @@ func _enter_tree():
# Prepare the settings in the Escoria UI category
func set_escoria_ui_settings():
ProjectSettings.set_setting(
"audio/default_bus_layout",
"res://addons/escoria-core/default_bus_layout.tres"
)
if !ProjectSettings.has_setting("escoria/ui/tooltip_follows_mouse"):
ProjectSettings.set_setting("escoria/ui/tooltip_follows_mouse", true)
@@ -245,6 +249,25 @@ func set_escoria_sound_settings():
"type": TYPE_BOOL
}
ProjectSettings.add_property_info(speech_enabled_property_info)
if !ProjectSettings.has_setting("escoria/sound/speech_folder"):
ProjectSettings.set_setting(
"escoria/sound/speech_folder",
"res://speech"
)
ProjectSettings.add_property_info({
"name": "escoria/sound/speech_folder",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_DIR
})
if !ProjectSettings.has_setting("escoria/sound/speech_extension"):
ProjectSettings.set_setting(
"escoria/sound/speech_extension",
"ogg"
)
ProjectSettings.add_property_info({
"name": "escoria/sound/speech_extension",
"type": TYPE_STRING
})
# Prepare the settings in the Escoria platform category and may need special

View File

@@ -3,7 +3,7 @@
[ext_resource path="res://addons/escoria-ui-9verbs/tooltip/action_target_tooltip.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/escoria-ui-9verbs/inventory/inventory_ui.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/escoria-ui-9verbs/verbs_menu.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/dialog_player.tscn" type="PackedScene" id=4]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/esc_dialog_player.tscn" type="PackedScene" id=4]
[ext_resource path="res://addons/escoria-ui-9verbs/game.gd" type="Script" id=5]
[ext_resource path="res://addons/escoria-core/game/scenes/camera_player/camera.tscn" type="PackedScene" id=6]
[ext_resource path="res://game/ui/commons/room_select.tscn" type="PackedScene" id=7]

View File

@@ -1,7 +1,7 @@
[gd_scene load_steps=9 format=2]
[ext_resource path="res://addons/escoria-ui-simplemouse/inventory/inventory_ui.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/dialog_player.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/esc_dialog_player.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/escoria-core/game/scenes/camera_player/camera.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/escoria-ui-simplemouse/verbs_mouseicons.tscn" type="PackedScene" id=4]
[ext_resource path="res://addons/escoria-ui-simplemouse/game.gd" type="Script" id=5]