1 extends DialogicSubsystem
3 ## Subsystem that handles glossaries.
5 ## List of glossary resources that are used.
7 ## If false, no parsing will be done.
10 ## Any key in this dictionary will overwrite the color for any item with that name.
11 var color_overrides := {}
13 const SETTING_DEFAULT_COLOR := 'dialogic/glossary/default_color'
17 ####################################################################################################
19 func clear_game_state(_clear_flag := DialogicGameHandler.ClearFlags.FULL_CLEAR) -> void:
22 for path: String in ProjectSettings.get_setting('dialogic/glossary/glossary_files', []):
29 ####################################################################################################
31 func parse_glossary(text: String) -> String:
35 var def_case_sensitive: bool = ProjectSettings.get_setting('dialogic/glossary/default_case_sensitive', true)
36 var def_color: Color = ProjectSettings.get_setting(SETTING_DEFAULT_COLOR, Color.POWDER_BLUE)
37 var regex := RegEx.new()
39 for glossary: DialogicGlossary in glossaries:
44 for entry_value: Variant in glossary.entries.values():
46 if not entry_value is Dictionary:
49 var entry: Dictionary = entry_value
50 var entry_key: String = entry.get(DialogicGlossary.NAME_PROPERTY, "")
52 # Older versions of the glossary resource do not have a property
53 # for their name, we must skip these.
54 # They can be updated by opening the resource in the glossary
56 if entry_key.is_empty():
59 if not entry.get('enabled', true):
62 var regex_options := glossary.get_set_regex_option(entry_key)
64 if regex_options.is_empty():
67 var pattern: String = '(?<=\\W|^)(?<!\\\\)(?<word>' + regex_options + ')(?!])(?=\\W|$)'
69 if entry.get('case_sensitive', def_case_sensitive):
70 regex.compile(pattern)
73 regex.compile('(?i)'+pattern)
75 var color: String = entry.get('color', def_color).to_html()
77 if entry_key in color_overrides:
78 color = color_overrides[entry_key].to_html()
80 text = regex.sub(text,
81 '[url=' + entry_key + ']' +
82 '[color=' + color + ']${word}[/color]' +
90 func add_glossary(path:String) -> void:
91 if ResourceLoader.exists(path):
92 var resource: DialogicGlossary = load(path)
94 if resource is DialogicGlossary:
95 glossaries.append(resource)
97 printerr('[Dialogic] The glossary file "' + path + '" is missing. Make sure it exists.')
100 ## Iterates over all glossaries and returns the first one that matches the
101 ## [param entry_key].
103 ## Runtime complexity:
104 ## O(n), where n is the number of glossaries.
105 func find_glossary(entry_key: String) -> DialogicGlossary:
106 for glossary: DialogicGlossary in glossaries:
108 if glossary.entries.has(entry_key):
114 ## Returns the first match for a given entry key.
115 ## If translation is available and enabled, it will be translated
116 func get_entry(entry_key: String) -> Dictionary:
117 var glossary: DialogicGlossary = dialogic.Glossary.find_glossary(entry_key)
123 "color": Color.WHITE,
129 var is_translation_enabled: bool = ProjectSettings.get_setting('dialogic/translation/enabled', false)
131 var entry := glossary.get_entry(entry_key)
136 result.color = entry.get("color")
137 if result.color == null:
138 result.color = ProjectSettings.get_setting(SETTING_DEFAULT_COLOR, Color.POWDER_BLUE)
140 if is_translation_enabled and not glossary._translation_id.is_empty():
141 var translation_key: String = glossary._translation_keys.get(entry_key)
142 var last_slash := translation_key.rfind('/')
147 var tr_base := translation_key.substr(0, last_slash)
149 result.title = translate(tr_base, "title", entry)
150 result.text = translate(tr_base, "text", entry)
151 result.extra = translate(tr_base, "extra", entry)
153 result.title = entry.get("title", "")
154 result.text = entry.get("text", "")
155 result.extra = entry.get("extra", "")
157 ## PARSE TEXTS FOR VARIABLES
158 result.title = dialogic.VAR.parse_variables(result.title)
159 result.text = dialogic.VAR.parse_variables(result.text)
160 result.extra = dialogic.VAR.parse_variables(result.extra)
166 ## Tries to translate the property with the given
167 func translate(tr_base: String, property: StringName, fallback_entry: Dictionary) -> String:
168 var tr_key := tr_base.path_join(property)
169 var tr_value := tr(tr_key)
171 if tr_key == tr_value:
172 tr_value = fallback_entry.get(property, "")