Fix dialogue manager plugin, lower resolution
This commit is contained in:
@@ -65,6 +65,8 @@ var _method_info_cache: Dictionary = {}
|
||||
|
||||
var _dotnet_dialogue_manager: RefCounted
|
||||
|
||||
var _expression_parser: DMExpressionParser = DMExpressionParser.new()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Cache the known Node2D properties
|
||||
@@ -185,6 +187,7 @@ func get_line(resource: DialogueResource, key: String, extra_game_states: Array)
|
||||
continue
|
||||
elif await _check_case_value(value, case, extra_game_states):
|
||||
next_id = case.next_id
|
||||
break
|
||||
# Nothing matched so check for else case
|
||||
if next_id == "":
|
||||
if not else_case.is_empty():
|
||||
@@ -206,16 +209,6 @@ func get_line(resource: DialogueResource, key: String, extra_game_states: Array)
|
||||
else:
|
||||
cummulative_weight += sibling.weight
|
||||
|
||||
# Find any simultaneously said lines.
|
||||
var concurrent_lines: Array[DialogueLine] = []
|
||||
if data.has(&"concurrent_lines"):
|
||||
# If the list includes this line then it isn't the origin line so ignore it.
|
||||
if not data.concurrent_lines.has(data.id):
|
||||
for concurrent_id: String in data.concurrent_lines:
|
||||
var concurrent_line: DialogueLine = await get_line(resource, concurrent_id, extra_game_states)
|
||||
if concurrent_line:
|
||||
concurrent_lines.append(concurrent_line)
|
||||
|
||||
# If this line is blank and it's the last line then check for returning snippets.
|
||||
if data.type in [DMConstants.TYPE_COMMENT, DMConstants.TYPE_UNKNOWN]:
|
||||
if data.next_id in [DMConstants.ID_END, DMConstants.ID_NULL, null]:
|
||||
@@ -252,11 +245,18 @@ func get_line(resource: DialogueResource, key: String, extra_game_states: Array)
|
||||
|
||||
# Set up a line object.
|
||||
var line: DialogueLine = await create_dialogue_line(data, extra_game_states)
|
||||
line.concurrent_lines = concurrent_lines
|
||||
|
||||
# If the jump point somehow has no content then just end.
|
||||
if not line: return null
|
||||
|
||||
# Find any simultaneously said lines.
|
||||
if data.has(&"concurrent_lines"):
|
||||
# If the list includes this line then it isn't the origin line so ignore it.
|
||||
if not data.concurrent_lines.has(data.id):
|
||||
# Resolve IDs to their actual lines.
|
||||
for line_id: String in data.concurrent_lines:
|
||||
line.concurrent_lines.append(await get_line(resource, line_id, extra_game_states))
|
||||
|
||||
# If we are the first of a list of responses then get the other ones.
|
||||
if data.type == DMConstants.TYPE_RESPONSE:
|
||||
# Note: For some reason C# has occasional issues with using the responses property directly
|
||||
@@ -293,7 +293,15 @@ func get_resolved_line_data(data: Dictionary, extra_game_states: Array = []) ->
|
||||
var text: String = translate(data)
|
||||
|
||||
# Resolve variables
|
||||
for replacement in data.get(&"text_replacements", [] as Array[Dictionary]):
|
||||
var text_replacements: Array[Dictionary] = data.get(&"text_replacements", [] as Array[Dictionary])
|
||||
if text_replacements.size() == 0 and "{{" in text:
|
||||
# This line is translated but has expressions that didn't exist in the base text.
|
||||
text_replacements = _expression_parser.extract_replacements(text, 0)
|
||||
|
||||
for replacement in text_replacements:
|
||||
if replacement.has("error"):
|
||||
assert(false, "%s \"%s\"" % [DMConstants.get_error_message(replacement.get("error")), text])
|
||||
|
||||
var value = await _resolve(replacement.expression.duplicate(true), extra_game_states)
|
||||
var index: int = text.find(replacement.value_in_text)
|
||||
if index == -1:
|
||||
@@ -442,6 +450,18 @@ func show_dialogue_balloon_scene(balloon_scene, resource: DialogueResource, titl
|
||||
return balloon
|
||||
|
||||
|
||||
## Resolve a static line ID to an actual line ID
|
||||
func static_id_to_line_id(resource: DialogueResource, static_id: String) -> String:
|
||||
var ids = static_id_to_line_ids(resource, static_id)
|
||||
if ids.size() == 0: return ""
|
||||
return ids[0]
|
||||
|
||||
|
||||
## Resolve a static line ID to any actual line IDs that match
|
||||
func static_id_to_line_ids(resource: DialogueResource, static_id: String) -> PackedStringArray:
|
||||
return resource.lines.values().filter(func(l): return l.get(&"translation_key", "") == static_id).map(func(l): return l.id)
|
||||
|
||||
|
||||
# Call "start" on the given balloon.
|
||||
func _start_balloon(balloon: Node, resource: DialogueResource, title: String, extra_game_states: Array) -> void:
|
||||
get_current_scene.call().add_child(balloon)
|
||||
@@ -524,7 +544,7 @@ func show_error_for_missing_state_value(message: String, will_show: bool = true)
|
||||
|
||||
# Translate a string
|
||||
func translate(data: Dictionary) -> String:
|
||||
if translation_source == DMConstants.TranslationSource.None:
|
||||
if TranslationServer.get_loaded_locales().size() == 0 or translation_source == DMConstants.TranslationSource.None:
|
||||
return data.text
|
||||
|
||||
var translation_key: String = data.get(&"translation_key", data.text)
|
||||
@@ -605,12 +625,13 @@ func create_response(data: Dictionary, extra_game_states: Array) -> DialogueResp
|
||||
type = DMConstants.TYPE_RESPONSE,
|
||||
next_id = data.next_id,
|
||||
is_allowed = data.is_allowed,
|
||||
condition_as_text = data.get(&"condition_as_text", ""),
|
||||
character = await get_resolved_character(data, extra_game_states),
|
||||
character_replacements = data.get(&"character_replacements", [] as Array[Dictionary]),
|
||||
text = resolved_data.text,
|
||||
text_replacements = data.get(&"text_replacements", [] as Array[Dictionary]),
|
||||
tags = data.get(&"tags", []),
|
||||
translation_key = data.get(&"translation_key", data.text)
|
||||
translation_key = data.get(&"translation_key", data.text),
|
||||
})
|
||||
|
||||
|
||||
@@ -629,7 +650,7 @@ func _get_game_states(extra_game_states: Array) -> Array:
|
||||
game_states = [_autoloads]
|
||||
# Add any other state shortcuts from settings
|
||||
for node_name in DMSettings.get_setting(DMSettings.STATE_AUTOLOAD_SHORTCUTS, ""):
|
||||
var state: Node = Engine.get_main_loop().root.get_node_or_null(node_name)
|
||||
var state: Node = Engine.get_main_loop().root.get_node_or_null(NodePath(node_name))
|
||||
if state:
|
||||
game_states.append(state)
|
||||
|
||||
@@ -661,21 +682,32 @@ func _check_case_value(match_value: Variant, data: Dictionary, extra_game_states
|
||||
|
||||
var expression: Array[Dictionary] = data.condition.expression.duplicate(true)
|
||||
|
||||
# If the when is a comparison when insert the match value as the first value to compare to
|
||||
var already_compared: bool = false
|
||||
if expression[0].type == DMConstants.TOKEN_COMPARISON:
|
||||
expression.insert(0, {
|
||||
type = DMConstants.TOKEN_VALUE,
|
||||
value = match_value
|
||||
})
|
||||
already_compared = true
|
||||
# Check for multiple values
|
||||
var expressions_to_check: Array = []
|
||||
var previous_comma_index: int = 0
|
||||
for i in range(0, expression.size()):
|
||||
if expression[i].type == DMConstants.TOKEN_COMMA:
|
||||
expressions_to_check.append(expression.slice(previous_comma_index, i))
|
||||
previous_comma_index = i + 1
|
||||
elif i == expression.size() - 1:
|
||||
expressions_to_check.append(expression.slice(previous_comma_index))
|
||||
|
||||
var resolved_value = await _resolve(expression, extra_game_states)
|
||||
for expression_to_check in expressions_to_check:
|
||||
# If the when is a comparison when insert the match value as the first value to compare to
|
||||
var already_compared: bool = false
|
||||
if expression_to_check[0].type == DMConstants.TOKEN_COMPARISON:
|
||||
expression_to_check.insert(0, {
|
||||
type = DMConstants.TOKEN_VALUE,
|
||||
value = match_value
|
||||
})
|
||||
already_compared = true
|
||||
|
||||
var resolved_value = await _resolve(expression_to_check, extra_game_states)
|
||||
if (already_compared and resolved_value) or match_value == resolved_value:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
if already_compared:
|
||||
return resolved_value
|
||||
else:
|
||||
return match_value == resolved_value
|
||||
|
||||
|
||||
# Make a change to game state or run a method
|
||||
@@ -757,6 +789,13 @@ func _get_state_value(property: String, extra_game_states: Array):
|
||||
if state.has(property):
|
||||
return state.get(property)
|
||||
else:
|
||||
# Try for a C# constant first
|
||||
if state.get_script() \
|
||||
and state.get_script().resource_path.ends_with(".cs") \
|
||||
and _get_dotnet_dialogue_manager().ThingHasConstant(state, property):
|
||||
return _get_dotnet_dialogue_manager().ResolveThingConstant(state, property)
|
||||
|
||||
# Otherwise just let Godot try and resolve it.
|
||||
var result = expression.execute([], state, false)
|
||||
if not expression.has_execute_failed():
|
||||
return result
|
||||
@@ -782,7 +821,7 @@ func _warn_about_state_name_collisions(target_key: String, extra_game_states: Ar
|
||||
# Get the list of state shortcuts.
|
||||
var state_shortcuts: Array = []
|
||||
for node_name in DMSettings.get_setting(DMSettings.STATE_AUTOLOAD_SHORTCUTS, ""):
|
||||
var state: Node = Engine.get_main_loop().root.get_node_or_null(node_name)
|
||||
var state: Node = Engine.get_main_loop().root.get_node_or_null(NodePath(node_name))
|
||||
if state:
|
||||
state_shortcuts.append(state)
|
||||
|
||||
@@ -867,7 +906,18 @@ func _resolve(tokens: Array, extra_game_states: Array):
|
||||
limit += 1
|
||||
var token: Dictionary = tokens[i]
|
||||
|
||||
if token.type == DMConstants.TOKEN_FUNCTION:
|
||||
if token.type == DMConstants.TOKEN_NULL_COALESCE:
|
||||
var caller: Dictionary = tokens[i - 1]
|
||||
if caller.value == null:
|
||||
# If the caller is null then the method/property is also null
|
||||
caller.type = DMConstants.TOKEN_VALUE
|
||||
caller.value = null
|
||||
tokens.remove_at(i + 1)
|
||||
tokens.remove_at(i)
|
||||
else:
|
||||
token.type = DMConstants.TOKEN_DOT
|
||||
|
||||
elif token.type == DMConstants.TOKEN_FUNCTION:
|
||||
var function_name: String = token.function
|
||||
var args = await _resolve_each(token.value, extra_game_states)
|
||||
if tokens[i - 1].type == DMConstants.TOKEN_DOT:
|
||||
@@ -1330,6 +1380,9 @@ func _is_valid(line: DialogueLine) -> bool:
|
||||
|
||||
# Check that a thing has a given method.
|
||||
func _thing_has_method(thing, method: String, args: Array) -> bool:
|
||||
if not is_instance_valid(thing):
|
||||
return false
|
||||
|
||||
if Builtins.is_supported(thing, method):
|
||||
return thing != _autoloads
|
||||
elif thing is Dictionary:
|
||||
@@ -1344,7 +1397,7 @@ func _thing_has_method(thing, method: String, args: Array) -> bool:
|
||||
if thing.has_method(method):
|
||||
return true
|
||||
|
||||
if method.to_snake_case() != method and DMSettings.check_for_dotnet_solution():
|
||||
if thing.get_script() and thing.get_script().resource_path.ends_with(".cs"):
|
||||
# If we get this far then the method might be a C# method with a Task return type
|
||||
return _get_dotnet_dialogue_manager().ThingHasMethod(thing, method, args)
|
||||
|
||||
@@ -1363,6 +1416,10 @@ func _thing_has_property(thing: Object, property: String) -> bool:
|
||||
if p.name == property:
|
||||
return true
|
||||
|
||||
if thing.get_script() and thing.get_script().resource_path.ends_with(".cs"):
|
||||
# If we get this far then the property might be a C# constant.
|
||||
return _get_dotnet_dialogue_manager().ThingHasConstant(thing, property)
|
||||
|
||||
return false
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user