@@ -20,6 +20,7 @@ static func get_dialogic_plugin() -> Node:
2020
2121#endregion
2222
23+
2324## Returns the autoload when in-game.
2425static func autoload () -> DialogicGameHandler :
2526 if Engine .is_editor_hint ():
@@ -28,9 +29,10 @@ static func autoload() -> DialogicGameHandler:
2829 return null
2930 return Engine .get_main_loop ().root .get_node ("Dialogic" )
3031
32+
3133#region FILE SYSTEM
3234## ##############################################################################
33- static func listdir (path : String , files_only : bool = true , throw_error :bool = true , full_file_path :bool = false , include_imports := false ) -> Array :
35+ static func listdir (path : String , files_only := true , throw_error := true , full_file_path := false , include_imports := false ) -> Array :
3436 var files : Array = []
3537 if path .is_empty (): path = "res://"
3638 if DirAccess .dir_exists_absolute (path ):
@@ -55,30 +57,52 @@ static func listdir(path: String, files_only: bool = true, throw_error:bool = tr
5557 return files
5658
5759
58-
5960static func get_module_path (name :String , builtin := true ) -> String :
6061 if builtin :
6162 return "res://addons/dialogic/Modules" .path_join (name )
6263 else :
6364 return ProjectSettings .get_setting ('dialogic/extensions_folder' , 'res://addons/dialogic_additions' ).path_join (name )
6465
6566
67+ ## This is a private and editor-only function.
68+ ##
69+ ## Populates the [class DialogicGameHandler] with new custom subsystems by
70+ ## directly manipulating the file's content and then importing the file.
71+ static func _update_autoload_subsystem_access () -> void :
72+ if not Engine .is_editor_hint ():
73+ printerr ("[Dialogic] This function is only available in the editor." )
74+ return
75+
76+ var script : Script = load ("res://addons/dialogic/Core/DialogicGameHandler.gd" )
77+ var new_subsystem_access_list := "#region SUBSYSTEMS\n "
78+
79+ for indexer : DialogicIndexer in get_indexers (true , true ):
80+
81+ for subsystem : Dictionary in indexer ._get_subsystems ().duplicate (true ):
82+ new_subsystem_access_list += '\n var {name} := preload("{script} ").new():\n\t get: return get_subsystem("{name} ")\n ' .format (subsystem )
83+
84+ new_subsystem_access_list += "\n #endregion"
85+ script .source_code = RegEx .create_from_string ("#region SUBSYSTEMS\\ n#*\\ n((?!#endregion)(.*\\ n))*#endregion" ).sub (script .source_code , new_subsystem_access_list )
86+ ResourceSaver .save (script )
87+ Engine .get_singleton ("EditorInterface" ).get_resource_filesystem ().reimport_files (["res://addons/dialogic/Core/DialogicGameHandler.gd" ])
88+
89+
6690static func get_indexers (include_custom := true , force_reload := false ) -> Array [DialogicIndexer ]:
6791 if Engine .get_main_loop ().has_meta ('dialogic_indexers' ) and ! force_reload :
6892 return Engine .get_main_loop ().get_meta ('dialogic_indexers' )
6993
70- var indexers : Array [DialogicIndexer ] = []
94+ var indexers : Array [DialogicIndexer ] = []
7195
7296 for file in listdir (DialogicUtil .get_module_path ('' ), false ):
73- var possible_script :String = DialogicUtil .get_module_path (file ).path_join ("index.gd" )
74- if FileAccess . file_exists (possible_script ):
97+ var possible_script : String = DialogicUtil .get_module_path (file ).path_join ("index.gd" )
98+ if ResourceLoader . exists (possible_script ):
7599 indexers .append (load (possible_script ).new ())
76100
77101 if include_custom :
78102 var extensions_folder : String = ProjectSettings .get_setting ('dialogic/extensions_folder' , "res://addons/dialogic_additions/" )
79103 for file in listdir (extensions_folder , false , false ):
80104 var possible_script : String = extensions_folder .path_join (file + "/index.gd" )
81- if FileAccess . file_exists (possible_script ):
105+ if ResourceLoader . exists (possible_script ):
82106 indexers .append (load (possible_script ).new ())
83107
84108 Engine .get_main_loop ().set_meta ('dialogic_indexers' , indexers )
@@ -182,19 +206,73 @@ static func get_next_translation_id() -> String:
182206#region VARIABLES
183207## ##############################################################################
184208
209+ enum VarTypes {ANY , STRING , FLOAT , INT , BOOL }
210+
211+
212+ static func get_default_variables () -> Dictionary :
213+ return ProjectSettings .get_setting ('dialogic/variables' , {})
214+
215+
185216# helper that converts a nested variable dictionary into an array with paths
186- static func list_variables (dict :Dictionary , path := "" ) -> Array :
217+ static func list_variables (dict :Dictionary , path := "" , type : = VarTypes . ANY ) -> Array :
187218 var array := []
188219 for key in dict .keys ():
189220 if typeof (dict [key ]) == TYPE_DICTIONARY :
190- array .append_array (list_variables (dict [key ], path + key + "." ))
221+ array .append_array (list_variables (dict [key ], path + key + "." , type ))
191222 else :
192- array .append (path + key )
223+ if type == VarTypes .ANY or get_variable_value_type (dict [key ]) == type :
224+ array .append (path + key )
193225 return array
194226
227+
228+ static func get_variable_value_type (value :Variant ) -> int :
229+ match typeof (value ):
230+ TYPE_STRING :
231+ return VarTypes .STRING
232+ TYPE_FLOAT :
233+ return VarTypes .FLOAT
234+ TYPE_INT :
235+ return VarTypes .INT
236+ TYPE_BOOL :
237+ return VarTypes .BOOL
238+ return VarTypes .ANY
239+
240+
241+ static func get_variable_type (path :String , dict :Dictionary = {}) -> VarTypes :
242+ if dict .is_empty ():
243+ dict = get_default_variables ()
244+ return get_variable_value_type (_get_value_in_dictionary (path , dict ))
245+
246+
247+ ## This will set a value in a dictionary (or a sub-dictionary based on the path)
248+ ## e.g. it could set "Something.Something.Something" in {'Something':{'Something':{'Someting':"value"}}}
249+ static func _set_value_in_dictionary (path :String , dictionary :Dictionary , value ):
250+ if '.' in path :
251+ var from := path .split ('.' )[0 ]
252+ if from in dictionary .keys ():
253+ dictionary [from ] = _set_value_in_dictionary (path .trim_prefix (from + "." ), dictionary [from ], value )
254+ else :
255+ if path in dictionary .keys ():
256+ dictionary [path ] = value
257+ return dictionary
258+
259+
260+ ## This will get a value in a dictionary (or a sub-dictionary based on the path)
261+ ## e.g. it could get "Something.Something.Something" in {'Something':{'Something':{'Someting':"value"}}}
262+ static func _get_value_in_dictionary (path :String , dictionary :Dictionary , default = null ) -> Variant :
263+ if '.' in path :
264+ var from := path .split ('.' )[0 ]
265+ if from in dictionary .keys ():
266+ return _get_value_in_dictionary (path .trim_prefix (from + "." ), dictionary [from ], default )
267+ else :
268+ if path in dictionary .keys ():
269+ return dictionary [path ]
270+ return default
271+
195272#endregion
196273
197274
275+
198276#region STYLES
199277## ##############################################################################
200278
@@ -207,7 +285,7 @@ static func get_fallback_style() -> DialogicStyle:
207285
208286
209287static func get_default_style () -> DialogicStyle :
210- var default : = ProjectSettings .get_setting ('dialogic/layout/default_style' , '' )
288+ var default : String = ProjectSettings .get_setting ('dialogic/layout/default_style' , '' )
211289 if ! ResourceLoader .exists (default ):
212290 return get_fallback_style ()
213291 return load (default )
@@ -217,7 +295,7 @@ static func get_style_by_name(name:String) -> DialogicStyle:
217295 if name .is_empty ():
218296 return get_default_style ()
219297
220- var styles : = ProjectSettings .get_setting ('dialogic/layout/style_list' , [])
298+ var styles : Array = ProjectSettings .get_setting ('dialogic/layout/style_list' , [])
221299 for style in styles :
222300 if not ResourceLoader .exists (style ):
223301 continue
@@ -275,7 +353,7 @@ static func get_scene_export_defaults(node:Node) -> Dictionary:
275353## ##############################################################################
276354
277355static func setup_script_property_edit_node (property_info : Dictionary , value :Variant , property_changed :Callable ) -> Control :
278- var input : Control = null
356+ var input : Control = null
279357 match property_info ['type' ]:
280358 TYPE_BOOL :
281359 input = CheckBox .new ()
@@ -287,7 +365,7 @@ static func setup_script_property_edit_node(property_info: Dictionary, value:Var
287365 if value != null :
288366 input .color = value
289367 input .color_changed .connect (DialogicUtil ._on_export_color_submitted .bind (property_info .name , property_changed ))
290- input .custom_minimum_size .x = DialogicUtil . get_editor_scale ()* 50
368+ input .custom_minimum_size .x = get_editor_scale ()* 50
291369 TYPE_INT :
292370 if property_info ['hint' ] & PROPERTY_HINT_ENUM :
293371 input = OptionButton .new ()
@@ -321,14 +399,15 @@ static func setup_script_property_edit_node(property_info: Dictionary, value:Var
321399 input .value_changed .connect (DialogicUtil ._on_export_number_submitted .bind (property_info .name , property_changed ))
322400 if value != null :
323401 input .value = value
324- TYPE_VECTOR2 :
325- input = load ( "res://addons/dialogic/Editor/Events/Fields/Vector2.tscn" ). instantiate ()
326- input . set_value ( value )
402+ TYPE_VECTOR2 , TYPE_VECTOR3 , TYPE_VECTOR4 :
403+ var vectorSize : String = type_string ( typeof ( value ))[ - 1 ]
404+ input = load ( "res://addons/dialogic/Editor/Events/Fields/field_vector" + vectorSize + ".tscn" ). instantiate ( )
327405 input .property_name = property_info ['name' ]
406+ input .set_value (value )
328407 input .value_changed .connect (DialogicUtil ._on_export_vector_submitted .bind (property_changed ))
329408 TYPE_STRING :
330409 if property_info ['hint' ] & PROPERTY_HINT_FILE or property_info ['hint' ] & PROPERTY_HINT_DIR :
331- input = load ("res://addons/dialogic/Editor/Events/Fields/FilePicker .tscn" ).instantiate ()
410+ input = load ("res://addons/dialogic/Editor/Events/Fields/field_file .tscn" ).instantiate ()
332411 input .file_filter = property_info ['hint_string' ]
333412 input .file_mode = FileDialog .FILE_MODE_OPEN_FILE
334413 if property_info ['hint' ] == PROPERTY_HINT_DIR :
@@ -341,7 +420,7 @@ static func setup_script_property_edit_node(property_info: Dictionary, value:Var
341420 input .value_changed .connect (DialogicUtil ._on_export_file_submitted .bind (property_changed ))
342421 elif property_info ['hint' ] & PROPERTY_HINT_ENUM :
343422 input = OptionButton .new ()
344- var options : PackedStringArray = []
423+ var options : PackedStringArray = []
345424 for x in property_info ['hint_string' ].split (',' ):
346425 options .append (x .split (':' )[0 ].strip_edges ())
347426 input .add_item (options [- 1 ])
@@ -360,9 +439,10 @@ static func setup_script_property_edit_node(property_info: Dictionary, value:Var
360439 input = LineEdit .new ()
361440 if value != null :
362441 input .text = value
363- input .text_submitted .connect (DialogicUtil . _on_export_input_text_submitted .bind (property_info .name , property_changed ))
442+ input .text_submitted .connect (_on_export_input_text_submitted .bind (property_info .name , property_changed ))
364443 return input
365444
445+
366446static func _on_export_input_text_submitted (text :String , property_name :String , callable : Callable ) -> void :
367447 callable .call (property_name , var_to_str (text ))
368448
@@ -384,7 +464,7 @@ static func _on_export_file_submitted(property_name:String, value:String, callab
384464static func _on_export_string_enum_submitted (value :int , property_name :String , list :PackedStringArray , callable : Callable ):
385465 callable .call (property_name , var_to_str (list [value ]))
386466
387- static func _on_export_vector_submitted (property_name :String , value :Vector2 , callable : Callable ) -> void :
467+ static func _on_export_vector_submitted (property_name :String , value :Variant , callable : Callable ) -> void :
388468 callable .call (property_name , var_to_str (value ))
389469
390470#endregion
0 commit comments