You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
3.9 KiB
140 lines
3.9 KiB
6 months ago
|
@tool
|
||
|
extends Resource
|
||
|
class_name DialogicCharacter
|
||
|
|
||
|
|
||
|
## Resource that represents a character in dialog.
|
||
|
## Manages/contains portraits, custom info and translation of characters.
|
||
|
|
||
|
@export var display_name := ""
|
||
|
@export var nicknames := []
|
||
|
|
||
|
@export var color := Color()
|
||
|
@export var description := ""
|
||
|
|
||
|
@export var scale := 1.0
|
||
|
@export var offset := Vector2()
|
||
|
@export var mirror := false
|
||
|
|
||
|
@export var default_portrait := ""
|
||
|
@export var portraits := {}
|
||
|
|
||
|
@export var custom_info := {}
|
||
|
|
||
|
## All valid properties that can be accessed by their translation.
|
||
|
enum TranslatedProperties {
|
||
|
NAME,
|
||
|
NICKNAMES,
|
||
|
}
|
||
|
|
||
|
var _translation_id := ""
|
||
|
|
||
|
|
||
|
func _to_string() -> String:
|
||
|
return "[{name}:{id}]".format({"name":get_character_name(), "id":get_instance_id()})
|
||
|
|
||
|
|
||
|
## Adds a translation ID to the character.
|
||
|
func add_translation_id() -> String:
|
||
|
_translation_id = DialogicUtil.get_next_translation_id()
|
||
|
return _translation_id
|
||
|
|
||
|
|
||
|
## Returns the character's translation ID.
|
||
|
## Adds a translation ID to the character if it doesn't have one.
|
||
|
func get_set_translation_id() -> String:
|
||
|
if _translation_id == null or _translation_id.is_empty():
|
||
|
return add_translation_id()
|
||
|
else:
|
||
|
return _translation_id
|
||
|
|
||
|
|
||
|
## Removes the translation ID from the character.
|
||
|
func remove_translation_id() -> void:
|
||
|
_translation_id = ""
|
||
|
|
||
|
|
||
|
## Checks [param property] and matches it to a translation key.
|
||
|
##
|
||
|
## Undefined behaviour if an invalid integer is passed.
|
||
|
func get_property_translation_key(property: TranslatedProperties) -> String:
|
||
|
var property_key := ""
|
||
|
|
||
|
match property:
|
||
|
TranslatedProperties.NAME:
|
||
|
property_key = "name"
|
||
|
TranslatedProperties.NICKNAMES:
|
||
|
property_key = "nicknames"
|
||
|
|
||
|
return "Character".path_join(_translation_id).path_join(property_key)
|
||
|
|
||
|
|
||
|
## Accesses the original text of the character.
|
||
|
##
|
||
|
## Undefined behaviour if an invalid integer is passed.
|
||
|
func _get_property_original_text(property: TranslatedProperties) -> String:
|
||
|
match property:
|
||
|
TranslatedProperties.NAME:
|
||
|
return display_name
|
||
|
TranslatedProperties.NICKNAMES:
|
||
|
return ", ".join(nicknames)
|
||
|
|
||
|
return ""
|
||
|
|
||
|
|
||
|
## Access a property of the character and if conditions are met, attempts to
|
||
|
## translate the property.
|
||
|
##
|
||
|
## The translation feature must be enabled in the project settings.
|
||
|
## The translation ID must be set.
|
||
|
## Otherwise, returns the text property as is.
|
||
|
##
|
||
|
## Undefined behaviour if an invalid integer is passed.
|
||
|
func _get_property_translated(property: TranslatedProperties) -> String:
|
||
|
var try_translation: bool = (_translation_id != null
|
||
|
and not _translation_id.is_empty()
|
||
|
and ProjectSettings.get_setting('dialogic/translation/enabled', false)
|
||
|
)
|
||
|
|
||
|
if try_translation:
|
||
|
var translation_key := get_property_translation_key(property)
|
||
|
var translated_property := tr(translation_key)
|
||
|
|
||
|
# If no translation is found, tr() returns the ID.
|
||
|
# However, we want to fallback to the original text.
|
||
|
if translated_property == translation_key:
|
||
|
return _get_property_original_text(property)
|
||
|
|
||
|
return translated_property
|
||
|
|
||
|
else:
|
||
|
return _get_property_original_text(property)
|
||
|
|
||
|
|
||
|
## Translates the nicknames of the characters and then returns them as an array
|
||
|
## of strings.
|
||
|
func get_nicknames_translated() -> Array:
|
||
|
var translated_nicknames := _get_property_translated(TranslatedProperties.NICKNAMES)
|
||
|
return (translated_nicknames.split(", ") as Array)
|
||
|
|
||
|
|
||
|
## Translates and returns the display name of the character.
|
||
|
func get_display_name_translated() -> String:
|
||
|
return _get_property_translated(TranslatedProperties.NAME)
|
||
|
|
||
|
|
||
|
## Returns the name of the file (without the extension).
|
||
|
func get_character_name() -> String:
|
||
|
if !resource_path.is_empty():
|
||
|
return resource_path.get_file().trim_suffix('.dch')
|
||
|
elif !display_name.is_empty():
|
||
|
return display_name.validate_node_name()
|
||
|
else:
|
||
|
return "UnnamedCharacter"
|
||
|
|
||
|
|
||
|
## Returns the info of the given portrait.
|
||
|
## Uses the default portrait if the given portrait doesn't exist.
|
||
|
func get_portrait_info(portrait_name:String) -> Dictionary:
|
||
|
return portraits.get(portrait_name, portraits.get(default_portrait, {}))
|