First work on dialogic, resized guild, and started implementing portraits.
This commit is contained in:
363
addons/dialogic/Modules/Variable/event_variable.gd
Normal file
363
addons/dialogic/Modules/Variable/event_variable.gd
Normal file
@@ -0,0 +1,363 @@
|
||||
@tool
|
||||
class_name DialogicVariableEvent
|
||||
extends DialogicEvent
|
||||
|
||||
## Event that allows changing a dialogic variable or a property of an autoload.
|
||||
|
||||
|
||||
enum Operations {SET, ADD, SUBSTRACT, MULTIPLY, DIVIDE}
|
||||
enum VarValueType {
|
||||
STRING = 0,
|
||||
NUMBER = 1,
|
||||
VARIABLE = 2,
|
||||
BOOL = 3,
|
||||
EXPRESSION = 4,
|
||||
RANDOM_NUMBER = 5,
|
||||
}
|
||||
|
||||
## Settings
|
||||
|
||||
## Name/Path of the variable that should be changed.
|
||||
var name := "":
|
||||
set(_value):
|
||||
name = _value
|
||||
if Engine.is_editor_hint() and not value:
|
||||
match DialogicUtil.get_variable_type(name):
|
||||
DialogicUtil.VarTypes.ANY, DialogicUtil.VarTypes.STRING:
|
||||
_value_type = VarValueType.STRING
|
||||
DialogicUtil.VarTypes.FLOAT, DialogicUtil.VarTypes.INT:
|
||||
_value_type = VarValueType.NUMBER
|
||||
DialogicUtil.VarTypes.BOOL:
|
||||
_value_type = VarValueType.BOOL
|
||||
ui_update_needed.emit()
|
||||
update_editor_warning()
|
||||
|
||||
## The operation to perform.
|
||||
var operation := Operations.SET:
|
||||
set(value):
|
||||
operation = value
|
||||
if operation != Operations.SET and _value_type == VarValueType.STRING:
|
||||
_value_type = VarValueType.NUMBER
|
||||
ui_update_needed.emit()
|
||||
update_editor_warning()
|
||||
|
||||
## The value that is used. Can be a variable as well.
|
||||
var value: Variant = ""
|
||||
var _value_type := 0 :
|
||||
set(_value):
|
||||
_value_type = _value
|
||||
if not _suppress_default_value:
|
||||
match _value_type:
|
||||
VarValueType.STRING, VarValueType.VARIABLE, VarValueType.EXPRESSION:
|
||||
value = ""
|
||||
VarValueType.NUMBER:
|
||||
value = 0
|
||||
VarValueType.BOOL:
|
||||
value = false
|
||||
VarValueType.RANDOM_NUMBER:
|
||||
value = null
|
||||
ui_update_needed.emit()
|
||||
update_editor_warning()
|
||||
|
||||
## If true, a random number between [random_min] and [random_max] is used instead of [value].
|
||||
var random_min: int = 0
|
||||
var random_max: int = 100
|
||||
|
||||
## Used to suppress _value_type from overwriting value with a default value when the type changes
|
||||
## This is only used when initializing the event_variable.
|
||||
var _suppress_default_value := false
|
||||
|
||||
|
||||
################################################################################
|
||||
## EXECUTE
|
||||
################################################################################
|
||||
|
||||
func _execute() -> void:
|
||||
if name:
|
||||
var original_value: Variant = dialogic.VAR.get_variable(name, null, operation == Operations.SET and "[" in name)
|
||||
|
||||
if value != null and (original_value != null or (operation == Operations.SET and "[" in name)):
|
||||
|
||||
var interpreted_value: Variant
|
||||
var result: Variant
|
||||
|
||||
match _value_type:
|
||||
VarValueType.STRING:
|
||||
interpreted_value = dialogic.VAR.get_variable('"' + value + '"')
|
||||
VarValueType.VARIABLE:
|
||||
interpreted_value = dialogic.VAR.get_variable('{' + value + '}')
|
||||
VarValueType.NUMBER, VarValueType.BOOL, VarValueType.EXPRESSION, VarValueType.RANDOM_NUMBER:
|
||||
interpreted_value = dialogic.VAR.get_variable(str(value))
|
||||
|
||||
if operation != Operations.SET and (not str(original_value).is_valid_float() or not str(interpreted_value).is_valid_float()):
|
||||
printerr("[Dialogic] Set Variable event failed because one value wasn't a float! [", original_value, ", ",interpreted_value,"]")
|
||||
finish()
|
||||
return
|
||||
|
||||
if operation == Operations.SET:
|
||||
result = interpreted_value
|
||||
|
||||
else:
|
||||
original_value = float(original_value)
|
||||
interpreted_value = float(interpreted_value)
|
||||
|
||||
match operation:
|
||||
Operations.ADD:
|
||||
result = original_value + interpreted_value
|
||||
Operations.SUBSTRACT:
|
||||
result = original_value - interpreted_value
|
||||
Operations.MULTIPLY:
|
||||
result = original_value * interpreted_value
|
||||
Operations.DIVIDE:
|
||||
result = original_value / interpreted_value
|
||||
|
||||
dialogic.VAR.set_variable(name, result)
|
||||
dialogic.VAR.variable_was_set.emit(
|
||||
{
|
||||
'variable' : name,
|
||||
'value' : interpreted_value,
|
||||
'value_str' : value,
|
||||
'orig_value' : original_value,
|
||||
'new_value' : result,
|
||||
})
|
||||
|
||||
else:
|
||||
printerr("[Dialogic] Set Variable event failed because one value wasn't set!")
|
||||
|
||||
finish()
|
||||
|
||||
|
||||
################################################################################
|
||||
## INITIALIZE
|
||||
################################################################################
|
||||
|
||||
func _init() -> void:
|
||||
event_name = "Set Variable"
|
||||
set_default_color('Color6')
|
||||
event_category = "Logic"
|
||||
event_sorting_index = 0
|
||||
help_page_path = "https://docs.dialogic.pro/variables.html#23-set-variable-event"
|
||||
|
||||
|
||||
################################################################################
|
||||
## SAVING/LOADING
|
||||
################################################################################
|
||||
|
||||
func to_text() -> String:
|
||||
var string := "set "
|
||||
if name:
|
||||
string += "{" + name.trim_prefix('{').trim_suffix('}') + "}"
|
||||
match operation:
|
||||
Operations.SET:
|
||||
string+= " = "
|
||||
Operations.ADD:
|
||||
string+= " += "
|
||||
Operations.SUBSTRACT:
|
||||
string+= " -= "
|
||||
Operations.MULTIPLY:
|
||||
string+= " *= "
|
||||
Operations.DIVIDE:
|
||||
string+= " /= "
|
||||
|
||||
value = str(value)
|
||||
match _value_type:
|
||||
VarValueType.STRING: # String
|
||||
string += '"'+value.replace('"', '\\"')+'"'
|
||||
VarValueType.NUMBER,VarValueType.BOOL,VarValueType.EXPRESSION: # Float Bool, or Expression
|
||||
string += str(value)
|
||||
VarValueType.VARIABLE: # Variable
|
||||
string += '{'+value+'}'
|
||||
VarValueType.RANDOM_NUMBER:
|
||||
string += 'range('+str(random_min)+','+str(random_max)+').pick_random()'
|
||||
|
||||
return string
|
||||
|
||||
|
||||
func from_text(string:String) -> void:
|
||||
var reg := RegEx.new()
|
||||
reg.compile("set(?<name>[^=+\\-*\\/]*)?(?<operation>=|\\+=|-=|\\*=|\\/=)?(?<value>.*)")
|
||||
var result := reg.search(string)
|
||||
if !result:
|
||||
return
|
||||
name = result.get_string('name').strip_edges().replace("{", "").replace("}", "")
|
||||
match result.get_string('operation').strip_edges():
|
||||
'=':
|
||||
operation = Operations.SET
|
||||
'-=':
|
||||
operation = Operations.SUBSTRACT
|
||||
'+=':
|
||||
operation = Operations.ADD
|
||||
'*=':
|
||||
operation = Operations.MULTIPLY
|
||||
'/=':
|
||||
operation = Operations.DIVIDE
|
||||
|
||||
_suppress_default_value = true
|
||||
value = result.get_string('value').strip_edges()
|
||||
if not value.is_empty():
|
||||
if value.begins_with('"') and value.ends_with('"') and value.count('"')-value.count('\\"') == 2:
|
||||
value = result.get_string('value').strip_edges().replace('"', '')
|
||||
_value_type = VarValueType.STRING
|
||||
elif value.begins_with('{') and value.ends_with('}') and value.count('{') == 1:
|
||||
value = result.get_string('value').strip_edges().trim_suffix('}').trim_prefix('{')
|
||||
_value_type = VarValueType.VARIABLE
|
||||
elif value in ["true", "false"]:
|
||||
value = value == "true"
|
||||
_value_type = VarValueType.BOOL
|
||||
elif value.begins_with('range(') and value.ends_with(').pick_random()'):
|
||||
_value_type = VarValueType.RANDOM_NUMBER
|
||||
var randinf := str(value).trim_prefix('range(').trim_suffix(').pick_random()').split(',')
|
||||
random_min = int(randinf[0])
|
||||
random_max = int(randinf[1])
|
||||
else:
|
||||
value = result.get_string('value').strip_edges()
|
||||
if value.is_valid_float():
|
||||
_value_type = VarValueType.NUMBER
|
||||
else:
|
||||
_value_type = VarValueType.EXPRESSION
|
||||
else:
|
||||
value = null
|
||||
_suppress_default_value = false
|
||||
|
||||
|
||||
func is_valid_event(string:String) -> bool:
|
||||
return string.begins_with('set')
|
||||
|
||||
|
||||
################################################################################
|
||||
## EDITOR REPRESENTATION
|
||||
################################################################################
|
||||
|
||||
func build_event_editor() -> void:
|
||||
add_header_edit('name', ValueType.DYNAMIC_OPTIONS, {
|
||||
'left_text' : 'Set',
|
||||
'suggestions_func' : get_var_suggestions,
|
||||
'icon' : load("res://addons/dialogic/Editor/Images/Pieces/variable.svg"),
|
||||
'placeholder' :'Select Variable'}
|
||||
)
|
||||
add_header_edit('operation', ValueType.FIXED_OPTIONS, {
|
||||
'options': [
|
||||
{
|
||||
'label': 'to be',
|
||||
'icon': load("res://addons/dialogic/Editor/Images/Dropdown/set.svg"),
|
||||
'value': Operations.SET
|
||||
},{
|
||||
'label': 'to itself plus',
|
||||
'icon': load("res://addons/dialogic/Editor/Images/Dropdown/plus.svg"),
|
||||
'value': Operations.ADD
|
||||
},{
|
||||
'label': 'to itself minus',
|
||||
'icon': load("res://addons/dialogic/Editor/Images/Dropdown/minus.svg"),
|
||||
'value': Operations.SUBSTRACT
|
||||
},{
|
||||
'label': 'to itself multiplied by',
|
||||
'icon': load("res://addons/dialogic/Editor/Images/Dropdown/multiply.svg"),
|
||||
'value': Operations.MULTIPLY
|
||||
},{
|
||||
'label': 'to itself divided by',
|
||||
'icon': load("res://addons/dialogic/Editor/Images/Dropdown/divide.svg"),
|
||||
'value': Operations.DIVIDE
|
||||
}
|
||||
]
|
||||
}, '!name.is_empty()')
|
||||
add_header_edit('_value_type', ValueType.FIXED_OPTIONS, {
|
||||
'options': [
|
||||
{
|
||||
'label': 'String',
|
||||
'icon': ["String", "EditorIcons"],
|
||||
'value': VarValueType.STRING
|
||||
},{
|
||||
'label': 'Number',
|
||||
'icon': ["float", "EditorIcons"],
|
||||
'value': VarValueType.NUMBER
|
||||
},{
|
||||
'label': 'Variable',
|
||||
'icon': load("res://addons/dialogic/Editor/Images/Pieces/variable.svg"),
|
||||
'value': VarValueType.VARIABLE
|
||||
},{
|
||||
'label': 'Bool',
|
||||
'icon': ["bool", "EditorIcons"],
|
||||
'value': VarValueType.BOOL
|
||||
},{
|
||||
'label': 'Expression',
|
||||
'icon': ["Variant", "EditorIcons"],
|
||||
'value': VarValueType.EXPRESSION
|
||||
},{
|
||||
'label': 'Random Number',
|
||||
'icon': ["RandomNumberGenerator", "EditorIcons"],
|
||||
'value': VarValueType.RANDOM_NUMBER
|
||||
}],
|
||||
'symbol_only':true},
|
||||
'!name.is_empty()')
|
||||
add_header_edit('value', ValueType.SINGLELINE_TEXT, {}, '!name.is_empty() and (_value_type == VarValueType.STRING or _value_type == VarValueType.EXPRESSION) ')
|
||||
add_header_edit('value', ValueType.BOOL, {}, '!name.is_empty() and (_value_type == VarValueType.BOOL) ')
|
||||
add_header_edit('value', ValueType.NUMBER, {}, '!name.is_empty() and _value_type == VarValueType.NUMBER')
|
||||
add_header_edit('value', ValueType.DYNAMIC_OPTIONS,
|
||||
{'suggestions_func' : get_value_suggestions, 'placeholder':'Select Variable'},
|
||||
'!name.is_empty() and _value_type == VarValueType.VARIABLE')
|
||||
add_header_label('a number between', '_value_type == VarValueType.RANDOM_NUMBER')
|
||||
add_header_edit('random_min', ValueType.NUMBER, {'right_text':'and', 'mode':1}, '!name.is_empty() and _value_type == VarValueType.RANDOM_NUMBER')
|
||||
add_header_edit('random_max', ValueType.NUMBER, {'mode':1}, '!name.is_empty() and _value_type == VarValueType.RANDOM_NUMBER')
|
||||
add_header_button('', _on_variable_editor_pressed, 'Variable Editor', ["ExternalLink", "EditorIcons"])
|
||||
|
||||
|
||||
func get_var_suggestions(filter:String) -> Dictionary:
|
||||
var suggestions := {}
|
||||
if filter:
|
||||
suggestions[filter] = {'value':filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}
|
||||
for var_path in DialogicUtil.list_variables(DialogicUtil.get_default_variables()):
|
||||
suggestions[var_path] = {'value':var_path, 'icon':load("res://addons/dialogic/Editor/Images/Pieces/variable.svg")}
|
||||
return suggestions
|
||||
|
||||
|
||||
func get_value_suggestions(_filter:String) -> Dictionary:
|
||||
var suggestions := {}
|
||||
|
||||
for var_path in DialogicUtil.list_variables(DialogicUtil.get_default_variables()):
|
||||
suggestions[var_path] = {'value':var_path, 'icon':load("res://addons/dialogic/Editor/Images/Pieces/variable.svg")}
|
||||
return suggestions
|
||||
|
||||
|
||||
func _on_variable_editor_pressed() -> void:
|
||||
var editor_manager := editor_node.find_parent('EditorsManager')
|
||||
if editor_manager:
|
||||
editor_manager.open_editor(editor_manager.editors['VariablesEditor']['node'], true)
|
||||
|
||||
|
||||
func update_editor_warning() -> void:
|
||||
if _value_type == VarValueType.STRING and operation != Operations.SET:
|
||||
ui_update_warning.emit('You cannot do this operation with a string!')
|
||||
elif operation != Operations.SET:
|
||||
var type := DialogicUtil.get_variable_type(name)
|
||||
if not type in [DialogicUtil.VarTypes.INT, DialogicUtil.VarTypes.FLOAT, DialogicUtil.VarTypes.ANY]:
|
||||
ui_update_warning.emit('The selected variable is not a number!')
|
||||
else:
|
||||
ui_update_warning.emit('')
|
||||
else:
|
||||
ui_update_warning.emit('')
|
||||
|
||||
|
||||
|
||||
####################### CODE COMPLETION ########################################
|
||||
################################################################################
|
||||
|
||||
func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
|
||||
if CodeCompletionHelper.get_line_untill_caret(line) == 'set ':
|
||||
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, '{', '{', TextNode.syntax_highlighter.variable_color)
|
||||
if symbol == '{':
|
||||
CodeCompletionHelper.suggest_variables(TextNode)
|
||||
|
||||
|
||||
func _get_start_code_completion(_CodeCompletionHelper:Node, TextNode:TextEdit) -> void:
|
||||
TextNode.add_code_completion_option(CodeEdit.KIND_PLAIN_TEXT, 'set', 'set ', event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.5))
|
||||
|
||||
|
||||
#################### SYNTAX HIGHLIGHTING #######################################
|
||||
################################################################################
|
||||
|
||||
func _get_syntax_highlighting(Highlighter:SyntaxHighlighter, dict:Dictionary, line:String) -> Dictionary:
|
||||
dict[line.find('set')] = {"color":event_color.lerp(Highlighter.normal_color, 0.5)}
|
||||
dict[line.find('set')+3] = {"color":Highlighter.normal_color}
|
||||
dict = Highlighter.color_region(dict, Highlighter.string_color, line, '"', '"', line.find('set'))
|
||||
dict = Highlighter.color_region(dict, Highlighter.variable_color, line, '{', '}', line.find('set'))
|
||||
return dict
|
||||
Reference in New Issue
Block a user