Skip to content

Commit 6e03858

Browse files
New Audio Event to replace music and sound event (#2488)
Implements a new audio event and removes the old music and sound events. Audio files can now be played on unlimited different "channels". Channels can be predefined (including default settings for volume, audio bus, loop, fade) and then easily used or created on the spot for single use. If no channel is used, then the file is played like a sound event before (so called One-Shot SFX now). By default a music channel is defined and the One-Shot-SFX channel. The new syntax is audio channel-name "file://path.mp3" [fade="2.0"] Also adds audio-syncing functionality and Validation for DynamicOptionsField. --------- Co-authored-by: Jowan-Spooner <[email protected]>
1 parent 7a24c14 commit 6e03858

29 files changed

+1190
-434
lines changed

addons/dialogic/Core/DialogicResourceUtil.gd

+41
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ class_name DialogicResourceUtil
33

44
static var label_cache := {}
55
static var event_cache: Array[DialogicEvent] = []
6+
static var channel_cache := {}
67

78
static var special_resources := {}
89

@@ -11,6 +12,7 @@ static func update() -> void:
1112
update_directory('.dch')
1213
update_directory('.dtl')
1314
update_label_cache()
15+
update_audio_channel_cache()
1416

1517

1618
#region RESOURCE DIRECTORIES
@@ -140,6 +142,45 @@ static func update_label_cache() -> void:
140142

141143
#endregion
142144

145+
#region AUDIO CHANNEL CACHE
146+
################################################################################
147+
# The audio channel cache is only for the editor so we don't have to scan all timelines
148+
# whenever we want to suggest channels. This has no use in game and is not always perfect.
149+
150+
static func get_audio_channel_cache() -> Dictionary:
151+
if not channel_cache.is_empty():
152+
return channel_cache
153+
154+
channel_cache = DialogicUtil.get_editor_setting('channel_ref', {})
155+
return channel_cache
156+
157+
158+
static func get_channel_list() -> Array:
159+
if channel_cache.is_empty():
160+
return []
161+
162+
var cached_names := []
163+
for timeline in channel_cache:
164+
for name in channel_cache[timeline]:
165+
if not cached_names.has(name):
166+
cached_names.append(name)
167+
return cached_names
168+
169+
170+
static func set_audio_channel_cache(cache:Dictionary) -> void:
171+
channel_cache = cache
172+
173+
174+
static func update_audio_channel_cache() -> void:
175+
var cache := get_audio_channel_cache()
176+
var timelines := get_timeline_directory().values()
177+
for timeline in cache:
178+
if !timeline in timelines:
179+
cache.erase(timeline)
180+
set_audio_channel_cache(cache)
181+
182+
#endregion
183+
143184
#region EVENT CACHE
144185
################################################################################
145186

addons/dialogic/Core/DialogicUtil.gd

+78
Original file line numberDiff line numberDiff line change
@@ -736,3 +736,81 @@ static func get_autoload_property_suggestions(filter:String, autoload_name:Strin
736736
suggestions[property.name] = {'value': property.name, 'tooltip':property.name, 'editor_icon': ["MemberProperty", "EditorIcons"]}
737737

738738
return suggestions
739+
740+
741+
static func get_audio_bus_suggestions(filter:= "") -> Dictionary:
742+
var bus_name_list := {}
743+
for i in range(AudioServer.bus_count):
744+
if i == 0:
745+
bus_name_list[AudioServer.get_bus_name(i)] = {'value':''}
746+
else:
747+
bus_name_list[AudioServer.get_bus_name(i)] = {'value':AudioServer.get_bus_name(i)}
748+
return bus_name_list
749+
750+
751+
static func get_audio_channel_suggestions(search_text:String) -> Dictionary:
752+
753+
754+
var suggestions := {}
755+
var channel_defaults := DialogicUtil.get_audio_channel_defaults()
756+
var cached_names := DialogicResourceUtil.get_channel_list()
757+
758+
for i in channel_defaults.keys():
759+
if not cached_names.has(i):
760+
cached_names.append(i)
761+
762+
cached_names.sort()
763+
764+
for i in cached_names:
765+
if i.is_empty():
766+
continue
767+
768+
suggestions[i] = {'value': i}
769+
770+
if i in channel_defaults.keys():
771+
suggestions[i]["editor_icon"] = ["ProjectList", "EditorIcons"]
772+
suggestions[i]["tooltip"] = "A default channel defined in the settings."
773+
774+
else:
775+
suggestions[i]["editor_icon"] = ["AudioStreamPlayer", "EditorIcons"]
776+
suggestions[i]["tooltip"] = "A temporary channel without defaults."
777+
778+
return suggestions
779+
780+
781+
static func get_audio_channel_defaults() -> Dictionary:
782+
return ProjectSettings.get_setting('dialogic/audio/channel_defaults', {
783+
"": {
784+
'volume': 0.0,
785+
'audio_bus': '',
786+
'fade_length': 0.0,
787+
'loop': false,
788+
},
789+
"music": {
790+
'volume': 0.0,
791+
'audio_bus': '',
792+
'fade_length': 0.0,
793+
'loop': true,
794+
}})
795+
796+
797+
static func validate_audio_channel_name(text: String) -> Dictionary:
798+
var result := {}
799+
var channel_name_regex := RegEx.create_from_string(r'(?<dash_only>^-$)|(?<invalid>[^\w-]{1})')
800+
var matches := channel_name_regex.search_all(text)
801+
var invalid_chars := []
802+
803+
for regex_match in matches:
804+
if regex_match.get_string('dash_only'):
805+
result['error_tooltip'] = "Channel name cannot be '-'."
806+
result['valid_text'] = ''
807+
else:
808+
var invalid_char = regex_match.get_string('invalid')
809+
if not invalid_char in invalid_chars:
810+
invalid_chars.append(invalid_char)
811+
812+
if invalid_chars:
813+
result['valid_text'] = channel_name_regex.sub(text, '', true)
814+
result['error_tooltip'] = "Channel names cannot contain the following characters: " + "".join(invalid_chars)
815+
816+
return result

addons/dialogic/Editor/CharacterEditor/char_edit_section_portraits.gd

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func _ready() -> void:
1919

2020
# Setting up Default Portrait Picker
2121
%DefaultPortraitPicker.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/portrait.svg")
22-
%DefaultPortraitPicker.get_suggestions_func = suggest_portraits
22+
%DefaultPortraitPicker.suggestions_func = suggest_portraits
2323

2424

2525
## Make sure preview get's updated when portrait settings change
@@ -74,4 +74,3 @@ func suggest_portraits(search:String) -> Dictionary:
7474
for portrait in character_editor.get_updated_portrait_dict().keys():
7575
suggestions[portrait] = {'value':portrait}
7676
return suggestions
77-

addons/dialogic/Editor/Common/ReferenceManager_AddReplacementPanel.gd

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var item: TreeItem = null
1111
func _ready() -> void:
1212
hide()
1313
%Character.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/character.svg")
14-
%Character.get_suggestions_func = get_character_suggestions
14+
%Character.suggestions_func = get_character_suggestions
1515

1616
%WholeWords.icon = get_theme_icon("FontItem", "EditorIcons")
1717
%MatchCase.icon = get_theme_icon("MatchCase", "EditorIcons")

addons/dialogic/Editor/Common/hint_tooltip_icon.tscn

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/hint_tooltip_icon.gd" id="1_x8t45"]
44

5-
[sub_resource type="Image" id="Image_eiyxd"]
5+
[sub_resource type="Image" id="Image_23kww"]
66
data = {
77
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
88
"format": "RGBA8",
@@ -11,11 +11,11 @@ data = {
1111
"width": 16
1212
}
1313

14-
[sub_resource type="ImageTexture" id="ImageTexture_lseut"]
15-
image = SubResource("Image_eiyxd")
14+
[sub_resource type="ImageTexture" id="ImageTexture_ydy7j"]
15+
image = SubResource("Image_23kww")
1616

1717
[node name="HintTooltip" type="TextureRect"]
1818
modulate = Color(0, 0, 0, 1)
19-
texture = SubResource("ImageTexture_lseut")
19+
texture = SubResource("ImageTexture_ydy7j")
2020
stretch_mode = 3
2121
script = ExtResource("1_x8t45")

addons/dialogic/Editor/Events/Fields/field_audio_preview.tscn

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[gd_scene load_steps=2 format=3 uid="uid://dotvrsumm5y5c"]
22

3-
[ext_resource type="Script" path="res://addons/dialogic/Editor/Events/Fields/field_audio_preview.gd" id="1_7wm54"]
3+
[ext_resource type="Script" uid="uid://6j1wkesnenoa" path="res://addons/dialogic/Editor/Events/Fields/field_audio_preview.gd" id="1_7wm54"]
44

55
[node name="Field_Audio_Preview" type="Button"]
66
offset_right = 8.0

addons/dialogic/Editor/Events/Fields/field_condition.gd

+1-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func _ready() -> void:
5656

5757

5858
for i in [%Value1Variable, %Value2Variable]:
59-
i.get_suggestions_func = get_variable_suggestions
59+
i.suggestions_func = get_variable_suggestions
6060
i.value_changed.connect(something_changed)
6161

6262
%Value1Number.value_changed.connect(something_changed)
@@ -264,4 +264,3 @@ func _on_value_1_variable_value_changed(property_name: Variant, value: Variant)
264264
%Value2Type.index_pressed(1)
265265

266266
something_changed()
267-

addons/dialogic/Editor/Events/Fields/field_number.gd

+10-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ extends DialogicVisualEditorField
44

55
## Event block field for integers and floats. Improved version of the native spinbox.
66

7+
@export_enum("Float", "Int", "Decible") var mode := 0 :
8+
set(new_mode):
9+
mode = new_mode
10+
match mode:
11+
0: use_float_mode() #FLOAT
12+
1: use_int_mode() #INT
13+
2: use_decibel_mode() #DECIBLE
714
@export var allow_string: bool = false
815
@export var step: float = 0.1
916
@export var enforce_step: bool = true
@@ -27,13 +34,6 @@ func _ready() -> void:
2734

2835

2936
func _load_display_info(info: Dictionary) -> void:
30-
match info.get('mode', 0):
31-
0: #FLOAT
32-
use_float_mode(info.get('step', 0.1))
33-
1: #INT
34-
use_int_mode(info.get('step', 1))
35-
2: #DECIBLE:
36-
use_decibel_mode(info.get('step', step))
3737

3838
for option in info.keys():
3939
match option:
@@ -46,6 +46,7 @@ func _load_display_info(info: Dictionary) -> void:
4646
step = info[option]
4747
'hide_step_button': %Spin.hide()
4848

49+
mode = info.get('mode', mode)
4950

5051
func _set_value(new_value: Variant) -> void:
5152
_on_value_text_submitted(str(new_value), true)
@@ -61,13 +62,13 @@ func get_value() -> float:
6162

6263

6364
func use_float_mode(value_step: float = 0.1) -> void:
64-
step = value_step
65+
#step = value_step
6566
update_suffix("")
6667
enforce_step = false
6768

6869

6970
func use_int_mode(value_step: float = 1) -> void:
70-
step = value_step
71+
#step = value_step
7172
update_suffix("")
7273
enforce_step = true
7374

@@ -196,4 +197,3 @@ func _on_value_focus_entered() -> void:
196197
%Value.select_all.call_deferred()
197198

198199
#endregion
199-

addons/dialogic/Editor/Events/Fields/field_number.tscn

+12-11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ grow_horizontal = 2
4040
grow_vertical = 2
4141
theme_override_constants/separation = 0
4242
script = ExtResource("1_0jdnn")
43+
mode = null
4344

4445
[node name="Value_Panel" type="PanelContainer" parent="."]
4546
layout_mode = 2
@@ -77,9 +78,9 @@ layout_mode = 2
7778
size_flags_horizontal = 3
7879
focus_mode = 1
7980
theme_override_constants/minimum_character_width = 0
80-
theme_override_styles/normal = SubResource("StyleBoxEmpty_8yqsu")
8181
theme_override_styles/focus = SubResource("StyleBoxEmpty_8yqsu")
8282
theme_override_styles/read_only = SubResource("StyleBoxEmpty_8yqsu")
83+
theme_override_styles/normal = SubResource("StyleBoxEmpty_8yqsu")
8384
text = "0"
8485
alignment = 1
8586
expand_to_text_length = true
@@ -113,37 +114,37 @@ theme_override_constants/separation = 0
113114
alignment = 1
114115

115116
[node name="Increment" type="Button" parent="Value_Panel/Layout/Spin"]
117+
auto_translate_mode = 2
116118
layout_mode = 2
117119
size_flags_vertical = 3
118-
auto_translate = false
119120
focus_neighbor_left = NodePath("../../Value")
120121
focus_neighbor_top = NodePath(".")
121122
focus_neighbor_bottom = NodePath("../Decrement")
122-
theme_override_colors/icon_hover_color = Color(0.412738, 0.550094, 0.760917, 1)
123123
theme_override_colors/icon_focus_color = Color(0.412738, 0.550094, 0.760917, 1)
124-
theme_override_styles/normal = SubResource("StyleBoxFlat_increment")
124+
theme_override_colors/icon_hover_color = Color(0.412738, 0.550094, 0.760917, 1)
125+
theme_override_styles/focus = SubResource("StyleBoxFlat_increment")
126+
theme_override_styles/disabled = SubResource("StyleBoxFlat_increment")
125127
theme_override_styles/hover = SubResource("StyleBoxFlat_increment")
126128
theme_override_styles/pressed = SubResource("StyleBoxFlat_increment")
127-
theme_override_styles/disabled = SubResource("StyleBoxFlat_increment")
128-
theme_override_styles/focus = SubResource("StyleBoxFlat_increment")
129+
theme_override_styles/normal = SubResource("StyleBoxFlat_increment")
129130
icon = ExtResource("3_v5cne")
130131
flat = true
131132
vertical_icon_alignment = 2
132133

133134
[node name="Decrement" type="Button" parent="Value_Panel/Layout/Spin"]
135+
auto_translate_mode = 2
134136
layout_mode = 2
135137
size_flags_vertical = 3
136-
auto_translate = false
137138
focus_neighbor_left = NodePath("../../Value")
138139
focus_neighbor_top = NodePath("../Increment")
139140
focus_neighbor_bottom = NodePath(".")
140-
theme_override_colors/icon_hover_color = Color(0.412738, 0.550094, 0.760917, 1)
141141
theme_override_colors/icon_focus_color = Color(0.412738, 0.550094, 0.760917, 1)
142-
theme_override_styles/normal = SubResource("StyleBoxFlat_decrement")
142+
theme_override_colors/icon_hover_color = Color(0.412738, 0.550094, 0.760917, 1)
143+
theme_override_styles/focus = SubResource("StyleBoxFlat_decrement")
144+
theme_override_styles/disabled = SubResource("StyleBoxFlat_decrement")
143145
theme_override_styles/hover = SubResource("StyleBoxFlat_decrement")
144146
theme_override_styles/pressed = SubResource("StyleBoxFlat_decrement")
145-
theme_override_styles/disabled = SubResource("StyleBoxFlat_decrement")
146-
theme_override_styles/focus = SubResource("StyleBoxFlat_decrement")
147+
theme_override_styles/normal = SubResource("StyleBoxFlat_decrement")
147148
icon = ExtResource("4_ph52o")
148149
flat = true
149150
vertical_icon_alignment = 2

0 commit comments

Comments
 (0)