Fix dialogue manager plugin, lower resolution
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
using Godot.Collections;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -92,8 +93,7 @@ namespace DialogueManagerRuntime
|
|||||||
|
|
||||||
public static async Task<GodotObject> GetSingleton()
|
public static async Task<GodotObject> GetSingleton()
|
||||||
{
|
{
|
||||||
if (instance != null)
|
if (instance != null) return instance;
|
||||||
return instance;
|
|
||||||
|
|
||||||
var tree = Engine.GetMainLoop();
|
var tree = Engine.GetMainLoop();
|
||||||
int x = 0;
|
int x = 0;
|
||||||
@@ -128,8 +128,7 @@ namespace DialogueManagerRuntime
|
|||||||
var result = await instance.ToSignal(instance, "bridge_get_next_dialogue_line_completed");
|
var result = await instance.ToSignal(instance, "bridge_get_next_dialogue_line_completed");
|
||||||
instance.QueueFree();
|
instance.QueueFree();
|
||||||
|
|
||||||
if ((RefCounted)result[0] == null)
|
if ((RefCounted)result[0] == null) return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
return new DialogueLine((RefCounted)result[0]);
|
return new DialogueLine((RefCounted)result[0]);
|
||||||
}
|
}
|
||||||
@@ -163,6 +162,18 @@ namespace DialogueManagerRuntime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Array<string> StaticIdToLineIds(Resource dialogueResource, string staticId)
|
||||||
|
{
|
||||||
|
return (Array<string>)Instance.Call("static_id_to_line_ids", dialogueResource, staticId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string StaticIdToLineId(Resource dialogueResource, string staticId)
|
||||||
|
{
|
||||||
|
return (string)Instance.Call("static_id_to_line_id", dialogueResource, staticId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static async void Mutate(Dictionary mutation, Array<Variant>? extraGameStates = null, bool isInlineMutation = false)
|
public static async void Mutate(Dictionary mutation, Array<Variant>? extraGameStates = null, bool isInlineMutation = false)
|
||||||
{
|
{
|
||||||
Instance.Call("_bridge_mutate", mutation, extraGameStates ?? new Array<Variant>(), isInlineMutation);
|
Instance.Call("_bridge_mutate", mutation, extraGameStates ?? new Array<Variant>(), isInlineMutation);
|
||||||
@@ -170,12 +181,105 @@ namespace DialogueManagerRuntime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Array<Dictionary> GetMembersForAutoload(Script script)
|
||||||
|
{
|
||||||
|
Array<Dictionary> members = new Array<Dictionary>();
|
||||||
|
|
||||||
|
string typeName = script.ResourcePath.GetFile().GetBaseName();
|
||||||
|
var matchingTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.Name == typeName);
|
||||||
|
foreach (var matchingType in matchingTypes)
|
||||||
|
{
|
||||||
|
var memberInfos = matchingType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||||
|
foreach (var memberInfo in memberInfos)
|
||||||
|
{
|
||||||
|
string type;
|
||||||
|
switch (memberInfo.MemberType)
|
||||||
|
{
|
||||||
|
case MemberTypes.Field:
|
||||||
|
FieldInfo fieldInfo = memberInfo as FieldInfo;
|
||||||
|
|
||||||
|
if (fieldInfo.FieldType.ToString().Contains("EventHandler"))
|
||||||
|
{
|
||||||
|
type = "signal";
|
||||||
|
}
|
||||||
|
else if (fieldInfo.IsLiteral)
|
||||||
|
{
|
||||||
|
type = "constant";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = "property";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MemberTypes.Method:
|
||||||
|
type = "method";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
members.Add(new Dictionary() {
|
||||||
|
{ "name", memberInfo.Name },
|
||||||
|
{ "type", type }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool ThingHasConstant(GodotObject thing, string property)
|
||||||
|
{
|
||||||
|
var fieldInfos = thing.GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||||
|
foreach (var fieldInfo in fieldInfos)
|
||||||
|
{
|
||||||
|
if (fieldInfo.Name == property && fieldInfo.IsLiteral)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Variant ResolveThingConstant(GodotObject thing, string property)
|
||||||
|
{
|
||||||
|
var fieldInfos = thing.GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||||
|
foreach (var fieldInfo in fieldInfos)
|
||||||
|
{
|
||||||
|
if (fieldInfo.Name == property && fieldInfo.IsLiteral)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Variant value = fieldInfo.GetValue(thing) switch
|
||||||
|
{
|
||||||
|
int v => Variant.From((long)v),
|
||||||
|
float v => Variant.From((double)v),
|
||||||
|
System.String v => Variant.From((string)v),
|
||||||
|
_ => Variant.From(fieldInfo.GetValue(thing))
|
||||||
|
};
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new Exception($"Constant {property} of type ${fieldInfo.GetValue(thing).GetType()} is not supported by Variant.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception($"{property} is not a public constant on {thing}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool ThingHasMethod(GodotObject thing, string method, Array<Variant> args)
|
public bool ThingHasMethod(GodotObject thing, string method, Array<Variant> args)
|
||||||
{
|
{
|
||||||
var methodInfos = thing.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
var methodInfos = thing.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||||
foreach (var methodInfo in methodInfos)
|
foreach (var methodInfo in methodInfos)
|
||||||
{
|
{
|
||||||
if (methodInfo.Name == method && args.Count == methodInfo.GetParameters().Length)
|
if (methodInfo.Name == method && args.Count >= methodInfo.GetParameters().Where(p => !p.HasDefaultValue).Count())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -191,14 +295,13 @@ namespace DialogueManagerRuntime
|
|||||||
var methodInfos = thing.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
var methodInfos = thing.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||||
foreach (var methodInfo in methodInfos)
|
foreach (var methodInfo in methodInfos)
|
||||||
{
|
{
|
||||||
if (methodInfo.Name == method && args.Count == methodInfo.GetParameters().Length)
|
if (methodInfo.Name == method && args.Count >= methodInfo.GetParameters().Where(p => !p.HasDefaultValue).Count())
|
||||||
{
|
{
|
||||||
info = methodInfo;
|
info = methodInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info == null)
|
if (info == null) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
// Convert the method args to something reflection can handle
|
// Convert the method args to something reflection can handle
|
||||||
@@ -347,6 +450,7 @@ namespace DialogueManagerRuntime
|
|||||||
|
|
||||||
public DialogueLine(RefCounted data)
|
public DialogueLine(RefCounted data)
|
||||||
{
|
{
|
||||||
|
id = (string)data.Get("id");
|
||||||
type = (string)data.Get("type");
|
type = (string)data.Get("type");
|
||||||
next_id = (string)data.Get("next_id");
|
next_id = (string)data.Get("next_id");
|
||||||
character = (string)data.Get("character");
|
character = (string)data.Get("character");
|
||||||
@@ -414,6 +518,13 @@ namespace DialogueManagerRuntime
|
|||||||
set => is_allowed = value;
|
set => is_allowed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string condition_as_text = "";
|
||||||
|
public string ConditionAsText
|
||||||
|
{
|
||||||
|
get => condition_as_text;
|
||||||
|
set => condition_as_text = value;
|
||||||
|
}
|
||||||
|
|
||||||
private string text = "";
|
private string text = "";
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
Zennysoft.Game.Ma/addons/dialogue_manager/assets/banner.png
Normal file
BIN
Zennysoft.Game.Ma/addons/dialogue_manager/assets/banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cnm67htuohhlo"
|
||||||
|
path="res://.godot/imported/banner.png-7e9e6a304eef850602c8d5afb80df9c3.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/dialogue_manager/assets/banner.png"
|
||||||
|
dest_files=["res://.godot/imported/banner.png-7e9e6a304eef850602c8d5afb80df9c3.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
@@ -168,12 +168,13 @@ func import_content(path: String, prefix: String, imported_line_map: Dictionary,
|
|||||||
for i in range(0, content.size()):
|
for i in range(0, content.size()):
|
||||||
var line = content[i]
|
var line = content[i]
|
||||||
if line.strip_edges().begins_with("~ "):
|
if line.strip_edges().begins_with("~ "):
|
||||||
|
var indent: String = "\t".repeat(get_indent(line))
|
||||||
var title = line.strip_edges().substr(2)
|
var title = line.strip_edges().substr(2)
|
||||||
if "/" in line:
|
if "/" in line:
|
||||||
var bits = title.split("/")
|
var bits = title.split("/")
|
||||||
content[i] = "~ %s/%s" % [_imported_titles[bits[0]], bits[1]]
|
content[i] = "%s~ %s/%s" % [indent, _imported_titles[bits[0]], bits[1]]
|
||||||
else:
|
else:
|
||||||
content[i] = "~ %s/%s" % [str(path.hash()), title]
|
content[i] = "%s~ %s/%s" % [indent, str(path.hash()), title]
|
||||||
|
|
||||||
elif "=>< " in line:
|
elif "=>< " in line:
|
||||||
var jump: String = line.substr(line.find("=>< ") + "=>< ".length()).strip_edges()
|
var jump: String = line.substr(line.find("=>< ") + "=>< ".length()).strip_edges()
|
||||||
@@ -185,7 +186,7 @@ func import_content(path: String, prefix: String, imported_line_map: Dictionary,
|
|||||||
else:
|
else:
|
||||||
content[i] = "%s=>< %s/%s" % [line.split("=>< ")[0], title_hash, bits[1]]
|
content[i] = "%s=>< %s/%s" % [line.split("=>< ")[0], title_hash, bits[1]]
|
||||||
|
|
||||||
elif not jump in ["END", "END!"]:
|
elif not jump in ["END", "END!"] and not jump.begins_with("{{"):
|
||||||
content[i] = "%s=>< %s/%s" % [line.split("=>< ")[0], str(path.hash()), jump]
|
content[i] = "%s=>< %s/%s" % [line.split("=>< ")[0], str(path.hash()), jump]
|
||||||
|
|
||||||
elif "=> " in line:
|
elif "=> " in line:
|
||||||
@@ -198,7 +199,7 @@ func import_content(path: String, prefix: String, imported_line_map: Dictionary,
|
|||||||
else:
|
else:
|
||||||
content[i] = "%s=> %s/%s" % [line.split("=> ")[0], title_hash, bits[1]]
|
content[i] = "%s=> %s/%s" % [line.split("=> ")[0], title_hash, bits[1]]
|
||||||
|
|
||||||
elif not jump in ["END", "END!"]:
|
elif not jump in ["END", "END!"] and not jump.begins_with("{{"):
|
||||||
content[i] = "%s=> %s/%s" % [line.split("=> ")[0], str(path.hash()), jump]
|
content[i] = "%s=> %s/%s" % [line.split("=> ")[0], str(path.hash()), jump]
|
||||||
|
|
||||||
imported_paths.append(path)
|
imported_paths.append(path)
|
||||||
@@ -249,18 +250,22 @@ func build_line_tree(raw_lines: PackedStringArray) -> DMTreeLine:
|
|||||||
tree_line.notes = "\n".join(doc_comments)
|
tree_line.notes = "\n".join(doc_comments)
|
||||||
doc_comments.clear()
|
doc_comments.clear()
|
||||||
|
|
||||||
# Empty lines are only kept so that we can work out groupings of things (eg. responses and
|
# Empty lines are only kept so that we can work out groupings of things (eg. randomised
|
||||||
# randomised lines). Therefore we only need to keep one empty line in a row even if there
|
# lines). Therefore we only need to keep one empty line in a row even if there
|
||||||
# are multiple. The indent of an empty line is assumed to be the same as the non-empty line
|
# are multiple. The indent of an empty line is assumed to be the same as the non-empty line
|
||||||
# following it. That way, grouping calculations should work.
|
# following it. That way, grouping calculations should work.
|
||||||
if tree_line.type in [DMConstants.TYPE_UNKNOWN, DMConstants.TYPE_COMMENT] and raw_lines.size() > i + 1:
|
if tree_line.type in [DMConstants.TYPE_UNKNOWN, DMConstants.TYPE_COMMENT] and raw_lines.size() > i + 1:
|
||||||
var next_line = raw_lines[i + 1]
|
var next_line = raw_lines[i + 1]
|
||||||
if previous_line and previous_line.type in [DMConstants.TYPE_UNKNOWN, DMConstants.TYPE_COMMENT] and tree_line.type in [DMConstants.TYPE_UNKNOWN, DMConstants.TYPE_COMMENT]:
|
if get_line_type(next_line) in [DMConstants.TYPE_UNKNOWN, DMConstants.TYPE_COMMENT]:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
tree_line.type = DMConstants.TYPE_UNKNOWN
|
tree_line.type = DMConstants.TYPE_UNKNOWN
|
||||||
tree_line.indent = get_indent(next_line)
|
tree_line.indent = get_indent(next_line)
|
||||||
|
|
||||||
|
# Nothing should be more than a single indent past its parent.
|
||||||
|
if tree_line.indent > parent_chain.size():
|
||||||
|
add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_INVALID_INDENTATION)
|
||||||
|
|
||||||
# Check for indentation changes
|
# Check for indentation changes
|
||||||
if tree_line.indent > parent_chain.size() - 1:
|
if tree_line.indent > parent_chain.size() - 1:
|
||||||
parent_chain.append(previous_line)
|
parent_chain.append(previous_line)
|
||||||
@@ -481,6 +486,7 @@ func parse_match_line(tree_line: DMTreeLine, line: DMCompiledLine, siblings: Arr
|
|||||||
# Check that all children are when or else.
|
# Check that all children are when or else.
|
||||||
for child in tree_line.children:
|
for child in tree_line.children:
|
||||||
if child.type == DMConstants.TYPE_WHEN: continue
|
if child.type == DMConstants.TYPE_WHEN: continue
|
||||||
|
if child.type == DMConstants.TYPE_UNKNOWN: continue
|
||||||
if child.type == DMConstants.TYPE_CONDITION and child.text.begins_with("else"): continue
|
if child.type == DMConstants.TYPE_CONDITION and child.text.begins_with("else"): continue
|
||||||
|
|
||||||
result = add_error(child.line_number, child.indent, DMConstants.ERR_EXPECTED_WHEN_OR_ELSE)
|
result = add_error(child.line_number, child.indent, DMConstants.ERR_EXPECTED_WHEN_OR_ELSE)
|
||||||
@@ -569,11 +575,15 @@ func parse_response_line(tree_line: DMTreeLine, line: DMCompiledLine, siblings:
|
|||||||
result = add_error(tree_line.line_number, condition.index, condition.error)
|
result = add_error(tree_line.line_number, condition.index, condition.error)
|
||||||
else:
|
else:
|
||||||
line.expression = condition
|
line.expression = condition
|
||||||
|
# Extract just the raw condition text
|
||||||
|
var found: RegExMatch = regex.WRAPPED_CONDITION_REGEX.search(tree_line.text)
|
||||||
|
line.expression_text = found.strings[found.names.expression]
|
||||||
|
|
||||||
tree_line.text = regex.WRAPPED_CONDITION_REGEX.sub(tree_line.text, "").strip_edges()
|
tree_line.text = regex.WRAPPED_CONDITION_REGEX.sub(tree_line.text, "").strip_edges()
|
||||||
|
|
||||||
# Find the original response in this group of responses.
|
# Find the original response in this group of responses.
|
||||||
var original_response: DMTreeLine = tree_line
|
var original_response: DMTreeLine = tree_line
|
||||||
for i in range(sibling_index - 1, 0, -1):
|
for i in range(sibling_index - 1, -1, -1):
|
||||||
if siblings[i].type == DMConstants.TYPE_RESPONSE:
|
if siblings[i].type == DMConstants.TYPE_RESPONSE:
|
||||||
original_response = siblings[i]
|
original_response = siblings[i]
|
||||||
elif siblings[i].type != DMConstants.TYPE_UNKNOWN:
|
elif siblings[i].type != DMConstants.TYPE_UNKNOWN:
|
||||||
@@ -690,14 +700,32 @@ func parse_dialogue_line(tree_line: DMTreeLine, line: DMCompiledLine, siblings:
|
|||||||
for i in range(0, tree_line.children.size()):
|
for i in range(0, tree_line.children.size()):
|
||||||
var child: DMTreeLine = tree_line.children[i]
|
var child: DMTreeLine = tree_line.children[i]
|
||||||
if child.type == DMConstants.TYPE_DIALOGUE:
|
if child.type == DMConstants.TYPE_DIALOGUE:
|
||||||
|
# Nested dialogue lines cannot have further nested dialogue.
|
||||||
|
if child.children.size() > 0:
|
||||||
|
add_error(child.children[0].line_number, child.children[0].indent, DMConstants.ERR_INVALID_INDENTATION)
|
||||||
|
# Mark this as a dialogue child of another dialogue line.
|
||||||
|
child.is_nested_dialogue = true
|
||||||
|
var child_line = DMCompiledLine.new("", DMConstants.TYPE_DIALOGUE)
|
||||||
|
parse_character_and_dialogue(child, child_line, [], 0, parent)
|
||||||
|
var child_static_line_id: String = extract_static_line_id(child.text)
|
||||||
|
if child_line.character != "" or child_static_line_id != "":
|
||||||
|
add_error(child.line_number, child.indent, DMConstants.ERR_UNEXPECTED_SYNTAX_ON_NESTED_DIALOGUE_LINE)
|
||||||
|
# Check that only the last child (or none) has a jump reference
|
||||||
|
if i < tree_line.children.size() - 1 and " =>" in child.text:
|
||||||
|
add_error(child.line_number, child.indent, DMConstants.ERR_NESTED_DIALOGUE_INVALID_JUMP)
|
||||||
|
if i == 0 and " =>" in tree_line.text:
|
||||||
|
add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_NESTED_DIALOGUE_INVALID_JUMP)
|
||||||
|
|
||||||
tree_line.text += "\n" + child.text
|
tree_line.text += "\n" + child.text
|
||||||
|
elif child.type == DMConstants.TYPE_UNKNOWN:
|
||||||
|
tree_line.text += "\n"
|
||||||
else:
|
else:
|
||||||
result = add_error(child.line_number, child.indent, DMConstants.ERR_INVALID_INDENTATION)
|
result = add_error(child.line_number, child.indent, DMConstants.ERR_INVALID_INDENTATION)
|
||||||
|
|
||||||
# Extract the static line ID
|
# Extract the static line ID
|
||||||
var static_line_id: String = extract_static_line_id(tree_line.text)
|
var static_line_id: String = extract_static_line_id(tree_line.text)
|
||||||
if static_line_id:
|
if static_line_id:
|
||||||
tree_line.text = tree_line.text.replace("[ID:%s]" % [static_line_id], "")
|
tree_line.text = tree_line.text.replace(" [ID:", "[ID:").replace("[ID:%s]" % [static_line_id], "")
|
||||||
line.translation_key = static_line_id
|
line.translation_key = static_line_id
|
||||||
|
|
||||||
# Check for simultaneous lines
|
# Check for simultaneous lines
|
||||||
@@ -730,7 +758,7 @@ func parse_dialogue_line(tree_line: DMTreeLine, line: DMCompiledLine, siblings:
|
|||||||
if expression.size() == 0:
|
if expression.size() == 0:
|
||||||
add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_INVALID_EXPRESSION)
|
add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_INVALID_EXPRESSION)
|
||||||
elif expression[0].type == DMConstants.TYPE_ERROR:
|
elif expression[0].type == DMConstants.TYPE_ERROR:
|
||||||
add_error(tree_line.line_number, tree_line.indent + expression[0].index, expression[0].value)
|
add_error(tree_line.line_number, tree_line.indent + expression[0].i, expression[0].value)
|
||||||
|
|
||||||
# If the line isn't part of a weighted random group then make it point to the next
|
# If the line isn't part of a weighted random group then make it point to the next
|
||||||
# available sibling.
|
# available sibling.
|
||||||
@@ -817,8 +845,13 @@ func parse_character_and_dialogue(tree_line: DMTreeLine, line: DMCompiledLine, s
|
|||||||
# Replace any newlines.
|
# Replace any newlines.
|
||||||
text = text.replace("\\n", "\n").strip_edges()
|
text = text.replace("\\n", "\n").strip_edges()
|
||||||
|
|
||||||
# If there was no manual translation key then just use the text itself
|
# If there was no manual translation key then just use the text itself (unless this is a
|
||||||
if line.translation_key == "":
|
# child dialogue below another dialogue line).
|
||||||
|
if not tree_line.is_nested_dialogue and line.translation_key == "":
|
||||||
|
# Show an error if missing translations is enabled
|
||||||
|
if DMSettings.get_setting(DMSettings.MISSING_TRANSLATIONS_ARE_ERRORS, false):
|
||||||
|
result = add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_MISSING_ID)
|
||||||
|
else:
|
||||||
line.translation_key = text
|
line.translation_key = text
|
||||||
|
|
||||||
line.text = text
|
line.text = text
|
||||||
@@ -829,9 +862,6 @@ func parse_character_and_dialogue(tree_line: DMTreeLine, line: DMCompiledLine, s
|
|||||||
result = add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_DUPLICATE_ID)
|
result = add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_DUPLICATE_ID)
|
||||||
else:
|
else:
|
||||||
_known_translation_keys[line.translation_key] = line.text
|
_known_translation_keys[line.translation_key] = line.text
|
||||||
# Show an error if missing translations is enabled
|
|
||||||
elif DMSettings.get_setting(DMSettings.MISSING_TRANSLATIONS_ARE_ERRORS, false):
|
|
||||||
result = add_error(tree_line.line_number, tree_line.indent, DMConstants.ERR_MISSING_ID)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -1009,7 +1039,7 @@ func extract_condition(text: String, is_wrapped: bool, index: int) -> Dictionary
|
|||||||
}
|
}
|
||||||
elif expression[0].type == DMConstants.TYPE_ERROR:
|
elif expression[0].type == DMConstants.TYPE_ERROR:
|
||||||
return {
|
return {
|
||||||
index = expression[0].index,
|
index = expression[0].i,
|
||||||
error = expression[0].value
|
error = expression[0].value
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
@@ -1037,7 +1067,7 @@ func extract_mutation(text: String) -> Dictionary:
|
|||||||
}
|
}
|
||||||
elif expression[0].type == DMConstants.TYPE_ERROR:
|
elif expression[0].type == DMConstants.TYPE_ERROR:
|
||||||
return {
|
return {
|
||||||
index = expression[0].index,
|
index = expression[0].i,
|
||||||
error = expression[0].value
|
error = expression[0].value
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ var concurrent_lines: PackedStringArray = []
|
|||||||
var tags: PackedStringArray = []
|
var tags: PackedStringArray = []
|
||||||
## The condition or mutation expression for this line.
|
## The condition or mutation expression for this line.
|
||||||
var expression: Dictionary = {}
|
var expression: Dictionary = {}
|
||||||
|
## The express as the raw text that was given.
|
||||||
|
var expression_text: String = ""
|
||||||
## The next sequential line to go to after this line.
|
## The next sequential line to go to after this line.
|
||||||
var next_id: String = ""
|
var next_id: String = ""
|
||||||
## The next line to go to after this line if it is unknown and compile time.
|
## The next line to go to after this line if it is unknown and compile time.
|
||||||
@@ -129,6 +131,8 @@ func to_data() -> Dictionary:
|
|||||||
d.tags = tags
|
d.tags = tags
|
||||||
if not notes.is_empty():
|
if not notes.is_empty():
|
||||||
d.notes = notes
|
d.notes = notes
|
||||||
|
if not expression_text.is_empty():
|
||||||
|
d.condition_as_text = expression_text
|
||||||
|
|
||||||
DMConstants.TYPE_DIALOGUE:
|
DMConstants.TYPE_DIALOGUE:
|
||||||
d.text = text
|
d.text = text
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ var TOKEN_DEFINITIONS: Dictionary = {
|
|||||||
DMConstants.TOKEN_NUMBER: RegEx.create_from_string("^\\-?\\d+(\\.\\d+)?"),
|
DMConstants.TOKEN_NUMBER: RegEx.create_from_string("^\\-?\\d+(\\.\\d+)?"),
|
||||||
DMConstants.TOKEN_OPERATOR: RegEx.create_from_string("^(\\+|\\-|\\*|/|%)"),
|
DMConstants.TOKEN_OPERATOR: RegEx.create_from_string("^(\\+|\\-|\\*|/|%)"),
|
||||||
DMConstants.TOKEN_COMMA: RegEx.create_from_string("^,"),
|
DMConstants.TOKEN_COMMA: RegEx.create_from_string("^,"),
|
||||||
|
DMConstants.TOKEN_NULL_COALESCE: RegEx.create_from_string("^\\?\\."),
|
||||||
DMConstants.TOKEN_DOT: RegEx.create_from_string("^\\."),
|
DMConstants.TOKEN_DOT: RegEx.create_from_string("^\\."),
|
||||||
DMConstants.TOKEN_STRING: RegEx.create_from_string("^&?(\".*?\"|\'.*?\')"),
|
DMConstants.TOKEN_STRING: RegEx.create_from_string("^&?(\".*?\"|\'.*?\')"),
|
||||||
DMConstants.TOKEN_NOT: RegEx.create_from_string("^(not( |$)|!)"),
|
DMConstants.TOKEN_NOT: RegEx.create_from_string("^(not( |$)|!)"),
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
class_name DMExpressionParser extends RefCounted
|
class_name DMExpressionParser extends RefCounted
|
||||||
|
|
||||||
|
|
||||||
|
var include_comments: bool = false
|
||||||
|
|
||||||
|
|
||||||
# Reference to the common [RegEx] that the parser needs.
|
# Reference to the common [RegEx] that the parser needs.
|
||||||
var regex: DMCompilerRegEx = DMCompilerRegEx.new()
|
var regex: DMCompilerRegEx = DMCompilerRegEx.new()
|
||||||
|
|
||||||
@@ -25,7 +28,7 @@ func tokenise(text: String, line_type: String, index: int) -> Array:
|
|||||||
index += 1
|
index += 1
|
||||||
text = text.substr(1)
|
text = text.substr(1)
|
||||||
else:
|
else:
|
||||||
return _build_token_tree_error(DMConstants.ERR_INVALID_EXPRESSION, index)
|
return _build_token_tree_error([], DMConstants.ERR_INVALID_EXPRESSION, index)
|
||||||
|
|
||||||
return _build_token_tree(tokens, line_type, "")[0]
|
return _build_token_tree(tokens, line_type, "")[0]
|
||||||
|
|
||||||
@@ -59,7 +62,7 @@ func extract_replacements(text: String, index: int) -> Array[Dictionary]:
|
|||||||
}
|
}
|
||||||
elif expression[0].type == DMConstants.TYPE_ERROR:
|
elif expression[0].type == DMConstants.TYPE_ERROR:
|
||||||
replacement = {
|
replacement = {
|
||||||
index = expression[0].index,
|
index = expression[0].i,
|
||||||
error = expression[0].value
|
error = expression[0].value
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
@@ -76,8 +79,13 @@ func extract_replacements(text: String, index: int) -> Array[Dictionary]:
|
|||||||
|
|
||||||
|
|
||||||
# Create a token that represents an error.
|
# Create a token that represents an error.
|
||||||
func _build_token_tree_error(error: int, index: int) -> Array:
|
func _build_token_tree_error(tree: Array, error: int, index: int) -> Array:
|
||||||
return [{ type = DMConstants.TOKEN_ERROR, value = error, index = index }]
|
tree.insert(0, {
|
||||||
|
type = DMConstants.TOKEN_ERROR,
|
||||||
|
value = error,
|
||||||
|
i = index
|
||||||
|
})
|
||||||
|
return tree
|
||||||
|
|
||||||
|
|
||||||
# Convert a list of tokens into an abstract syntax tree.
|
# Convert a list of tokens into an abstract syntax tree.
|
||||||
@@ -91,14 +99,22 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
var error = _check_next_token(token, tokens, line_type, expected_close_token)
|
var error = _check_next_token(token, tokens, line_type, expected_close_token)
|
||||||
if error != OK:
|
if error != OK:
|
||||||
var error_token: Dictionary = tokens[1] if tokens.size() > 1 else token
|
var error_token: Dictionary = tokens[1] if tokens.size() > 1 else token
|
||||||
return [_build_token_tree_error(error, error_token.index), tokens]
|
return [_build_token_tree_error(tree, error, error_token.index), tokens]
|
||||||
|
|
||||||
match token.type:
|
match token.type:
|
||||||
|
DMConstants.TOKEN_COMMENT:
|
||||||
|
if include_comments:
|
||||||
|
tree.append({
|
||||||
|
type = DMConstants.TOKEN_COMMENT,
|
||||||
|
value = token.value,
|
||||||
|
i = token.index
|
||||||
|
})
|
||||||
|
|
||||||
DMConstants.TOKEN_FUNCTION:
|
DMConstants.TOKEN_FUNCTION:
|
||||||
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_PARENS_CLOSE)
|
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_PARENS_CLOSE)
|
||||||
|
|
||||||
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
||||||
return [_build_token_tree_error(sub_tree[0][0].value, sub_tree[0][0].index), tokens]
|
return [_build_token_tree_error(tree, sub_tree[0][0].value, sub_tree[0][0].i), tokens]
|
||||||
|
|
||||||
tree.append({
|
tree.append({
|
||||||
type = DMConstants.TOKEN_FUNCTION,
|
type = DMConstants.TOKEN_FUNCTION,
|
||||||
@@ -113,11 +129,11 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_BRACKET_CLOSE)
|
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_BRACKET_CLOSE)
|
||||||
|
|
||||||
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
||||||
return [_build_token_tree_error(sub_tree[0][0].value, sub_tree[0][0].index), tokens]
|
return [_build_token_tree_error(tree, sub_tree[0][0].value, sub_tree[0][0].i), tokens]
|
||||||
|
|
||||||
var args = _tokens_to_list(sub_tree[0])
|
var args = _tokens_to_list(sub_tree[0])
|
||||||
if args.size() != 1:
|
if args.size() != 1:
|
||||||
return [_build_token_tree_error(DMConstants.ERR_INVALID_INDEX, token.index), tokens]
|
return [_build_token_tree_error(tree, DMConstants.ERR_INVALID_INDEX, token.index), tokens]
|
||||||
|
|
||||||
tree.append({
|
tree.append({
|
||||||
type = DMConstants.TOKEN_DICTIONARY_REFERENCE,
|
type = DMConstants.TOKEN_DICTIONARY_REFERENCE,
|
||||||
@@ -132,7 +148,7 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_BRACE_CLOSE)
|
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_BRACE_CLOSE)
|
||||||
|
|
||||||
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
||||||
return [_build_token_tree_error(sub_tree[0][0].value, sub_tree[0][0].index), tokens]
|
return [_build_token_tree_error(tree, sub_tree[0][0].value, sub_tree[0][0].i), tokens]
|
||||||
|
|
||||||
var t = sub_tree[0]
|
var t = sub_tree[0]
|
||||||
for i in range(0, t.size() - 2):
|
for i in range(0, t.size() - 2):
|
||||||
@@ -154,7 +170,7 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_BRACKET_CLOSE)
|
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_BRACKET_CLOSE)
|
||||||
|
|
||||||
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
||||||
return [_build_token_tree_error(sub_tree[0][0].value, sub_tree[0][0].index), tokens]
|
return [_build_token_tree_error(tree, sub_tree[0][0].value, sub_tree[0][0].i), tokens]
|
||||||
|
|
||||||
var type = DMConstants.TOKEN_ARRAY
|
var type = DMConstants.TOKEN_ARRAY
|
||||||
var value = _tokens_to_list(sub_tree[0])
|
var value = _tokens_to_list(sub_tree[0])
|
||||||
@@ -177,7 +193,7 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_PARENS_CLOSE)
|
var sub_tree = _build_token_tree(tokens, line_type, DMConstants.TOKEN_PARENS_CLOSE)
|
||||||
|
|
||||||
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
if sub_tree[0].size() > 0 and sub_tree[0][0].type == DMConstants.TOKEN_ERROR:
|
||||||
return [_build_token_tree_error(sub_tree[0][0].value, sub_tree[0][0].index), tokens]
|
return [_build_token_tree_error(tree, sub_tree[0][0].value, sub_tree[0][0].i), tokens]
|
||||||
|
|
||||||
tree.append({
|
tree.append({
|
||||||
type = DMConstants.TOKEN_GROUP,
|
type = DMConstants.TOKEN_GROUP,
|
||||||
@@ -190,7 +206,7 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
DMConstants.TOKEN_BRACE_CLOSE, \
|
DMConstants.TOKEN_BRACE_CLOSE, \
|
||||||
DMConstants.TOKEN_BRACKET_CLOSE:
|
DMConstants.TOKEN_BRACKET_CLOSE:
|
||||||
if token.type != expected_close_token:
|
if token.type != expected_close_token:
|
||||||
return [_build_token_tree_error(DMConstants.ERR_UNEXPECTED_CLOSING_BRACKET, token.index), tokens]
|
return [_build_token_tree_error(tree, DMConstants.ERR_UNEXPECTED_CLOSING_BRACKET, token.index), tokens]
|
||||||
|
|
||||||
tree.append({
|
tree.append({
|
||||||
type = token.type,
|
type = token.type,
|
||||||
@@ -211,7 +227,8 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
|
|
||||||
DMConstants.TOKEN_COMMA, \
|
DMConstants.TOKEN_COMMA, \
|
||||||
DMConstants.TOKEN_COLON, \
|
DMConstants.TOKEN_COLON, \
|
||||||
DMConstants.TOKEN_DOT:
|
DMConstants.TOKEN_DOT, \
|
||||||
|
DMConstants.TOKEN_NULL_COALESCE:
|
||||||
tree.append({
|
tree.append({
|
||||||
type = token.type,
|
type = token.type,
|
||||||
i = token.index
|
i = token.index
|
||||||
@@ -248,7 +265,7 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
})
|
})
|
||||||
|
|
||||||
DMConstants.TOKEN_CONDITION:
|
DMConstants.TOKEN_CONDITION:
|
||||||
return [_build_token_tree_error(DMConstants.ERR_UNEXPECTED_CONDITION, token.index), token]
|
return [_build_token_tree_error(tree, DMConstants.ERR_UNEXPECTED_CONDITION, token.index), token]
|
||||||
|
|
||||||
DMConstants.TOKEN_BOOL:
|
DMConstants.TOKEN_BOOL:
|
||||||
tree.append({
|
tree.append({
|
||||||
@@ -280,8 +297,8 @@ func _build_token_tree(tokens: Array[Dictionary], line_type: String, expected_cl
|
|||||||
})
|
})
|
||||||
|
|
||||||
if expected_close_token != "":
|
if expected_close_token != "":
|
||||||
var index: int = tokens[0].index if tokens.size() > 0 else 0
|
var index: int = tokens[0].i if tokens.size() > 0 else 0
|
||||||
return [_build_token_tree_error(DMConstants.ERR_MISSING_CLOSING_BRACKET, index), tokens]
|
return [_build_token_tree_error(tree, DMConstants.ERR_MISSING_CLOSING_BRACKET, index), tokens]
|
||||||
|
|
||||||
return [tree, tokens]
|
return [tree, tokens]
|
||||||
|
|
||||||
@@ -347,8 +364,8 @@ func _check_next_token(token: Dictionary, next_tokens: Array[Dictionary], line_t
|
|||||||
|
|
||||||
DMConstants.TOKEN_COMPARISON, \
|
DMConstants.TOKEN_COMPARISON, \
|
||||||
DMConstants.TOKEN_OPERATOR, \
|
DMConstants.TOKEN_OPERATOR, \
|
||||||
DMConstants.TOKEN_COMMA, \
|
|
||||||
DMConstants.TOKEN_DOT, \
|
DMConstants.TOKEN_DOT, \
|
||||||
|
DMConstants.TOKEN_NULL_COALESCE, \
|
||||||
DMConstants.TOKEN_NOT, \
|
DMConstants.TOKEN_NOT, \
|
||||||
DMConstants.TOKEN_AND_OR, \
|
DMConstants.TOKEN_AND_OR, \
|
||||||
DMConstants.TOKEN_DICTIONARY_REFERENCE:
|
DMConstants.TOKEN_DICTIONARY_REFERENCE:
|
||||||
@@ -366,6 +383,20 @@ func _check_next_token(token: Dictionary, next_tokens: Array[Dictionary], line_t
|
|||||||
DMConstants.TOKEN_DOT
|
DMConstants.TOKEN_DOT
|
||||||
]
|
]
|
||||||
|
|
||||||
|
DMConstants.TOKEN_COMMA:
|
||||||
|
unexpected_token_types = [
|
||||||
|
null,
|
||||||
|
DMConstants.TOKEN_COMMA,
|
||||||
|
DMConstants.TOKEN_COLON,
|
||||||
|
DMConstants.TOKEN_ASSIGNMENT,
|
||||||
|
DMConstants.TOKEN_OPERATOR,
|
||||||
|
DMConstants.TOKEN_AND_OR,
|
||||||
|
DMConstants.TOKEN_PARENS_CLOSE,
|
||||||
|
DMConstants.TOKEN_BRACE_CLOSE,
|
||||||
|
DMConstants.TOKEN_BRACKET_CLOSE,
|
||||||
|
DMConstants.TOKEN_DOT
|
||||||
|
]
|
||||||
|
|
||||||
DMConstants.TOKEN_COLON:
|
DMConstants.TOKEN_COLON:
|
||||||
unexpected_token_types = [
|
unexpected_token_types = [
|
||||||
DMConstants.TOKEN_COMMA,
|
DMConstants.TOKEN_COMMA,
|
||||||
@@ -409,7 +440,8 @@ func _check_next_token(token: Dictionary, next_tokens: Array[Dictionary], line_t
|
|||||||
DMConstants.TOKEN_BRACKET_OPEN
|
DMConstants.TOKEN_BRACKET_OPEN
|
||||||
]
|
]
|
||||||
|
|
||||||
if (expected_token_types.size() > 0 and not next_token.type in expected_token_types or unexpected_token_types.size() > 0 and next_token.type in unexpected_token_types):
|
if (expected_token_types.size() > 0 and not next_token.type in expected_token_types) \
|
||||||
|
or (unexpected_token_types.size() > 0 and next_token.type in unexpected_token_types):
|
||||||
match next_token.type:
|
match next_token.type:
|
||||||
null:
|
null:
|
||||||
return DMConstants.ERR_UNEXPECTED_END_OF_EXPRESSION
|
return DMConstants.ERR_UNEXPECTED_END_OF_EXPRESSION
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ var text: String = ""
|
|||||||
var children: Array[DMTreeLine] = []
|
var children: Array[DMTreeLine] = []
|
||||||
## Any doc comments attached to this line.
|
## Any doc comments attached to this line.
|
||||||
var notes: String = ""
|
var notes: String = ""
|
||||||
|
## Is this a dialogue line that is the child of another dialogue line?
|
||||||
|
var is_nested_dialogue: bool = false
|
||||||
|
|
||||||
|
|
||||||
func _init(initial_id: String) -> void:
|
func _init(initial_id: String) -> void:
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ var font_size: int:
|
|||||||
|
|
||||||
var WEIGHTED_RANDOM_PREFIX: RegEx = RegEx.create_from_string("^\\%[\\d.]+\\s")
|
var WEIGHTED_RANDOM_PREFIX: RegEx = RegEx.create_from_string("^\\%[\\d.]+\\s")
|
||||||
|
|
||||||
|
var compiler_regex: DMCompilerRegEx = DMCompilerRegEx.new()
|
||||||
|
var _autoloads: Dictionary[String, String] = {}
|
||||||
|
var _autoload_member_cache: Dictionary[String, Dictionary] = {}
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# Add error gutter
|
# Add error gutter
|
||||||
@@ -65,6 +69,10 @@ func _ready() -> void:
|
|||||||
|
|
||||||
syntax_highlighter = DMSyntaxHighlighter.new()
|
syntax_highlighter = DMSyntaxHighlighter.new()
|
||||||
|
|
||||||
|
# Keep track of any autoloads
|
||||||
|
ProjectSettings.settings_changed.connect(_on_project_settings_changed)
|
||||||
|
_on_project_settings_changed()
|
||||||
|
|
||||||
|
|
||||||
func _gui_input(event: InputEvent) -> void:
|
func _gui_input(event: InputEvent) -> void:
|
||||||
# Handle shortcuts that come from the editor
|
# Handle shortcuts that come from the editor
|
||||||
@@ -141,6 +149,7 @@ func _request_code_completion(force: bool) -> void:
|
|||||||
var cursor: Vector2 = get_cursor()
|
var cursor: Vector2 = get_cursor()
|
||||||
var current_line: String = get_line(cursor.y)
|
var current_line: String = get_line(cursor.y)
|
||||||
|
|
||||||
|
# Match jumps
|
||||||
if ("=> " in current_line or "=>< " in current_line) and (cursor.x > current_line.find("=>")):
|
if ("=> " in current_line or "=>< " in current_line) and (cursor.x > current_line.find("=>")):
|
||||||
var prompt: String = current_line.split("=>")[1]
|
var prompt: String = current_line.split("=>")[1]
|
||||||
if prompt.begins_with("< "):
|
if prompt.begins_with("< "):
|
||||||
@@ -166,9 +175,8 @@ func _request_code_completion(force: bool) -> void:
|
|||||||
add_code_completion_option(CodeEdit.KIND_CLASS, title, title.substr(prompt.length()), theme_overrides.text_color, get_theme_icon("CombineLines", "EditorIcons"))
|
add_code_completion_option(CodeEdit.KIND_CLASS, title, title.substr(prompt.length()), theme_overrides.text_color, get_theme_icon("CombineLines", "EditorIcons"))
|
||||||
elif matches_prompt(prompt, title):
|
elif matches_prompt(prompt, title):
|
||||||
add_code_completion_option(CodeEdit.KIND_CLASS, title, title.substr(prompt.length()), theme_overrides.text_color, get_theme_icon("ArrowRight", "EditorIcons"))
|
add_code_completion_option(CodeEdit.KIND_CLASS, title, title.substr(prompt.length()), theme_overrides.text_color, get_theme_icon("ArrowRight", "EditorIcons"))
|
||||||
update_code_completion_options(true)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
# Match character names
|
||||||
var name_so_far: String = WEIGHTED_RANDOM_PREFIX.sub(current_line.strip_edges(), "")
|
var name_so_far: String = WEIGHTED_RANDOM_PREFIX.sub(current_line.strip_edges(), "")
|
||||||
if name_so_far != "" and name_so_far[0].to_upper() == name_so_far[0]:
|
if name_so_far != "" and name_so_far[0].to_upper() == name_so_far[0]:
|
||||||
# Only show names starting with that character
|
# Only show names starting with that character
|
||||||
@@ -176,8 +184,71 @@ func _request_code_completion(force: bool) -> void:
|
|||||||
if names.size() > 0:
|
if names.size() > 0:
|
||||||
for name in names:
|
for name in names:
|
||||||
add_code_completion_option(CodeEdit.KIND_CLASS, name + ": ", name.substr(name_so_far.length()) + ": ", theme_overrides.text_color, get_theme_icon("Sprite2D", "EditorIcons"))
|
add_code_completion_option(CodeEdit.KIND_CLASS, name + ": ", name.substr(name_so_far.length()) + ": ", theme_overrides.text_color, get_theme_icon("Sprite2D", "EditorIcons"))
|
||||||
|
|
||||||
|
# Match autoloads on mutation lines
|
||||||
|
for prefix in ["do ", "do! ", "set ", "if ", "elif ", "else if ", "match ", "when ", "using "]:
|
||||||
|
if (current_line.strip_edges().begins_with(prefix) and (cursor.x > current_line.find(prefix))):
|
||||||
|
var expression: String = current_line.substr(0, cursor.x).strip_edges().substr(3)
|
||||||
|
# Find the last couple of tokens
|
||||||
|
var possible_prompt: String = expression.reverse()
|
||||||
|
possible_prompt = possible_prompt.substr(0, possible_prompt.find(" "))
|
||||||
|
possible_prompt = possible_prompt.substr(0, possible_prompt.find("("))
|
||||||
|
possible_prompt = possible_prompt.reverse()
|
||||||
|
var segments: PackedStringArray = possible_prompt.split(".").slice(-2)
|
||||||
|
var auto_completes: Array[Dictionary] = []
|
||||||
|
|
||||||
|
# Autoloads and state shortcuts
|
||||||
|
if segments.size() == 1:
|
||||||
|
var prompt: String = segments[0]
|
||||||
|
for autoload in _autoloads.keys():
|
||||||
|
if matches_prompt(prompt, autoload):
|
||||||
|
auto_completes.append({
|
||||||
|
prompt = prompt,
|
||||||
|
text = autoload,
|
||||||
|
type = "script"
|
||||||
|
})
|
||||||
|
for autoload in get_state_shortcuts():
|
||||||
|
for member: Dictionary in get_members_for_autoload(autoload):
|
||||||
|
if matches_prompt(prompt, member.name):
|
||||||
|
auto_completes.append({
|
||||||
|
prompt = prompt,
|
||||||
|
text = member.name,
|
||||||
|
type = member.type
|
||||||
|
})
|
||||||
|
|
||||||
|
# Members of an autoload
|
||||||
|
elif segments[0] in _autoloads.keys() and not current_line.strip_edges().begins_with("using "):
|
||||||
|
var prompt: String = segments[1]
|
||||||
|
for member: Dictionary in get_members_for_autoload(segments[0]):
|
||||||
|
if matches_prompt(prompt, member.name):
|
||||||
|
auto_completes.append({
|
||||||
|
prompt = prompt,
|
||||||
|
text = member.name,
|
||||||
|
type = member.type
|
||||||
|
})
|
||||||
|
|
||||||
|
auto_completes.sort_custom(func(a, b): return a.text < b.text)
|
||||||
|
|
||||||
|
for auto_complete in auto_completes:
|
||||||
|
var icon: Texture2D
|
||||||
|
var text: String = auto_complete.text
|
||||||
|
match auto_complete.type:
|
||||||
|
"script":
|
||||||
|
icon = get_theme_icon("Script", "EditorIcons")
|
||||||
|
"property":
|
||||||
|
icon = get_theme_icon("MemberProperty", "EditorIcons")
|
||||||
|
"method":
|
||||||
|
icon = get_theme_icon("MemberMethod", "EditorIcons")
|
||||||
|
text += "()"
|
||||||
|
"signal":
|
||||||
|
icon = get_theme_icon("MemberSignal", "EditorIcons")
|
||||||
|
"constant":
|
||||||
|
icon = get_theme_icon("MemberConstant", "EditorIcons")
|
||||||
|
var insert: String = text.substr(auto_complete.prompt.length())
|
||||||
|
add_code_completion_option(CodeEdit.KIND_CLASS, text, insert, theme_overrides.text_color, icon)
|
||||||
|
|
||||||
update_code_completion_options(true)
|
update_code_completion_options(true)
|
||||||
else:
|
if get_code_completion_options().size() == 0:
|
||||||
cancel_code_completion()
|
cancel_code_completion()
|
||||||
|
|
||||||
|
|
||||||
@@ -190,17 +261,21 @@ func _confirm_code_completion(replace: bool) -> void:
|
|||||||
var completion = get_code_completion_option(get_code_completion_selected_index())
|
var completion = get_code_completion_option(get_code_completion_selected_index())
|
||||||
begin_complex_operation()
|
begin_complex_operation()
|
||||||
# Delete any part of the text that we've already typed
|
# Delete any part of the text that we've already typed
|
||||||
|
if completion.insert_text.length() > 0:
|
||||||
for i in range(0, completion.display_text.length() - completion.insert_text.length()):
|
for i in range(0, completion.display_text.length() - completion.insert_text.length()):
|
||||||
backspace()
|
backspace()
|
||||||
# Insert the whole match
|
# Insert the whole match
|
||||||
insert_text_at_caret(completion.display_text)
|
insert_text_at_caret(completion.display_text)
|
||||||
end_complex_operation()
|
end_complex_operation()
|
||||||
|
|
||||||
|
if completion.display_text.ends_with("()"):
|
||||||
|
set_cursor(get_cursor() - Vector2.RIGHT)
|
||||||
|
|
||||||
# Close the autocomplete menu on the next tick
|
# Close the autocomplete menu on the next tick
|
||||||
call_deferred("cancel_code_completion")
|
call_deferred("cancel_code_completion")
|
||||||
|
|
||||||
|
|
||||||
### Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
|
||||||
# Get the current caret as a Vector2
|
# Get the current caret as a Vector2
|
||||||
@@ -219,6 +294,69 @@ func matches_prompt(prompt: String, matcher: String) -> bool:
|
|||||||
return prompt.length() < matcher.length() and matcher.to_lower().begins_with(prompt.to_lower())
|
return prompt.length() < matcher.length() and matcher.to_lower().begins_with(prompt.to_lower())
|
||||||
|
|
||||||
|
|
||||||
|
func get_state_shortcuts() -> PackedStringArray:
|
||||||
|
# Get any shortcuts defined in settings
|
||||||
|
var shortcuts: PackedStringArray = DMSettings.get_setting(DMSettings.STATE_AUTOLOAD_SHORTCUTS, [])
|
||||||
|
# Check for "using" clauses
|
||||||
|
for line: String in text.split("\n"):
|
||||||
|
var found: RegExMatch = compiler_regex.USING_REGEX.search(line)
|
||||||
|
if found:
|
||||||
|
shortcuts.append(found.strings[found.names.state])
|
||||||
|
# Check for any other script sources
|
||||||
|
for extra_script_source in DMSettings.get_setting(DMSettings.EXTRA_AUTO_COMPLETE_SCRIPT_SOURCES, []):
|
||||||
|
shortcuts.append(extra_script_source)
|
||||||
|
|
||||||
|
return shortcuts
|
||||||
|
|
||||||
|
|
||||||
|
func get_members_for_autoload(autoload_name: String) -> Array[Dictionary]:
|
||||||
|
# Debounce method list lookups
|
||||||
|
if _autoload_member_cache.has(autoload_name) and _autoload_member_cache.get(autoload_name).get("at") > Time.get_ticks_msec() - 5000:
|
||||||
|
return _autoload_member_cache.get(autoload_name).get("members")
|
||||||
|
|
||||||
|
if not _autoloads.has(autoload_name) and not autoload_name.begins_with("res://") and not autoload_name.begins_with("uid://"): return []
|
||||||
|
|
||||||
|
var autoload = load(_autoloads.get(autoload_name, autoload_name))
|
||||||
|
var script: Script = autoload if autoload is Script else autoload.get_script()
|
||||||
|
|
||||||
|
if not is_instance_valid(script): return []
|
||||||
|
|
||||||
|
var members: Array[Dictionary] = []
|
||||||
|
if script.resource_path.ends_with(".gd"):
|
||||||
|
for m: Dictionary in script.get_script_method_list():
|
||||||
|
if not m.name.begins_with("@"):
|
||||||
|
members.append({
|
||||||
|
name = m.name,
|
||||||
|
type = "method"
|
||||||
|
})
|
||||||
|
for m: Dictionary in script.get_script_property_list():
|
||||||
|
members.append({
|
||||||
|
name = m.name,
|
||||||
|
type = "property"
|
||||||
|
})
|
||||||
|
for m: Dictionary in script.get_script_signal_list():
|
||||||
|
members.append({
|
||||||
|
name = m.name,
|
||||||
|
type = "signal"
|
||||||
|
})
|
||||||
|
for c: String in script.get_script_constant_map():
|
||||||
|
members.append({
|
||||||
|
name = c,
|
||||||
|
type = "constant"
|
||||||
|
})
|
||||||
|
elif script.resource_path.ends_with(".cs"):
|
||||||
|
var dotnet = load(Engine.get_meta("DialogueManagerPlugin").get_plugin_path() + "/DialogueManager.cs").new()
|
||||||
|
for m: Dictionary in dotnet.GetMembersForAutoload(script):
|
||||||
|
members.append(m)
|
||||||
|
|
||||||
|
_autoload_member_cache[autoload_name] = {
|
||||||
|
at = Time.get_ticks_msec(),
|
||||||
|
members = members
|
||||||
|
}
|
||||||
|
|
||||||
|
return members
|
||||||
|
|
||||||
|
|
||||||
## Get a list of titles from the current text
|
## Get a list of titles from the current text
|
||||||
func get_titles() -> PackedStringArray:
|
func get_titles() -> PackedStringArray:
|
||||||
var titles = PackedStringArray([])
|
var titles = PackedStringArray([])
|
||||||
@@ -417,7 +555,18 @@ func move_line(offset: int) -> void:
|
|||||||
scroll_vertical = starting_scroll + offset
|
scroll_vertical = starting_scroll + offset
|
||||||
|
|
||||||
|
|
||||||
### Signals
|
#endregion
|
||||||
|
|
||||||
|
#region Signals
|
||||||
|
|
||||||
|
|
||||||
|
func _on_project_settings_changed() -> void:
|
||||||
|
_autoloads = {}
|
||||||
|
var project = ConfigFile.new()
|
||||||
|
project.load("res://project.godot")
|
||||||
|
for autoload in project.get_section_keys("autoload"):
|
||||||
|
if autoload != "DialogueManager":
|
||||||
|
_autoloads[autoload] = project.get_value("autoload", autoload).substr(1)
|
||||||
|
|
||||||
|
|
||||||
func _on_code_edit_symbol_validate(symbol: String) -> void:
|
func _on_code_edit_symbol_validate(symbol: String) -> void:
|
||||||
@@ -456,3 +605,6 @@ func _on_code_edit_gutter_clicked(line: int, gutter: int) -> void:
|
|||||||
var line_errors = errors.filter(func(error): return error.line_number == line)
|
var line_errors = errors.filter(func(error): return error.line_number == line)
|
||||||
if line_errors.size() > 0:
|
if line_errors.size() > 0:
|
||||||
error_clicked.emit(line)
|
error_clicked.emit(line)
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ func _clear_highlighting_cache() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
||||||
|
expression_parser.include_comments = true
|
||||||
|
|
||||||
var colors: Dictionary = {}
|
var colors: Dictionary = {}
|
||||||
var text_edit: TextEdit = get_text_edit()
|
var text_edit: TextEdit = get_text_edit()
|
||||||
var text: String = text_edit.get_line(line)
|
var text: String = text_edit.get_line(line)
|
||||||
@@ -38,6 +40,7 @@ func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
|||||||
DMConstants.TYPE_IMPORT:
|
DMConstants.TYPE_IMPORT:
|
||||||
colors[index] = { color = theme.conditions_color }
|
colors[index] = { color = theme.conditions_color }
|
||||||
var import: RegExMatch = regex.IMPORT_REGEX.search(text)
|
var import: RegExMatch = regex.IMPORT_REGEX.search(text)
|
||||||
|
if import:
|
||||||
colors[index + import.get_start("path") - 1] = { color = theme.strings_color }
|
colors[index + import.get_start("path") - 1] = { color = theme.strings_color }
|
||||||
colors[index + import.get_end("path") + 1] = { color = theme.conditions_color }
|
colors[index + import.get_end("path") + 1] = { color = theme.conditions_color }
|
||||||
colors[index + import.get_start("prefix")] = { color = theme.text_color }
|
colors[index + import.get_start("prefix")] = { color = theme.text_color }
|
||||||
@@ -53,7 +56,7 @@ func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
|||||||
index = text.find(" ")
|
index = text.find(" ")
|
||||||
if index > -1:
|
if index > -1:
|
||||||
var expression: Array = expression_parser.tokenise(text.substr(index), DMConstants.TYPE_CONDITION, 0)
|
var expression: Array = expression_parser.tokenise(text.substr(index), DMConstants.TYPE_CONDITION, 0)
|
||||||
if expression.size() == 0 or expression[0].type == DMConstants.TYPE_ERROR:
|
if expression.size() == 0:
|
||||||
colors[index] = { color = theme.critical_color }
|
colors[index] = { color = theme.critical_color }
|
||||||
else:
|
else:
|
||||||
_highlight_expression(expression, colors, index)
|
_highlight_expression(expression, colors, index)
|
||||||
@@ -62,7 +65,7 @@ func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
|||||||
colors[0] = { color = theme.mutations_color }
|
colors[0] = { color = theme.mutations_color }
|
||||||
index = text.find(" ")
|
index = text.find(" ")
|
||||||
var expression: Array = expression_parser.tokenise(text.substr(index), DMConstants.TYPE_MUTATION, 0)
|
var expression: Array = expression_parser.tokenise(text.substr(index), DMConstants.TYPE_MUTATION, 0)
|
||||||
if expression.size() == 0 or expression[0].type == DMConstants.TYPE_ERROR:
|
if expression.size() == 0:
|
||||||
colors[index] = { color = theme.critical_color }
|
colors[index] = { color = theme.critical_color }
|
||||||
else:
|
else:
|
||||||
_highlight_expression(expression, colors, index)
|
_highlight_expression(expression, colors, index)
|
||||||
@@ -84,9 +87,13 @@ func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
|||||||
|
|
||||||
var dialogue_text: String = text.substr(index, text.find("=>"))
|
var dialogue_text: String = text.substr(index, text.find("=>"))
|
||||||
|
|
||||||
# Highlight character name
|
# Highlight character name (but ignore ":" within line ID reference)
|
||||||
var split_index: int = dialogue_text.replace("\\:", "??").find(":")
|
var split_index: int = dialogue_text.replace("\\:", "??").find(":")
|
||||||
|
if text.substr(split_index - 3, 3) != "[ID":
|
||||||
colors[index + split_index + 1] = { color = theme.text_color }
|
colors[index + split_index + 1] = { color = theme.text_color }
|
||||||
|
else:
|
||||||
|
# If there's no character name then just highlight the text as dialogue.
|
||||||
|
colors[index] = { color = theme.text_color }
|
||||||
|
|
||||||
# Interpolation
|
# Interpolation
|
||||||
var replacements: Array[RegExMatch] = regex.REPLACEMENTS_REGEX.search_all(dialogue_text)
|
var replacements: Array[RegExMatch] = regex.REPLACEMENTS_REGEX.search_all(dialogue_text)
|
||||||
@@ -155,6 +162,9 @@ func _highlight_expression(tokens: Array, colors: Dictionary, index: int) -> int
|
|||||||
for token: Dictionary in tokens:
|
for token: Dictionary in tokens:
|
||||||
last_index = token.i
|
last_index = token.i
|
||||||
match token.type:
|
match token.type:
|
||||||
|
DMConstants.TOKEN_COMMENT:
|
||||||
|
colors[index + token.i] = { color = theme.comments_color }
|
||||||
|
|
||||||
DMConstants.TOKEN_CONDITION, DMConstants.TOKEN_AND_OR:
|
DMConstants.TOKEN_CONDITION, DMConstants.TOKEN_AND_OR:
|
||||||
colors[index + token.i] = { color = theme.conditions_color }
|
colors[index + token.i] = { color = theme.conditions_color }
|
||||||
|
|
||||||
@@ -164,7 +174,9 @@ func _highlight_expression(tokens: Array, colors: Dictionary, index: int) -> int
|
|||||||
else:
|
else:
|
||||||
colors[index + token.i] = { color = theme.members_color }
|
colors[index + token.i] = { color = theme.members_color }
|
||||||
|
|
||||||
DMConstants.TOKEN_OPERATOR, DMConstants.TOKEN_COLON, DMConstants.TOKEN_COMMA, DMConstants.TOKEN_NUMBER, DMConstants.TOKEN_ASSIGNMENT:
|
DMConstants.TOKEN_OPERATOR, DMConstants.TOKEN_COLON, \
|
||||||
|
DMConstants.TOKEN_COMMA, DMConstants.TOKEN_DOT, DMConstants.TOKEN_NULL_COALESCE, \
|
||||||
|
DMConstants.TOKEN_NUMBER, DMConstants.TOKEN_ASSIGNMENT:
|
||||||
colors[index + token.i] = { color = theme.symbols_color }
|
colors[index + token.i] = { color = theme.symbols_color }
|
||||||
|
|
||||||
DMConstants.TOKEN_STRING:
|
DMConstants.TOKEN_STRING:
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func update_results_view() -> void:
|
|||||||
var matched_word: String = "[bgcolor=" + colors.critical_color.to_html() + "][color=" + colors.text_color.to_html() + "]" + path_result.matched_text + "[/color][/bgcolor]"
|
var matched_word: String = "[bgcolor=" + colors.critical_color.to_html() + "][color=" + colors.text_color.to_html() + "]" + path_result.matched_text + "[/color][/bgcolor]"
|
||||||
highlight = "[s]" + matched_word + "[/s][bgcolor=" + colors.notice_color.to_html() + "][color=" + colors.text_color.to_html() + "]" + replace_input.text + "[/color][/bgcolor]"
|
highlight = "[s]" + matched_word + "[/s][bgcolor=" + colors.notice_color.to_html() + "][color=" + colors.text_color.to_html() + "]" + replace_input.text + "[/color][/bgcolor]"
|
||||||
else:
|
else:
|
||||||
highlight = "[bgcolor=" + colors.symbols_color.to_html() + "][color=" + colors.text_color.to_html() + "]" + path_result.matched_text + "[/color][/bgcolor]"
|
highlight = "[bgcolor=" + colors.notice_color.to_html() + "][color=" + colors.text_color.to_html() + "]" + path_result.matched_text + "[/color][/bgcolor]"
|
||||||
var text: String = path_result.text.substr(0, path_result.index) + highlight + path_result.text.substr(path_result.index + path_result.query.length())
|
var text: String = path_result.text.substr(0, path_result.index) + highlight + path_result.text.substr(path_result.index + path_result.query.length())
|
||||||
result_label.text = "%s: %s" % [str(path_result.line).lpad(4), text]
|
result_label.text = "%s: %s" % [str(path_result.line).lpad(4), text]
|
||||||
result_label.gui_input.connect(func(event):
|
result_label.gui_input.connect(func(event):
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func find_in_line(line: String, text: String, from_index: int = 0) -> int:
|
|||||||
return line.findn(text, from_index)
|
return line.findn(text, from_index)
|
||||||
|
|
||||||
|
|
||||||
### Signals
|
#region Signals
|
||||||
|
|
||||||
|
|
||||||
func _on_text_edit_gui_input(event: InputEvent) -> void:
|
func _on_text_edit_gui_input(event: InputEvent) -> void:
|
||||||
@@ -177,14 +177,17 @@ func _on_replace_button_pressed() -> void:
|
|||||||
|
|
||||||
# Replace the selection at result index
|
# Replace the selection at result index
|
||||||
var r: Array = results[result_index]
|
var r: Array = results[result_index]
|
||||||
|
code_edit.begin_complex_operation()
|
||||||
var lines: PackedStringArray = code_edit.text.split("\n")
|
var lines: PackedStringArray = code_edit.text.split("\n")
|
||||||
var line: String = lines[r[0]]
|
var line: String = lines[r[0]]
|
||||||
line = line.substr(0, r[1]) + replace_input.text + line.substr(r[1] + r[2])
|
line = line.substr(0, r[1]) + replace_input.text + line.substr(r[1] + r[2])
|
||||||
lines[r[0]] = line
|
lines[r[0]] = line
|
||||||
code_edit.text = "\n".join(lines)
|
code_edit.text = "\n".join(lines)
|
||||||
search(input.text, result_index)
|
code_edit.end_complex_operation()
|
||||||
code_edit.text_changed.emit()
|
code_edit.text_changed.emit()
|
||||||
|
|
||||||
|
search(input.text, result_index)
|
||||||
|
|
||||||
|
|
||||||
func _on_replace_all_button_pressed() -> void:
|
func _on_replace_all_button_pressed() -> void:
|
||||||
if match_case_button.button_pressed:
|
if match_case_button.button_pressed:
|
||||||
@@ -210,3 +213,6 @@ func _on_input_focus_entered() -> void:
|
|||||||
|
|
||||||
func _on_match_case_check_box_toggled(button_pressed: bool) -> void:
|
func _on_match_case_check_box_toggled(button_pressed: bool) -> void:
|
||||||
search()
|
search()
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const TOKEN_COMPARISON = &"comparison"
|
|||||||
const TOKEN_ASSIGNMENT = &"assignment"
|
const TOKEN_ASSIGNMENT = &"assignment"
|
||||||
const TOKEN_OPERATOR = &"operator"
|
const TOKEN_OPERATOR = &"operator"
|
||||||
const TOKEN_COMMA = &"comma"
|
const TOKEN_COMMA = &"comma"
|
||||||
|
const TOKEN_NULL_COALESCE = &"null_coalesce"
|
||||||
const TOKEN_DOT = &"dot"
|
const TOKEN_DOT = &"dot"
|
||||||
const TOKEN_CONDITION = &"condition"
|
const TOKEN_CONDITION = &"condition"
|
||||||
const TOKEN_BOOL = &"bool"
|
const TOKEN_BOOL = &"bool"
|
||||||
@@ -119,6 +120,12 @@ const ERR_ONLY_ONE_ELSE_ALLOWED = 137
|
|||||||
const ERR_WHEN_MUST_BELONG_TO_MATCH = 138
|
const ERR_WHEN_MUST_BELONG_TO_MATCH = 138
|
||||||
const ERR_CONCURRENT_LINE_WITHOUT_ORIGIN = 139
|
const ERR_CONCURRENT_LINE_WITHOUT_ORIGIN = 139
|
||||||
const ERR_GOTO_NOT_ALLOWED_ON_CONCURRECT_LINES = 140
|
const ERR_GOTO_NOT_ALLOWED_ON_CONCURRECT_LINES = 140
|
||||||
|
const ERR_UNEXPECTED_SYNTAX_ON_NESTED_DIALOGUE_LINE = 141
|
||||||
|
const ERR_NESTED_DIALOGUE_INVALID_JUMP = 142
|
||||||
|
|
||||||
|
|
||||||
|
static var _current_locale: String = ""
|
||||||
|
static var _current_translation: Translation
|
||||||
|
|
||||||
|
|
||||||
## Get the error message
|
## Get the error message
|
||||||
@@ -204,16 +211,21 @@ static func get_error_message(error: int) -> String:
|
|||||||
return translate(&"errors.concurrent_line_without_origin")
|
return translate(&"errors.concurrent_line_without_origin")
|
||||||
ERR_GOTO_NOT_ALLOWED_ON_CONCURRECT_LINES:
|
ERR_GOTO_NOT_ALLOWED_ON_CONCURRECT_LINES:
|
||||||
return translate(&"errors.goto_not_allowed_on_concurrect_lines")
|
return translate(&"errors.goto_not_allowed_on_concurrect_lines")
|
||||||
|
ERR_UNEXPECTED_SYNTAX_ON_NESTED_DIALOGUE_LINE:
|
||||||
|
return translate(&"errors.unexpected_syntax_on_nested_dialogue_line")
|
||||||
|
ERR_NESTED_DIALOGUE_INVALID_JUMP:
|
||||||
|
return translate(&"errors.err_nested_dialogue_invalid_jump")
|
||||||
|
|
||||||
return translate(&"errors.unknown")
|
return translate(&"errors.unknown")
|
||||||
|
|
||||||
|
|
||||||
static func translate(string: String) -> String:
|
static func translate(string: String) -> String:
|
||||||
var base_path = new().get_script().resource_path.get_base_dir()
|
var locale: String = TranslationServer.get_tool_locale()
|
||||||
|
if _current_translation == null or _current_locale != locale:
|
||||||
var language: String = TranslationServer.get_tool_locale()
|
var base_path: String = new().get_script().resource_path.get_base_dir()
|
||||||
var translations_path: String = "%s/l10n/%s.po" % [base_path, language]
|
var translation_path: String = "%s/l10n/%s.po" % [base_path, locale]
|
||||||
var fallback_translations_path: String = "%s/l10n/%s.po" % [base_path, TranslationServer.get_tool_locale().substr(0, 2)]
|
var fallback_translation_path: String = "%s/l10n/%s.po" % [base_path, locale.substr(0, 2)]
|
||||||
var en_translations_path: String = "%s/l10n/en.po" % base_path
|
var en_translation_path: String = "%s/l10n/en.po" % base_path
|
||||||
var translations: Translation = load(translations_path if FileAccess.file_exists(translations_path) else (fallback_translations_path if FileAccess.file_exists(fallback_translations_path) else en_translations_path))
|
_current_translation = load(translation_path if FileAccess.file_exists(translation_path) else (fallback_translation_path if FileAccess.file_exists(fallback_translation_path) else en_translation_path))
|
||||||
return translations.get_message(string)
|
_current_locale = locale
|
||||||
|
return _current_translation.get_message(string)
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ var _method_info_cache: Dictionary = {}
|
|||||||
|
|
||||||
var _dotnet_dialogue_manager: RefCounted
|
var _dotnet_dialogue_manager: RefCounted
|
||||||
|
|
||||||
|
var _expression_parser: DMExpressionParser = DMExpressionParser.new()
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# Cache the known Node2D properties
|
# Cache the known Node2D properties
|
||||||
@@ -185,6 +187,7 @@ func get_line(resource: DialogueResource, key: String, extra_game_states: Array)
|
|||||||
continue
|
continue
|
||||||
elif await _check_case_value(value, case, extra_game_states):
|
elif await _check_case_value(value, case, extra_game_states):
|
||||||
next_id = case.next_id
|
next_id = case.next_id
|
||||||
|
break
|
||||||
# Nothing matched so check for else case
|
# Nothing matched so check for else case
|
||||||
if next_id == "":
|
if next_id == "":
|
||||||
if not else_case.is_empty():
|
if not else_case.is_empty():
|
||||||
@@ -206,16 +209,6 @@ func get_line(resource: DialogueResource, key: String, extra_game_states: Array)
|
|||||||
else:
|
else:
|
||||||
cummulative_weight += sibling.weight
|
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 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.type in [DMConstants.TYPE_COMMENT, DMConstants.TYPE_UNKNOWN]:
|
||||||
if data.next_id in [DMConstants.ID_END, DMConstants.ID_NULL, null]:
|
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.
|
# Set up a line object.
|
||||||
var line: DialogueLine = await create_dialogue_line(data, extra_game_states)
|
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 the jump point somehow has no content then just end.
|
||||||
if not line: return null
|
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 we are the first of a list of responses then get the other ones.
|
||||||
if data.type == DMConstants.TYPE_RESPONSE:
|
if data.type == DMConstants.TYPE_RESPONSE:
|
||||||
# Note: For some reason C# has occasional issues with using the responses property directly
|
# 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)
|
var text: String = translate(data)
|
||||||
|
|
||||||
# Resolve variables
|
# 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 value = await _resolve(replacement.expression.duplicate(true), extra_game_states)
|
||||||
var index: int = text.find(replacement.value_in_text)
|
var index: int = text.find(replacement.value_in_text)
|
||||||
if index == -1:
|
if index == -1:
|
||||||
@@ -442,6 +450,18 @@ func show_dialogue_balloon_scene(balloon_scene, resource: DialogueResource, titl
|
|||||||
return balloon
|
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.
|
# Call "start" on the given balloon.
|
||||||
func _start_balloon(balloon: Node, resource: DialogueResource, title: String, extra_game_states: Array) -> void:
|
func _start_balloon(balloon: Node, resource: DialogueResource, title: String, extra_game_states: Array) -> void:
|
||||||
get_current_scene.call().add_child(balloon)
|
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
|
# Translate a string
|
||||||
func translate(data: Dictionary) -> 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
|
return data.text
|
||||||
|
|
||||||
var translation_key: String = data.get(&"translation_key", 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,
|
type = DMConstants.TYPE_RESPONSE,
|
||||||
next_id = data.next_id,
|
next_id = data.next_id,
|
||||||
is_allowed = data.is_allowed,
|
is_allowed = data.is_allowed,
|
||||||
|
condition_as_text = data.get(&"condition_as_text", ""),
|
||||||
character = await get_resolved_character(data, extra_game_states),
|
character = await get_resolved_character(data, extra_game_states),
|
||||||
character_replacements = data.get(&"character_replacements", [] as Array[Dictionary]),
|
character_replacements = data.get(&"character_replacements", [] as Array[Dictionary]),
|
||||||
text = resolved_data.text,
|
text = resolved_data.text,
|
||||||
text_replacements = data.get(&"text_replacements", [] as Array[Dictionary]),
|
text_replacements = data.get(&"text_replacements", [] as Array[Dictionary]),
|
||||||
tags = data.get(&"tags", []),
|
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]
|
game_states = [_autoloads]
|
||||||
# Add any other state shortcuts from settings
|
# Add any other state shortcuts from settings
|
||||||
for node_name in DMSettings.get_setting(DMSettings.STATE_AUTOLOAD_SHORTCUTS, ""):
|
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:
|
if state:
|
||||||
game_states.append(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)
|
var expression: Array[Dictionary] = data.condition.expression.duplicate(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))
|
||||||
|
|
||||||
|
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
|
# If the when is a comparison when insert the match value as the first value to compare to
|
||||||
var already_compared: bool = false
|
var already_compared: bool = false
|
||||||
if expression[0].type == DMConstants.TOKEN_COMPARISON:
|
if expression_to_check[0].type == DMConstants.TOKEN_COMPARISON:
|
||||||
expression.insert(0, {
|
expression_to_check.insert(0, {
|
||||||
type = DMConstants.TOKEN_VALUE,
|
type = DMConstants.TOKEN_VALUE,
|
||||||
value = match_value
|
value = match_value
|
||||||
})
|
})
|
||||||
already_compared = true
|
already_compared = true
|
||||||
|
|
||||||
var resolved_value = await _resolve(expression, extra_game_states)
|
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
|
# 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):
|
if state.has(property):
|
||||||
return state.get(property)
|
return state.get(property)
|
||||||
else:
|
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)
|
var result = expression.execute([], state, false)
|
||||||
if not expression.has_execute_failed():
|
if not expression.has_execute_failed():
|
||||||
return result
|
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.
|
# Get the list of state shortcuts.
|
||||||
var state_shortcuts: Array = []
|
var state_shortcuts: Array = []
|
||||||
for node_name in DMSettings.get_setting(DMSettings.STATE_AUTOLOAD_SHORTCUTS, ""):
|
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:
|
if state:
|
||||||
state_shortcuts.append(state)
|
state_shortcuts.append(state)
|
||||||
|
|
||||||
@@ -867,7 +906,18 @@ func _resolve(tokens: Array, extra_game_states: Array):
|
|||||||
limit += 1
|
limit += 1
|
||||||
var token: Dictionary = tokens[i]
|
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 function_name: String = token.function
|
||||||
var args = await _resolve_each(token.value, extra_game_states)
|
var args = await _resolve_each(token.value, extra_game_states)
|
||||||
if tokens[i - 1].type == DMConstants.TOKEN_DOT:
|
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.
|
# Check that a thing has a given method.
|
||||||
func _thing_has_method(thing, method: String, args: Array) -> bool:
|
func _thing_has_method(thing, method: String, args: Array) -> bool:
|
||||||
|
if not is_instance_valid(thing):
|
||||||
|
return false
|
||||||
|
|
||||||
if Builtins.is_supported(thing, method):
|
if Builtins.is_supported(thing, method):
|
||||||
return thing != _autoloads
|
return thing != _autoloads
|
||||||
elif thing is Dictionary:
|
elif thing is Dictionary:
|
||||||
@@ -1344,7 +1397,7 @@ func _thing_has_method(thing, method: String, args: Array) -> bool:
|
|||||||
if thing.has_method(method):
|
if thing.has_method(method):
|
||||||
return true
|
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
|
# 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)
|
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:
|
if p.name == property:
|
||||||
return true
|
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
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ var next_id: String = ""
|
|||||||
## [code]true[/code] if the condition of this line was met.
|
## [code]true[/code] if the condition of this line was met.
|
||||||
var is_allowed: bool = true
|
var is_allowed: bool = true
|
||||||
|
|
||||||
|
## The original condition text.
|
||||||
|
var condition_as_text: String = ""
|
||||||
|
|
||||||
## A character (depending on the "characters in responses" behaviour setting).
|
## A character (depending on the "characters in responses" behaviour setting).
|
||||||
var character: String = ""
|
var character: String = ""
|
||||||
|
|
||||||
@@ -45,6 +48,7 @@ func _init(data: Dictionary = {}) -> void:
|
|||||||
text_replacements = data.text_replacements
|
text_replacements = data.text_replacements
|
||||||
tags = data.tags
|
tags = data.tags
|
||||||
translation_key = data.translation_key
|
translation_key = data.translation_key
|
||||||
|
condition_as_text = data.condition_as_text
|
||||||
|
|
||||||
|
|
||||||
func _to_string() -> String:
|
func _to_string() -> String:
|
||||||
|
|||||||
@@ -100,16 +100,20 @@ func _configure_focus() -> void:
|
|||||||
|
|
||||||
if i == 0:
|
if i == 0:
|
||||||
item.focus_neighbor_top = item.get_path()
|
item.focus_neighbor_top = item.get_path()
|
||||||
|
item.focus_neighbor_left = item.get_path()
|
||||||
item.focus_previous = item.get_path()
|
item.focus_previous = item.get_path()
|
||||||
else:
|
else:
|
||||||
item.focus_neighbor_top = items[i - 1].get_path()
|
item.focus_neighbor_top = items[i - 1].get_path()
|
||||||
|
item.focus_neighbor_left = items[i - 1].get_path()
|
||||||
item.focus_previous = items[i - 1].get_path()
|
item.focus_previous = items[i - 1].get_path()
|
||||||
|
|
||||||
if i == items.size() - 1:
|
if i == items.size() - 1:
|
||||||
item.focus_neighbor_bottom = item.get_path()
|
item.focus_neighbor_bottom = item.get_path()
|
||||||
|
item.focus_neighbor_right = item.get_path()
|
||||||
item.focus_next = item.get_path()
|
item.focus_next = item.get_path()
|
||||||
else:
|
else:
|
||||||
item.focus_neighbor_bottom = items[i + 1].get_path()
|
item.focus_neighbor_bottom = items[i + 1].get_path()
|
||||||
|
item.focus_neighbor_right = items[i + 1].get_path()
|
||||||
item.focus_next = items[i + 1].get_path()
|
item.focus_next = items[i + 1].get_path()
|
||||||
|
|
||||||
item.mouse_entered.connect(_on_response_mouse_entered.bind(item))
|
item.mouse_entered.connect(_on_response_mouse_entered.bind(item))
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ corner_radius_top_right = 5
|
|||||||
corner_radius_bottom_right = 5
|
corner_radius_bottom_right = 5
|
||||||
corner_radius_bottom_left = 5
|
corner_radius_bottom_left = 5
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uy0d5"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qkmqt"]
|
||||||
bg_color = Color(0, 0, 0, 1)
|
bg_color = Color(0, 0, 0, 1)
|
||||||
border_width_left = 3
|
border_width_left = 3
|
||||||
border_width_top = 3
|
border_width_top = 3
|
||||||
@@ -61,7 +61,7 @@ MarginContainer/constants/margin_bottom = 15
|
|||||||
MarginContainer/constants/margin_left = 30
|
MarginContainer/constants/margin_left = 30
|
||||||
MarginContainer/constants/margin_right = 30
|
MarginContainer/constants/margin_right = 30
|
||||||
MarginContainer/constants/margin_top = 15
|
MarginContainer/constants/margin_top = 15
|
||||||
Panel/styles/panel = SubResource("StyleBoxFlat_uy0d5")
|
PanelContainer/styles/panel = SubResource("StyleBoxFlat_qkmqt")
|
||||||
|
|
||||||
[node name="ExampleBalloon" type="CanvasLayer"]
|
[node name="ExampleBalloon" type="CanvasLayer"]
|
||||||
layer = 100
|
layer = 100
|
||||||
@@ -77,33 +77,28 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
theme = SubResource("Theme_qq3yp")
|
theme = SubResource("Theme_qq3yp")
|
||||||
|
|
||||||
[node name="Panel" type="Panel" parent="Balloon"]
|
[node name="MarginContainer" type="MarginContainer" parent="Balloon"]
|
||||||
clip_children = 2
|
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 12
|
anchors_preset = 12
|
||||||
anchor_top = 1.0
|
anchor_top = 1.0
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
offset_left = 21.0
|
offset_top = -219.0
|
||||||
offset_top = -183.0
|
|
||||||
offset_right = -19.0
|
|
||||||
offset_bottom = -19.0
|
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
|
|
||||||
|
[node name="PanelContainer" type="PanelContainer" parent="Balloon/MarginContainer"]
|
||||||
|
clip_children = 2
|
||||||
|
layout_mode = 2
|
||||||
mouse_filter = 1
|
mouse_filter = 1
|
||||||
|
|
||||||
[node name="Dialogue" type="MarginContainer" parent="Balloon/Panel"]
|
[node name="MarginContainer" type="MarginContainer" parent="Balloon/MarginContainer/PanelContainer"]
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/Panel/Dialogue"]
|
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/Panel/Dialogue/VBoxContainer"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/MarginContainer/PanelContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
modulate = Color(1, 1, 1, 0.501961)
|
modulate = Color(1, 1, 1, 0.501961)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
@@ -113,37 +108,35 @@ text = "Character"
|
|||||||
fit_content = true
|
fit_content = true
|
||||||
scroll_active = false
|
scroll_active = false
|
||||||
|
|
||||||
[node name="DialogueLabel" parent="Balloon/Panel/Dialogue/VBoxContainer" instance=ExtResource("2_a8ve6")]
|
[node name="DialogueLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_a8ve6")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
text = "Dialogue..."
|
text = "Dialogue..."
|
||||||
|
|
||||||
[node name="Responses" type="MarginContainer" parent="Balloon"]
|
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon" node_paths=PackedStringArray("response_template")]
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 7
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 0.5
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -147.0
|
|
||||||
offset_top = -558.0
|
|
||||||
offset_right = 494.0
|
|
||||||
offset_bottom = -154.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 0
|
|
||||||
|
|
||||||
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon/Responses" node_paths=PackedStringArray("response_template")]
|
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -290.5
|
||||||
|
offset_top = -35.0
|
||||||
|
offset_right = 290.5
|
||||||
|
offset_bottom = 35.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
size_flags_vertical = 8
|
size_flags_vertical = 8
|
||||||
theme_override_constants/separation = 2
|
theme_override_constants/separation = 2
|
||||||
|
alignment = 1
|
||||||
script = ExtResource("3_72ixx")
|
script = ExtResource("3_72ixx")
|
||||||
response_template = NodePath("ResponseExample")
|
response_template = NodePath("ResponseExample")
|
||||||
|
|
||||||
[node name="ResponseExample" type="Button" parent="Balloon/Responses/ResponsesMenu"]
|
[node name="ResponseExample" type="Button" parent="Balloon/ResponsesMenu"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Response example"
|
text = "Response example"
|
||||||
|
|
||||||
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
|
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
|
||||||
[connection signal="response_selected" from="Balloon/Responses/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]
|
[connection signal="response_selected" from="Balloon/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ corner_radius_top_right = 3
|
|||||||
corner_radius_bottom_right = 3
|
corner_radius_bottom_right = 3
|
||||||
corner_radius_bottom_left = 3
|
corner_radius_bottom_left = 3
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uy0d5"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i6nbm"]
|
||||||
bg_color = Color(0, 0, 0, 1)
|
bg_color = Color(0, 0, 0, 1)
|
||||||
border_width_left = 1
|
border_width_left = 1
|
||||||
border_width_top = 1
|
border_width_top = 1
|
||||||
@@ -87,7 +87,7 @@ MarginContainer/constants/margin_bottom = 4
|
|||||||
MarginContainer/constants/margin_left = 8
|
MarginContainer/constants/margin_left = 8
|
||||||
MarginContainer/constants/margin_right = 8
|
MarginContainer/constants/margin_right = 8
|
||||||
MarginContainer/constants/margin_top = 4
|
MarginContainer/constants/margin_top = 4
|
||||||
Panel/styles/panel = SubResource("StyleBoxFlat_uy0d5")
|
PanelContainer/styles/panel = SubResource("StyleBoxFlat_i6nbm")
|
||||||
|
|
||||||
[node name="ExampleBalloon" type="CanvasLayer"]
|
[node name="ExampleBalloon" type="CanvasLayer"]
|
||||||
layer = 100
|
layer = 100
|
||||||
@@ -103,33 +103,28 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
theme = SubResource("Theme_qq3yp")
|
theme = SubResource("Theme_qq3yp")
|
||||||
|
|
||||||
[node name="Panel" type="Panel" parent="Balloon"]
|
[node name="MarginContainer" type="MarginContainer" parent="Balloon"]
|
||||||
clip_children = 2
|
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 12
|
anchors_preset = 12
|
||||||
anchor_top = 1.0
|
anchor_top = 1.0
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
offset_left = 3.0
|
offset_top = -71.0
|
||||||
offset_top = -62.0
|
|
||||||
offset_right = -4.0
|
|
||||||
offset_bottom = -4.0
|
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
|
|
||||||
|
[node name="PanelContainer" type="PanelContainer" parent="Balloon/MarginContainer"]
|
||||||
|
clip_children = 2
|
||||||
|
layout_mode = 2
|
||||||
mouse_filter = 1
|
mouse_filter = 1
|
||||||
|
|
||||||
[node name="Dialogue" type="MarginContainer" parent="Balloon/Panel"]
|
[node name="MarginContainer" type="MarginContainer" parent="Balloon/MarginContainer/PanelContainer"]
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/Panel/Dialogue"]
|
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/Panel/Dialogue/VBoxContainer"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/MarginContainer/PanelContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
modulate = Color(1, 1, 1, 0.501961)
|
modulate = Color(1, 1, 1, 0.501961)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
@@ -139,36 +134,33 @@ text = "Character"
|
|||||||
fit_content = true
|
fit_content = true
|
||||||
scroll_active = false
|
scroll_active = false
|
||||||
|
|
||||||
[node name="DialogueLabel" parent="Balloon/Panel/Dialogue/VBoxContainer" instance=ExtResource("2_hfvdi")]
|
[node name="DialogueLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_hfvdi")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
text = "Dialogue..."
|
text = "Dialogue..."
|
||||||
|
|
||||||
[node name="Responses" type="MarginContainer" parent="Balloon"]
|
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon"]
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 7
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 0.5
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -124.0
|
|
||||||
offset_top = -218.0
|
|
||||||
offset_right = 125.0
|
|
||||||
offset_bottom = -50.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 0
|
|
||||||
|
|
||||||
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon/Responses"]
|
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -116.5
|
||||||
|
offset_top = -9.0
|
||||||
|
offset_right = 116.5
|
||||||
|
offset_bottom = 9.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
size_flags_vertical = 8
|
size_flags_vertical = 8
|
||||||
theme_override_constants/separation = 2
|
theme_override_constants/separation = 2
|
||||||
script = ExtResource("3_1j1j0")
|
script = ExtResource("3_1j1j0")
|
||||||
|
|
||||||
[node name="ResponseExample" type="Button" parent="Balloon/Responses/ResponsesMenu"]
|
[node name="ResponseExample" type="Button" parent="Balloon/ResponsesMenu"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Response Example"
|
text = "Response Example"
|
||||||
|
|
||||||
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
|
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
|
||||||
[connection signal="response_selected" from="Balloon/Responses/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]
|
[connection signal="response_selected" from="Balloon/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]
|
||||||
|
|||||||
@@ -3,10 +3,16 @@ class_name DMExportPlugin extends EditorExportPlugin
|
|||||||
const IGNORED_PATHS = [
|
const IGNORED_PATHS = [
|
||||||
"/assets",
|
"/assets",
|
||||||
"/components",
|
"/components",
|
||||||
"/l10n",
|
"/views",
|
||||||
"/views"
|
"inspector_plugin",
|
||||||
|
"test_scene"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
func _get_name() -> String:
|
||||||
|
return "Dialogue Manager Export Plugin"
|
||||||
|
|
||||||
|
|
||||||
func _export_file(path: String, type: String, features: PackedStringArray) -> void:
|
func _export_file(path: String, type: String, features: PackedStringArray) -> void:
|
||||||
var plugin_path: String = Engine.get_meta("DialogueManagerPlugin").get_plugin_path()
|
var plugin_path: String = Engine.get_meta("DialogueManagerPlugin").get_plugin_path()
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ class_name DMImportPlugin extends EditorImportPlugin
|
|||||||
signal compiled_resource(resource: Resource)
|
signal compiled_resource(resource: Resource)
|
||||||
|
|
||||||
|
|
||||||
const COMPILER_VERSION = 14
|
const COMPILER_VERSION = 15
|
||||||
|
|
||||||
|
|
||||||
func _get_importer_name() -> String:
|
func _get_importer_name() -> String:
|
||||||
# NOTE: A change to this forces a re-import of all dialogue
|
return "dialogue_manager"
|
||||||
return "dialogue_manager_compiler_%s" % COMPILER_VERSION
|
|
||||||
|
|
||||||
|
func _get_format_version() -> int:
|
||||||
|
return COMPILER_VERSION
|
||||||
|
|
||||||
|
|
||||||
func _get_visible_name() -> String:
|
func _get_visible_name() -> String:
|
||||||
@@ -74,7 +77,7 @@ func _import(source_file: String, save_path: String, options: Dictionary, platfo
|
|||||||
if result.errors.size() > 0:
|
if result.errors.size() > 0:
|
||||||
printerr("%d errors found in %s" % [result.errors.size(), source_file])
|
printerr("%d errors found in %s" % [result.errors.size(), source_file])
|
||||||
cache.add_errors_to_file(source_file, result.errors)
|
cache.add_errors_to_file(source_file, result.errors)
|
||||||
return ERR_PARSE_ERROR
|
return OK
|
||||||
|
|
||||||
# Get the current addon version
|
# Get the current addon version
|
||||||
var config: ConfigFile = ConfigFile.new()
|
var config: ConfigFile = ConfigFile.new()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ msgstr ""
|
|||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: de\n"
|
"Language: en\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
@@ -108,6 +108,15 @@ msgstr "End dialogue"
|
|||||||
msgid "generate_line_ids"
|
msgid "generate_line_ids"
|
||||||
msgstr "Generate line IDs"
|
msgstr "Generate line IDs"
|
||||||
|
|
||||||
|
msgid "use_uuid_only_for_ids"
|
||||||
|
msgstr "Use UUID only for IDs"
|
||||||
|
|
||||||
|
msgid "set_id_prefix_length"
|
||||||
|
msgstr "Set ID prefix length"
|
||||||
|
|
||||||
|
msgid "id_prefix_length"
|
||||||
|
msgstr "ID prefix length:"
|
||||||
|
|
||||||
msgid "save_characters_to_csv"
|
msgid "save_characters_to_csv"
|
||||||
msgstr "Save character names to CSV..."
|
msgstr "Save character names to CSV..."
|
||||||
|
|
||||||
@@ -324,6 +333,12 @@ msgstr "Concurrent lines need an origin line that doesn't start with \"| \"."
|
|||||||
msgid "errors.goto_not_allowed_on_concurrect_lines"
|
msgid "errors.goto_not_allowed_on_concurrect_lines"
|
||||||
msgstr "Goto references are not allowed on concurrent dialogue lines."
|
msgstr "Goto references are not allowed on concurrent dialogue lines."
|
||||||
|
|
||||||
|
msgid "errors.unexpected_syntax_on_nested_dialogue_line"
|
||||||
|
msgstr "Nested dialogue lines may only contain dialogue."
|
||||||
|
|
||||||
|
msgid "errors.err_nested_dialogue_invalid_jump"
|
||||||
|
msgstr "Only the last line of nested dialogue is allowed to include a jump."
|
||||||
|
|
||||||
msgid "errors.unknown"
|
msgid "errors.unknown"
|
||||||
msgstr "Unknown syntax."
|
msgstr "Unknown syntax."
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,15 @@ msgstr "Finalizar diálogo"
|
|||||||
msgid "generate_line_ids"
|
msgid "generate_line_ids"
|
||||||
msgstr "Generar IDs de línea"
|
msgstr "Generar IDs de línea"
|
||||||
|
|
||||||
|
msgid "use_uuid_only_for_ids"
|
||||||
|
msgstr "Usar solo UUID como ID"
|
||||||
|
|
||||||
|
msgid "set_id_prefix_length"
|
||||||
|
msgstr "Establecer la longitud del prefijo de ID"
|
||||||
|
|
||||||
|
msgid "id_prefix_length"
|
||||||
|
msgstr "Longitud del prefijo de ID:"
|
||||||
|
|
||||||
msgid "save_characters_to_csv"
|
msgid "save_characters_to_csv"
|
||||||
msgstr "Guardar los nombres de los personajes en un archivo CSV..."
|
msgstr "Guardar los nombres de los personajes en un archivo CSV..."
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,15 @@ msgstr ""
|
|||||||
msgid "generate_line_ids"
|
msgid "generate_line_ids"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "use_uuid_only_for_ids"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "set_id_prefix_length"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "id_prefix_length"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "save_to_csv"
|
msgid "save_to_csv"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -314,6 +323,12 @@ msgstr ""
|
|||||||
msgid "errors.goto_not_allowed_on_concurrect_lines"
|
msgid "errors.goto_not_allowed_on_concurrect_lines"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "errors.unexpected_syntax_on_nested_dialogue_line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "errors.err_nested_dialogue_invalid_jump"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "errors.unknown"
|
msgid "errors.unknown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,15 @@ msgstr "Кінець діалогу"
|
|||||||
msgid "generate_line_ids"
|
msgid "generate_line_ids"
|
||||||
msgstr "Згенерувати ідентифікатори рядків"
|
msgstr "Згенерувати ідентифікатори рядків"
|
||||||
|
|
||||||
|
msgid "use_uuid_only_for_ids"
|
||||||
|
msgstr "Використовувати лише UUID як ID"
|
||||||
|
|
||||||
|
msgid "set_id_prefix_length"
|
||||||
|
msgstr "Встановити довжину префікса ID"
|
||||||
|
|
||||||
|
msgid "id_prefix_length"
|
||||||
|
msgstr "Довжина префікса ID:"
|
||||||
|
|
||||||
msgid "save_characters_to_csv"
|
msgid "save_characters_to_csv"
|
||||||
msgstr "Зберегти імена персонажів в CSV..."
|
msgstr "Зберегти імена персонажів в CSV..."
|
||||||
|
|
||||||
@@ -320,6 +329,12 @@ msgstr "Паралельні рядки потребують початково
|
|||||||
msgid "errors.goto_not_allowed_on_concurrect_lines"
|
msgid "errors.goto_not_allowed_on_concurrect_lines"
|
||||||
msgstr "У паралельних діалогових рядках не допускаються Goto посилання."
|
msgstr "У паралельних діалогових рядках не допускаються Goto посилання."
|
||||||
|
|
||||||
|
msgid "errors.unexpected_syntax_on_nested_dialogue_line"
|
||||||
|
msgstr "Вкладені рядки діалогу можуть містити лише діалог."
|
||||||
|
|
||||||
|
msgid "errors.err_nested_dialogue_invalid_jump"
|
||||||
|
msgstr "Лише останній рядок вкладеного діалогу може містити перехід."
|
||||||
|
|
||||||
msgid "errors.unknown"
|
msgid "errors.unknown"
|
||||||
msgstr "Невідомий синтаксис."
|
msgstr "Невідомий синтаксис."
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,15 @@ msgstr "结束对话"
|
|||||||
msgid "generate_line_ids"
|
msgid "generate_line_ids"
|
||||||
msgstr "生成行 ID"
|
msgstr "生成行 ID"
|
||||||
|
|
||||||
|
msgid "use_uuid_only_for_ids"
|
||||||
|
msgstr "仅使用UUID作为ID"
|
||||||
|
|
||||||
|
msgid "set_id_prefix_length"
|
||||||
|
msgstr "设置ID前缀长度"
|
||||||
|
|
||||||
|
msgid "id_prefix_length"
|
||||||
|
msgstr "ID前缀长度:"
|
||||||
|
|
||||||
msgid "save_characters_to_csv"
|
msgid "save_characters_to_csv"
|
||||||
msgstr "保存角色到 CSV"
|
msgstr "保存角色到 CSV"
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,15 @@ msgstr "結束對話"
|
|||||||
msgid "generate_line_ids"
|
msgid "generate_line_ids"
|
||||||
msgstr "生成行 ID"
|
msgstr "生成行 ID"
|
||||||
|
|
||||||
|
msgid "use_uuid_only_for_ids"
|
||||||
|
msgstr "僅使用 UUID 作為 ID"
|
||||||
|
|
||||||
|
msgid "set_id_prefix_length"
|
||||||
|
msgstr "設定 ID 前綴長度"
|
||||||
|
|
||||||
|
msgid "id_prefix_length"
|
||||||
|
msgstr "ID 前綴長度:"
|
||||||
|
|
||||||
msgid "save_characters_to_csv"
|
msgid "save_characters_to_csv"
|
||||||
msgstr "保存角色到 CSV"
|
msgstr "保存角色到 CSV"
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
name="Dialogue Manager"
|
name="Dialogue Manager"
|
||||||
description="A powerful nonlinear dialogue system"
|
description="A powerful nonlinear dialogue system"
|
||||||
author="Nathan Hoad"
|
author="Nathan Hoad"
|
||||||
version="3.4.0"
|
version="3.7.1"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
|||||||
@@ -13,9 +13,15 @@ var main_view
|
|||||||
var dialogue_cache: DMCache
|
var dialogue_cache: DMCache
|
||||||
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
func _enable_plugin() -> void:
|
||||||
add_autoload_singleton("DialogueManager", get_plugin_path() + "/dialogue_manager.gd")
|
add_autoload_singleton("DialogueManager", get_plugin_path() + "/dialogue_manager.gd")
|
||||||
|
|
||||||
|
|
||||||
|
func _disable_plugin() -> void:
|
||||||
|
remove_autoload_singleton("DialogueManager")
|
||||||
|
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
Engine.set_meta("DialogueManagerPlugin", self)
|
Engine.set_meta("DialogueManagerPlugin", self)
|
||||||
|
|
||||||
@@ -105,8 +111,6 @@ func _enter_tree() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
remove_autoload_singleton("DialogueManager")
|
|
||||||
|
|
||||||
remove_import_plugin(import_plugin)
|
remove_import_plugin(import_plugin)
|
||||||
import_plugin = null
|
import_plugin = null
|
||||||
|
|
||||||
@@ -172,6 +176,11 @@ func _apply_changes() -> void:
|
|||||||
_update_localization()
|
_update_localization()
|
||||||
|
|
||||||
|
|
||||||
|
func _save_external_data() -> void:
|
||||||
|
if dialogue_cache != null:
|
||||||
|
dialogue_cache.reimport_files()
|
||||||
|
|
||||||
|
|
||||||
func _build() -> bool:
|
func _build() -> bool:
|
||||||
# If this is the dotnet Godot then we need to check if the solution file exists
|
# If this is the dotnet Godot then we need to check if the solution file exists
|
||||||
DMSettings.check_for_dotnet_solution()
|
DMSettings.check_for_dotnet_solution()
|
||||||
@@ -320,6 +329,9 @@ func update_import_paths(from_path: String, to_path: String) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _update_localization() -> void:
|
func _update_localization() -> void:
|
||||||
|
if not DMSettings.get_setting(DMSettings.UPDATE_POT_FILES_AUTOMATICALLY, true):
|
||||||
|
return
|
||||||
|
|
||||||
var dialogue_files = dialogue_cache.get_files()
|
var dialogue_files = dialogue_cache.get_files()
|
||||||
|
|
||||||
# Add any new files to POT generation
|
# Add any new files to POT generation
|
||||||
|
|||||||
@@ -23,9 +23,13 @@ const EXTRA_CSV_LOCALES = "editor/translations/extra_csv_locales"
|
|||||||
const INCLUDE_CHARACTER_IN_TRANSLATION_EXPORTS = "editor/translations/include_character_in_translation_exports"
|
const INCLUDE_CHARACTER_IN_TRANSLATION_EXPORTS = "editor/translations/include_character_in_translation_exports"
|
||||||
## Includes a "_notes" column in CSV exports
|
## Includes a "_notes" column in CSV exports
|
||||||
const INCLUDE_NOTES_IN_TRANSLATION_EXPORTS = "editor/translations/include_notes_in_translation_exports"
|
const INCLUDE_NOTES_IN_TRANSLATION_EXPORTS = "editor/translations/include_notes_in_translation_exports"
|
||||||
|
## Automatically update the project's list of translatable files when dialogue files are added or removed
|
||||||
|
const UPDATE_POT_FILES_AUTOMATICALLY = "editor/translations/update_pot_files_automatically"
|
||||||
|
|
||||||
## A custom test scene to use when testing dialogue.
|
## A custom test scene to use when testing dialogue.
|
||||||
const CUSTOM_TEST_SCENE_PATH = "editor/advanced/custom_test_scene_path"
|
const CUSTOM_TEST_SCENE_PATH = "editor/advanced/custom_test_scene_path"
|
||||||
|
## Extra script files to include in the auto-complete-able list
|
||||||
|
const EXTRA_AUTO_COMPLETE_SCRIPT_SOURCES = "editor/advanced/extra_auto_complete_script_sources"
|
||||||
|
|
||||||
## The custom balloon for this game.
|
## The custom balloon for this game.
|
||||||
const BALLOON_PATH = "runtime/balloon_path"
|
const BALLOON_PATH = "runtime/balloon_path"
|
||||||
@@ -38,9 +42,12 @@ const WARN_ABOUT_METHOD_PROPERTY_OR_SIGNAL_NAME_CONFLICTS = "runtime/warn_about_
|
|||||||
const IGNORE_MISSING_STATE_VALUES = "runtime/advanced/ignore_missing_state_values"
|
const IGNORE_MISSING_STATE_VALUES = "runtime/advanced/ignore_missing_state_values"
|
||||||
## Whether or not the project is utilising dotnet.
|
## Whether or not the project is utilising dotnet.
|
||||||
const USES_DOTNET = "runtime/advanced/uses_dotnet"
|
const USES_DOTNET = "runtime/advanced/uses_dotnet"
|
||||||
|
## Maximum length of text prefix in auto-generated IDs
|
||||||
|
const AUTO_GENERATED_ID_PREFIX_LENGTH = "editor/translations/auto_generated_id_prefix_length"
|
||||||
|
## Use only UUID for auto-generated IDs without text prefix
|
||||||
|
const USE_UUID_ONLY_FOR_IDS = "editor/translations/use_uuid_only_for_ids"
|
||||||
|
|
||||||
|
static var SETTINGS_CONFIGURATION = {
|
||||||
const SETTINGS_CONFIGURATION = {
|
|
||||||
WRAP_LONG_LINES: {
|
WRAP_LONG_LINES: {
|
||||||
value = false,
|
value = false,
|
||||||
type = TYPE_BOOL,
|
type = TYPE_BOOL,
|
||||||
@@ -68,6 +75,8 @@ const SETTINGS_CONFIGURATION = {
|
|||||||
EXTRA_CSV_LOCALES: {
|
EXTRA_CSV_LOCALES: {
|
||||||
value = [],
|
value = [],
|
||||||
type = TYPE_PACKED_STRING_ARRAY,
|
type = TYPE_PACKED_STRING_ARRAY,
|
||||||
|
hint = PROPERTY_HINT_TYPE_STRING,
|
||||||
|
hint_string = "%d:" % [TYPE_STRING],
|
||||||
is_advanced = true
|
is_advanced = true
|
||||||
},
|
},
|
||||||
INCLUDE_CHARACTER_IN_TRANSLATION_EXPORTS: {
|
INCLUDE_CHARACTER_IN_TRANSLATION_EXPORTS: {
|
||||||
@@ -80,6 +89,11 @@ const SETTINGS_CONFIGURATION = {
|
|||||||
type = TYPE_BOOL,
|
type = TYPE_BOOL,
|
||||||
is_advanced = true
|
is_advanced = true
|
||||||
},
|
},
|
||||||
|
UPDATE_POT_FILES_AUTOMATICALLY: {
|
||||||
|
value = true,
|
||||||
|
type = TYPE_BOOL,
|
||||||
|
is_advanced = true
|
||||||
|
},
|
||||||
|
|
||||||
CUSTOM_TEST_SCENE_PATH: {
|
CUSTOM_TEST_SCENE_PATH: {
|
||||||
value = preload("./test_scene.tscn").resource_path,
|
value = preload("./test_scene.tscn").resource_path,
|
||||||
@@ -87,6 +101,13 @@ const SETTINGS_CONFIGURATION = {
|
|||||||
hint = PROPERTY_HINT_FILE,
|
hint = PROPERTY_HINT_FILE,
|
||||||
is_advanced = true
|
is_advanced = true
|
||||||
},
|
},
|
||||||
|
EXTRA_AUTO_COMPLETE_SCRIPT_SOURCES: {
|
||||||
|
value = [],
|
||||||
|
type = TYPE_PACKED_STRING_ARRAY,
|
||||||
|
hint = PROPERTY_HINT_TYPE_STRING,
|
||||||
|
hint_string = "%d/%d:*.*" % [TYPE_STRING, PROPERTY_HINT_FILE],
|
||||||
|
is_advanced = true
|
||||||
|
},
|
||||||
|
|
||||||
BALLOON_PATH: {
|
BALLOON_PATH: {
|
||||||
value = "",
|
value = "",
|
||||||
@@ -96,6 +117,8 @@ const SETTINGS_CONFIGURATION = {
|
|||||||
STATE_AUTOLOAD_SHORTCUTS: {
|
STATE_AUTOLOAD_SHORTCUTS: {
|
||||||
value = [],
|
value = [],
|
||||||
type = TYPE_PACKED_STRING_ARRAY,
|
type = TYPE_PACKED_STRING_ARRAY,
|
||||||
|
hint = PROPERTY_HINT_TYPE_STRING,
|
||||||
|
hint_string = "%d:" % [TYPE_STRING],
|
||||||
},
|
},
|
||||||
WARN_ABOUT_METHOD_PROPERTY_OR_SIGNAL_NAME_CONFLICTS: {
|
WARN_ABOUT_METHOD_PROPERTY_OR_SIGNAL_NAME_CONFLICTS: {
|
||||||
value = false,
|
value = false,
|
||||||
@@ -112,7 +135,19 @@ const SETTINGS_CONFIGURATION = {
|
|||||||
value = false,
|
value = false,
|
||||||
type = TYPE_BOOL,
|
type = TYPE_BOOL,
|
||||||
is_hidden = true
|
is_hidden = true
|
||||||
}
|
},
|
||||||
|
AUTO_GENERATED_ID_PREFIX_LENGTH: {
|
||||||
|
value = 30,
|
||||||
|
type = TYPE_INT,
|
||||||
|
hint = PROPERTY_HINT_RANGE,
|
||||||
|
hint_string = "0,100,1",
|
||||||
|
is_advanced = true
|
||||||
|
},
|
||||||
|
USE_UUID_ONLY_FOR_IDS: {
|
||||||
|
value = false,
|
||||||
|
type = TYPE_BOOL,
|
||||||
|
is_advanced = true
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -203,7 +238,7 @@ static func get_user_config() -> Dictionary:
|
|||||||
recent_files = [],
|
recent_files = [],
|
||||||
reopen_files = [],
|
reopen_files = [],
|
||||||
most_recent_reopen_file = "",
|
most_recent_reopen_file = "",
|
||||||
carets = {},
|
file_meta = {},
|
||||||
run_title = "",
|
run_title = "",
|
||||||
run_resource_path = "",
|
run_resource_path = "",
|
||||||
is_running_test_scene = false,
|
is_running_test_scene = false,
|
||||||
@@ -229,10 +264,17 @@ static func set_user_value(key: String, value) -> void:
|
|||||||
save_user_config(user_config)
|
save_user_config(user_config)
|
||||||
|
|
||||||
|
|
||||||
static func get_user_value(key: String, default = null):
|
static func get_user_value(key: String, default = null) -> Variant:
|
||||||
return get_user_config().get(key, default)
|
return get_user_config().get(key, default)
|
||||||
|
|
||||||
|
|
||||||
|
static func forget_path(path: String) -> void:
|
||||||
|
remove_recent_file(path)
|
||||||
|
var file_meta: Dictionary = get_user_value("file_meta", {})
|
||||||
|
file_meta.erase(path)
|
||||||
|
set_user_value("file_meta", file_meta)
|
||||||
|
|
||||||
|
|
||||||
static func add_recent_file(path: String) -> void:
|
static func add_recent_file(path: String) -> void:
|
||||||
var recent_files: Array = get_user_value("recent_files", [])
|
var recent_files: Array = get_user_value("recent_files", [])
|
||||||
if path in recent_files:
|
if path in recent_files:
|
||||||
@@ -266,23 +308,34 @@ static func clear_recent_files() -> void:
|
|||||||
|
|
||||||
|
|
||||||
static func set_caret(path: String, cursor: Vector2) -> void:
|
static func set_caret(path: String, cursor: Vector2) -> void:
|
||||||
var carets: Dictionary = get_user_value("carets", {})
|
var file_meta: Dictionary = get_user_value("file_meta", {})
|
||||||
carets[path] = {
|
file_meta[path] = file_meta.get(path, {}).merged({ cursor = "%d,%d" % [cursor.x, cursor.y] }, true)
|
||||||
x = cursor.x,
|
set_user_value("file_meta", file_meta)
|
||||||
y = cursor.y
|
|
||||||
}
|
|
||||||
set_user_value("carets", carets)
|
|
||||||
|
|
||||||
|
|
||||||
static func get_caret(path: String) -> Vector2:
|
static func get_caret(path: String) -> Vector2:
|
||||||
var carets = get_user_value("carets", {})
|
var file_meta: Dictionary = get_user_value("file_meta", {})
|
||||||
if carets.has(path):
|
if file_meta.has(path):
|
||||||
var caret = carets.get(path)
|
var cursor: PackedStringArray = file_meta.get(path).get("cursor", "0,0").split(",")
|
||||||
return Vector2(caret.x, caret.y)
|
return Vector2(cursor[0].to_int(), cursor[1].to_int())
|
||||||
else:
|
else:
|
||||||
return Vector2.ZERO
|
return Vector2.ZERO
|
||||||
|
|
||||||
|
|
||||||
|
static func set_scroll(path: String, scroll_vertical: int) -> void:
|
||||||
|
var file_meta: Dictionary = get_user_value("file_meta", {})
|
||||||
|
file_meta[path] = file_meta.get(path, {}).merged({ scroll_vertical = scroll_vertical }, true)
|
||||||
|
set_user_value("file_meta", file_meta)
|
||||||
|
|
||||||
|
|
||||||
|
static func get_scroll(path: String) -> int:
|
||||||
|
var file_meta: Dictionary = get_user_value("file_meta", {})
|
||||||
|
if file_meta.has(path):
|
||||||
|
return file_meta.get(path).get("scroll_vertical", 0)
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
static func check_for_dotnet_solution() -> bool:
|
static func check_for_dotnet_solution() -> bool:
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
var has_dotnet_solution: bool = false
|
var has_dotnet_solution: bool = false
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ func reimport_files(and_files: PackedStringArray = []) -> void:
|
|||||||
if _files_marked_for_reimport.is_empty(): return
|
if _files_marked_for_reimport.is_empty(): return
|
||||||
|
|
||||||
EditorInterface.get_resource_filesystem().reimport_files(_files_marked_for_reimport)
|
EditorInterface.get_resource_filesystem().reimport_files(_files_marked_for_reimport)
|
||||||
|
_files_marked_for_reimport.clear()
|
||||||
|
|
||||||
|
|
||||||
## Add a dialogue file to the cache.
|
## Add a dialogue file to the cache.
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ signal confirmation_closed()
|
|||||||
|
|
||||||
@onready var parse_timer: Timer = $ParseTimer
|
@onready var parse_timer: Timer = $ParseTimer
|
||||||
|
|
||||||
|
# Banner
|
||||||
|
@onready var banner: CenterContainer = %Banner
|
||||||
|
@onready var banner_new_button: Button = %BannerNewButton
|
||||||
|
@onready var banner_quick_open: Button = %BannerQuickOpen
|
||||||
|
@onready var banner_examples: Button = %BannerExamples
|
||||||
|
|
||||||
# Dialogs
|
# Dialogs
|
||||||
@onready var new_dialog: FileDialog = $NewDialog
|
@onready var new_dialog: FileDialog = $NewDialog
|
||||||
@onready var save_dialog: FileDialog = $SaveDialog
|
@onready var save_dialog: FileDialog = $SaveDialog
|
||||||
@@ -87,6 +93,7 @@ var current_file_path: String = "":
|
|||||||
title_list.hide()
|
title_list.hide()
|
||||||
code_edit.hide()
|
code_edit.hide()
|
||||||
errors_panel.hide()
|
errors_panel.hide()
|
||||||
|
banner.show()
|
||||||
else:
|
else:
|
||||||
test_button.disabled = false
|
test_button.disabled = false
|
||||||
test_line_button.disabled = false
|
test_line_button.disabled = false
|
||||||
@@ -97,17 +104,25 @@ var current_file_path: String = "":
|
|||||||
files_list.show()
|
files_list.show()
|
||||||
title_list.show()
|
title_list.show()
|
||||||
code_edit.show()
|
code_edit.show()
|
||||||
|
banner.hide()
|
||||||
|
|
||||||
|
var cursor: Vector2 = DMSettings.get_caret(current_file_path)
|
||||||
|
var scroll_vertical: int = DMSettings.get_scroll(current_file_path)
|
||||||
|
|
||||||
code_edit.text = open_buffers[current_file_path].text
|
code_edit.text = open_buffers[current_file_path].text
|
||||||
code_edit.errors = []
|
code_edit.errors = []
|
||||||
code_edit.clear_undo_history()
|
code_edit.clear_undo_history()
|
||||||
code_edit.set_cursor(DMSettings.get_caret(current_file_path))
|
code_edit.set_cursor(cursor)
|
||||||
|
code_edit.scroll_vertical = scroll_vertical
|
||||||
code_edit.grab_focus()
|
code_edit.grab_focus()
|
||||||
|
|
||||||
_on_code_edit_text_changed()
|
_on_code_edit_text_changed()
|
||||||
|
|
||||||
errors_panel.errors = []
|
errors_panel.errors = []
|
||||||
code_edit.errors = []
|
code_edit.errors = []
|
||||||
|
|
||||||
|
if search_and_replace.visible:
|
||||||
|
search_and_replace.search()
|
||||||
get:
|
get:
|
||||||
return current_file_path
|
return current_file_path
|
||||||
|
|
||||||
@@ -177,6 +192,8 @@ func _ready() -> void:
|
|||||||
|
|
||||||
EditorInterface.get_file_system_dock().files_moved.connect(_on_files_moved)
|
EditorInterface.get_file_system_dock().files_moved.connect(_on_files_moved)
|
||||||
|
|
||||||
|
code_edit.get_v_scroll_bar().value_changed.connect(_on_code_edit_scroll_changed)
|
||||||
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
DMSettings.set_user_value("reopen_files", open_buffers.keys())
|
DMSettings.set_user_value("reopen_files", open_buffers.keys())
|
||||||
@@ -269,6 +286,12 @@ func open_file(path: String) -> void:
|
|||||||
self.current_file_path = path
|
self.current_file_path = path
|
||||||
|
|
||||||
|
|
||||||
|
func quick_open() -> void:
|
||||||
|
quick_open_files_list.files = Engine.get_meta("DMCache").get_files()
|
||||||
|
quick_open_dialog.popup_centered()
|
||||||
|
quick_open_files_list.focus_filter()
|
||||||
|
|
||||||
|
|
||||||
func show_file_in_filesystem(path: String) -> void:
|
func show_file_in_filesystem(path: String) -> void:
|
||||||
EditorInterface.get_file_system_dock().navigate_to_path(path)
|
EditorInterface.get_file_system_dock().navigate_to_path(path)
|
||||||
|
|
||||||
@@ -367,6 +390,9 @@ func apply_theme() -> void:
|
|||||||
font_size = editor_settings.get_setting("interface/editor/code_font_size")
|
font_size = editor_settings.get_setting("interface/editor/code_font_size")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
banner_new_button.icon = get_theme_icon("New", "EditorIcons")
|
||||||
|
banner_quick_open.icon = get_theme_icon("Load", "EditorIcons")
|
||||||
|
|
||||||
new_button.icon = get_theme_icon("New", "EditorIcons")
|
new_button.icon = get_theme_icon("New", "EditorIcons")
|
||||||
new_button.tooltip_text = DMConstants.translate(&"start_a_new_file")
|
new_button.tooltip_text = DMConstants.translate(&"start_a_new_file")
|
||||||
|
|
||||||
@@ -493,8 +519,8 @@ func show_build_error_dialog() -> void:
|
|||||||
|
|
||||||
# Generate translation line IDs for any line that doesn't already have one
|
# Generate translation line IDs for any line that doesn't already have one
|
||||||
func generate_translations_keys() -> void:
|
func generate_translations_keys() -> void:
|
||||||
randomize()
|
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
|
||||||
seed(Time.get_unix_time_from_system())
|
rng.randomize()
|
||||||
|
|
||||||
var cursor: Vector2 = code_edit.get_cursor()
|
var cursor: Vector2 = code_edit.get_cursor()
|
||||||
var lines: PackedStringArray = code_edit.text.split("\n")
|
var lines: PackedStringArray = code_edit.text.split("\n")
|
||||||
@@ -502,6 +528,8 @@ func generate_translations_keys() -> void:
|
|||||||
var key_regex = RegEx.new()
|
var key_regex = RegEx.new()
|
||||||
key_regex.compile("\\[ID:(?<key>.*?)\\]")
|
key_regex.compile("\\[ID:(?<key>.*?)\\]")
|
||||||
|
|
||||||
|
var compiled_lines: Dictionary = DMCompiler.compile_string(code_edit.text, "").lines
|
||||||
|
|
||||||
# Make list of known keys
|
# Make list of known keys
|
||||||
var known_keys = {}
|
var known_keys = {}
|
||||||
for i in range(0, lines.size()):
|
for i in range(0, lines.size()):
|
||||||
@@ -524,6 +552,7 @@ func generate_translations_keys() -> void:
|
|||||||
var l = line.strip_edges()
|
var l = line.strip_edges()
|
||||||
|
|
||||||
if not [DMConstants.TYPE_DIALOGUE, DMConstants.TYPE_RESPONSE].has(DMCompiler.get_line_type(l)): continue
|
if not [DMConstants.TYPE_DIALOGUE, DMConstants.TYPE_RESPONSE].has(DMCompiler.get_line_type(l)): continue
|
||||||
|
if not compiled_lines.has(str(i)): continue
|
||||||
|
|
||||||
if "[ID:" in line: continue
|
if "[ID:" in line: continue
|
||||||
|
|
||||||
@@ -538,7 +567,14 @@ func generate_translations_keys() -> void:
|
|||||||
key = known_keys.find_key(text)
|
key = known_keys.find_key(text)
|
||||||
else:
|
else:
|
||||||
var regex: DMCompilerRegEx = DMCompilerRegEx.new()
|
var regex: DMCompilerRegEx = DMCompilerRegEx.new()
|
||||||
key = regex.ALPHA_NUMERIC.sub(text.strip_edges(), "_", true).substr(0, 30)
|
if DMSettings.get_setting(DMSettings.USE_UUID_ONLY_FOR_IDS, false):
|
||||||
|
# Generate UUID only
|
||||||
|
var uuid = str(randi() % 1000000).sha1_text().substr(0, 12)
|
||||||
|
key = uuid.to_upper()
|
||||||
|
else:
|
||||||
|
# Generate text prefix + hash
|
||||||
|
var prefix_length = DMSettings.get_setting(DMSettings.AUTO_GENERATED_ID_PREFIX_LENGTH, 30)
|
||||||
|
key = regex.ALPHA_NUMERIC.sub(text.strip_edges(), "_", true).substr(0, prefix_length)
|
||||||
if key.begins_with("_"):
|
if key.begins_with("_"):
|
||||||
key = key.substr(1)
|
key = key.substr(1)
|
||||||
if key.ends_with("_"):
|
if key.ends_with("_"):
|
||||||
@@ -799,6 +835,16 @@ func show_search_form(is_enabled: bool) -> void:
|
|||||||
search_and_replace.focus_line_edit()
|
search_and_replace.focus_line_edit()
|
||||||
|
|
||||||
|
|
||||||
|
func run_test_scene(from_key: String) -> void:
|
||||||
|
DMSettings.set_user_value("run_title", from_key)
|
||||||
|
DMSettings.set_user_value("is_running_test_scene", true)
|
||||||
|
DMSettings.set_user_value("run_resource_path", current_file_path)
|
||||||
|
var test_scene_path: String = DMSettings.get_setting(DMSettings.CUSTOM_TEST_SCENE_PATH, "res://addons/dialogue_manager/test_scene.tscn")
|
||||||
|
if ResourceUID.has_id(ResourceUID.text_to_id(test_scene_path)):
|
||||||
|
test_scene_path = ResourceUID.get_id_path(ResourceUID.text_to_id(test_scene_path))
|
||||||
|
EditorInterface.play_custom_scene(test_scene_path)
|
||||||
|
|
||||||
|
|
||||||
### Signals
|
### Signals
|
||||||
|
|
||||||
|
|
||||||
@@ -831,9 +877,7 @@ func _on_open_menu_id_pressed(id: int) -> void:
|
|||||||
OPEN_OPEN:
|
OPEN_OPEN:
|
||||||
open_dialog.popup_centered()
|
open_dialog.popup_centered()
|
||||||
OPEN_QUICK:
|
OPEN_QUICK:
|
||||||
quick_open_files_list.files = Engine.get_meta("DMCache").get_files()
|
quick_open()
|
||||||
quick_open_dialog.popup_centered()
|
|
||||||
quick_open_files_list.focus_filter()
|
|
||||||
OPEN_CLEAR:
|
OPEN_CLEAR:
|
||||||
DMSettings.clear_recent_files()
|
DMSettings.clear_recent_files()
|
||||||
build_open_menu()
|
build_open_menu()
|
||||||
@@ -923,13 +967,14 @@ func _on_main_view_visibility_changed() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_new_button_pressed() -> void:
|
func _on_new_button_pressed() -> void:
|
||||||
new_dialog.current_file = "dialogue"
|
new_dialog.current_file = "untitled"
|
||||||
new_dialog.popup_centered()
|
new_dialog.popup_centered()
|
||||||
|
|
||||||
|
|
||||||
func _on_new_dialog_confirmed() -> void:
|
func _on_new_dialog_confirmed() -> void:
|
||||||
if new_dialog.current_file.get_basename() == "":
|
var path: String = new_dialog.current_path
|
||||||
var path = "res://untitled.dialogue"
|
if path.get_file() == ".dialogue":
|
||||||
|
path = "%s/untitled.dialogue" % path.get_basename()
|
||||||
new_file(path)
|
new_file(path)
|
||||||
open_file(path)
|
open_file(path)
|
||||||
|
|
||||||
@@ -960,8 +1005,8 @@ func _on_quick_open_files_list_file_double_clicked(file_path: String) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_quick_open_dialog_confirmed() -> void:
|
func _on_quick_open_dialog_confirmed() -> void:
|
||||||
if quick_open_files_list.current_file_path:
|
if quick_open_files_list.last_selected_file_path:
|
||||||
open_file(quick_open_files_list.current_file_path)
|
open_file(quick_open_files_list.last_selected_file_path)
|
||||||
|
|
||||||
|
|
||||||
func _on_save_all_button_pressed() -> void:
|
func _on_save_all_button_pressed() -> void:
|
||||||
@@ -983,6 +1028,10 @@ func _on_code_edit_text_changed() -> void:
|
|||||||
parse_timer.start(1)
|
parse_timer.start(1)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_code_edit_scroll_changed(value: int) -> void:
|
||||||
|
DMSettings.set_scroll(current_file_path, code_edit.scroll_vertical)
|
||||||
|
|
||||||
|
|
||||||
func _on_code_edit_active_title_change(title: String) -> void:
|
func _on_code_edit_active_title_change(title: String) -> void:
|
||||||
title_list.select_title(title)
|
title_list.select_title(title)
|
||||||
|
|
||||||
@@ -1033,11 +1082,7 @@ func _on_test_button_pressed() -> void:
|
|||||||
errors_dialog.popup_centered()
|
errors_dialog.popup_centered()
|
||||||
return
|
return
|
||||||
|
|
||||||
DMSettings.set_user_value("run_title", "")
|
run_test_scene("")
|
||||||
DMSettings.set_user_value("is_running_test_scene", true)
|
|
||||||
DMSettings.set_user_value("run_resource_path", current_file_path)
|
|
||||||
var test_scene_path: String = DMSettings.get_setting(DMSettings.CUSTOM_TEST_SCENE_PATH, "res://addons/dialogue_manager/test_scene.tscn")
|
|
||||||
EditorInterface.play_custom_scene(test_scene_path)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_test_line_button_pressed() -> void:
|
func _on_test_line_button_pressed() -> void:
|
||||||
@@ -1052,12 +1097,9 @@ func _on_test_line_button_pressed() -> void:
|
|||||||
for i in range(code_edit.get_cursor().y, code_edit.get_line_count()):
|
for i in range(code_edit.get_cursor().y, code_edit.get_line_count()):
|
||||||
if not code_edit.get_line(i).is_empty():
|
if not code_edit.get_line(i).is_empty():
|
||||||
line_to_run = i
|
line_to_run = i
|
||||||
break;
|
break
|
||||||
DMSettings.set_user_value("run_title", str(line_to_run))
|
|
||||||
DMSettings.set_user_value("is_running_test_scene", true)
|
run_test_scene(str(line_to_run))
|
||||||
DMSettings.set_user_value("run_resource_path", current_file_path)
|
|
||||||
var test_scene_path: String = DMSettings.get_setting(DMSettings.CUSTOM_TEST_SCENE_PATH, "res://addons/dialogue_manager/test_scene.tscn")
|
|
||||||
EditorInterface.play_custom_scene(test_scene_path)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_support_button_pressed() -> void:
|
func _on_support_button_pressed() -> void:
|
||||||
@@ -1139,3 +1181,22 @@ func _on_close_confirmation_dialog_custom_action(action: StringName) -> void:
|
|||||||
func _on_find_in_files_result_selected(path: String, cursor: Vector2, length: int) -> void:
|
func _on_find_in_files_result_selected(path: String, cursor: Vector2, length: int) -> void:
|
||||||
open_file(path)
|
open_file(path)
|
||||||
code_edit.select(cursor.y, cursor.x, cursor.y, cursor.x + length)
|
code_edit.select(cursor.y, cursor.x, cursor.y, cursor.x + length)
|
||||||
|
code_edit.set_line_as_center_visible(cursor.y)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_banner_image_gui_input(event: InputEvent) -> void:
|
||||||
|
if event.is_pressed():
|
||||||
|
OS.shell_open("https://bravestcoconut.com/wishlist")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_banner_new_button_pressed() -> void:
|
||||||
|
new_dialog.current_file = "untitled"
|
||||||
|
new_dialog.popup_centered()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_banner_quick_open_pressed() -> void:
|
||||||
|
quick_open()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_banner_examples_pressed() -> void:
|
||||||
|
OS.shell_open("https://itch.io/c/5226650/godot-dialogue-manager-example-projects")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=15 format=3 uid="uid://cbuf1q3xsse3q"]
|
[gd_scene load_steps=16 format=3 uid="uid://cbuf1q3xsse3q"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cipjcc7bkh1pc" path="res://addons/dialogue_manager/views/main_view.gd" id="1_h6qfq"]
|
[ext_resource type="Script" uid="uid://cipjcc7bkh1pc" path="res://addons/dialogue_manager/views/main_view.gd" id="1_h6qfq"]
|
||||||
[ext_resource type="PackedScene" uid="uid://civ6shmka5e8u" path="res://addons/dialogue_manager/components/code_edit.tscn" id="2_f73fm"]
|
[ext_resource type="PackedScene" uid="uid://civ6shmka5e8u" path="res://addons/dialogue_manager/components/code_edit.tscn" id="2_f73fm"]
|
||||||
@@ -8,20 +8,9 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://gr8nakpbrhby" path="res://addons/dialogue_manager/components/search_and_replace.tscn" id="6_ylh0t"]
|
[ext_resource type="PackedScene" uid="uid://gr8nakpbrhby" path="res://addons/dialogue_manager/components/search_and_replace.tscn" id="6_ylh0t"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cs8pwrxr5vxix" path="res://addons/dialogue_manager/components/errors_panel.tscn" id="7_5cvl4"]
|
[ext_resource type="PackedScene" uid="uid://cs8pwrxr5vxix" path="res://addons/dialogue_manager/components/errors_panel.tscn" id="7_5cvl4"]
|
||||||
[ext_resource type="Script" uid="uid://klpiq4tk3t7a" path="res://addons/dialogue_manager/components/code_edit_syntax_highlighter.gd" id="7_necsa"]
|
[ext_resource type="Script" uid="uid://klpiq4tk3t7a" path="res://addons/dialogue_manager/components/code_edit_syntax_highlighter.gd" id="7_necsa"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cnm67htuohhlo" path="res://addons/dialogue_manager/assets/banner.png" id="9_y6rqu"]
|
||||||
[ext_resource type="PackedScene" uid="uid://0n7hwviyyly4" path="res://addons/dialogue_manager/components/find_in_files.tscn" id="10_yold3"]
|
[ext_resource type="PackedScene" uid="uid://0n7hwviyyly4" path="res://addons/dialogue_manager/components/find_in_files.tscn" id="10_yold3"]
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_faxki"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 16,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 16
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="ImageTexture" id="ImageTexture_ka3gk"]
|
|
||||||
image = SubResource("Image_faxki")
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_y6rqu"]
|
[sub_resource type="Image" id="Image_y6rqu"]
|
||||||
data = {
|
data = {
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||||
@@ -31,10 +20,22 @@ data = {
|
|||||||
"width": 16
|
"width": 16
|
||||||
}
|
}
|
||||||
|
|
||||||
[sub_resource type="ImageTexture" id="ImageTexture_57eek"]
|
[sub_resource type="ImageTexture" id="ImageTexture_ka3gk"]
|
||||||
image = SubResource("Image_y6rqu")
|
image = SubResource("Image_y6rqu")
|
||||||
|
|
||||||
[sub_resource type="SyntaxHighlighter" id="SyntaxHighlighter_kb7f8"]
|
[sub_resource type="Image" id="Image_mpdoc"]
|
||||||
|
data = {
|
||||||
|
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||||
|
"format": "RGBA8",
|
||||||
|
"height": 16,
|
||||||
|
"mipmaps": false,
|
||||||
|
"width": 16
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="ImageTexture" id="ImageTexture_57eek"]
|
||||||
|
image = SubResource("Image_mpdoc")
|
||||||
|
|
||||||
|
[sub_resource type="SyntaxHighlighter" id="SyntaxHighlighter_xv2j4"]
|
||||||
script = ExtResource("7_necsa")
|
script = ExtResource("7_necsa")
|
||||||
|
|
||||||
[node name="MainView" type="Control"]
|
[node name="MainView" type="Control"]
|
||||||
@@ -132,7 +133,6 @@ size_flags_vertical = 3
|
|||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
|
||||||
|
|
||||||
[node name="FilesPopupMenu" type="PopupMenu" parent="Margin/Content/SidePanel/Bookmarks/FilesList"]
|
[node name="FilesPopupMenu" type="PopupMenu" parent="Margin/Content/SidePanel/Bookmarks/FilesList"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
@@ -158,6 +158,7 @@ text = "Insert"
|
|||||||
item_count = 15
|
item_count = 15
|
||||||
popup/item_0/text = "Wave BBCode"
|
popup/item_0/text = "Wave BBCode"
|
||||||
popup/item_0/icon = SubResource("ImageTexture_57eek")
|
popup/item_0/icon = SubResource("ImageTexture_57eek")
|
||||||
|
popup/item_0/id = 0
|
||||||
popup/item_1/text = "Shake BBCode"
|
popup/item_1/text = "Shake BBCode"
|
||||||
popup/item_1/icon = SubResource("ImageTexture_57eek")
|
popup/item_1/icon = SubResource("ImageTexture_57eek")
|
||||||
popup/item_1/id = 1
|
popup/item_1/id = 1
|
||||||
@@ -291,9 +292,9 @@ visible = false
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme_override_colors/current_line_color = Color(0.266667, 0.278431, 0.352941, 0.243137)
|
|
||||||
theme_override_colors/background_color = Color(0.156863, 0.164706, 0.211765, 1)
|
|
||||||
theme_override_colors/font_color = Color(0.972549, 0.972549, 0.94902, 1)
|
theme_override_colors/font_color = Color(0.972549, 0.972549, 0.94902, 1)
|
||||||
|
theme_override_colors/background_color = Color(0.156863, 0.164706, 0.211765, 1)
|
||||||
|
theme_override_colors/current_line_color = Color(0.266667, 0.278431, 0.352941, 0.243137)
|
||||||
theme_override_font_sizes/font_size = 14
|
theme_override_font_sizes/font_size = 14
|
||||||
theme_override_colors/bookmark_color = Color(1, 0.333333, 0.333333, 1)
|
theme_override_colors/bookmark_color = Color(1, 0.333333, 0.333333, 1)
|
||||||
text = "~ start
|
text = "~ start
|
||||||
@@ -312,12 +313,57 @@ Coco: Meow.
|
|||||||
|
|
||||||
=> END"
|
=> END"
|
||||||
scroll_smooth = true
|
scroll_smooth = true
|
||||||
syntax_highlighter = SubResource("SyntaxHighlighter_kb7f8")
|
syntax_highlighter = SubResource("SyntaxHighlighter_xv2j4")
|
||||||
|
|
||||||
[node name="ErrorsPanel" parent="Margin/Content/CodePanel" instance=ExtResource("7_5cvl4")]
|
[node name="ErrorsPanel" parent="Margin/Content/CodePanel" instance=ExtResource("7_5cvl4")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Banner" type="CenterContainer" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = 34.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="PanelContainer" type="VBoxContainer" parent="Banner"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 5
|
||||||
|
|
||||||
|
[node name="BannerImage" type="TextureRect" parent="Banner/PanelContainer"]
|
||||||
|
custom_minimum_size = Vector2(600, 200)
|
||||||
|
layout_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 2
|
||||||
|
texture = ExtResource("9_y6rqu")
|
||||||
|
expand_mode = 3
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="Banner/PanelContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 5
|
||||||
|
|
||||||
|
[node name="BannerNewButton" type="Button" parent="Banner/PanelContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "New Dialogue..."
|
||||||
|
|
||||||
|
[node name="BannerQuickOpen" type="Button" parent="Banner/PanelContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Quick open..."
|
||||||
|
|
||||||
|
[node name="BannerExamples" type="Button" parent="Banner/PanelContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Example projects..."
|
||||||
|
|
||||||
[node name="NewDialog" type="FileDialog" parent="."]
|
[node name="NewDialog" type="FileDialog" parent="."]
|
||||||
size = Vector2i(900, 750)
|
size = Vector2i(900, 750)
|
||||||
min_size = Vector2i(600, 500)
|
min_size = Vector2i(600, 500)
|
||||||
@@ -417,6 +463,10 @@ code_edit = NodePath("../../Margin/Content/CodePanel/CodeEdit")
|
|||||||
[connection signal="external_file_requested" from="Margin/Content/CodePanel/CodeEdit" to="." method="_on_code_edit_external_file_requested"]
|
[connection signal="external_file_requested" from="Margin/Content/CodePanel/CodeEdit" to="." method="_on_code_edit_external_file_requested"]
|
||||||
[connection signal="text_changed" from="Margin/Content/CodePanel/CodeEdit" to="." method="_on_code_edit_text_changed"]
|
[connection signal="text_changed" from="Margin/Content/CodePanel/CodeEdit" to="." method="_on_code_edit_text_changed"]
|
||||||
[connection signal="error_pressed" from="Margin/Content/CodePanel/ErrorsPanel" to="." method="_on_errors_panel_error_pressed"]
|
[connection signal="error_pressed" from="Margin/Content/CodePanel/ErrorsPanel" to="." method="_on_errors_panel_error_pressed"]
|
||||||
|
[connection signal="gui_input" from="Banner/PanelContainer/BannerImage" to="." method="_on_banner_image_gui_input"]
|
||||||
|
[connection signal="pressed" from="Banner/PanelContainer/HBoxContainer/BannerNewButton" to="." method="_on_banner_new_button_pressed"]
|
||||||
|
[connection signal="pressed" from="Banner/PanelContainer/HBoxContainer/BannerQuickOpen" to="." method="_on_banner_quick_open_pressed"]
|
||||||
|
[connection signal="pressed" from="Banner/PanelContainer/HBoxContainer/BannerExamples" to="." method="_on_banner_examples_pressed"]
|
||||||
[connection signal="confirmed" from="NewDialog" to="." method="_on_new_dialog_confirmed"]
|
[connection signal="confirmed" from="NewDialog" to="." method="_on_new_dialog_confirmed"]
|
||||||
[connection signal="file_selected" from="NewDialog" to="." method="_on_new_dialog_file_selected"]
|
[connection signal="file_selected" from="NewDialog" to="." method="_on_new_dialog_file_selected"]
|
||||||
[connection signal="file_selected" from="SaveDialog" to="." method="_on_save_dialog_file_selected"]
|
[connection signal="file_selected" from="SaveDialog" to="." method="_on_save_dialog_file_selected"]
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ runtime/advanced/uses_dotnet=true
|
|||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
window/size/viewport_width=1920
|
window/size/viewport_width=1280
|
||||||
window/size/viewport_height=1080
|
window/size/viewport_height=720
|
||||||
|
|
||||||
[dotnet]
|
[dotnet]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[remap]
|
[remap]
|
||||||
|
|
||||||
importer="dialogue_manager_compiler_14"
|
importer="dialogue_manager"
|
||||||
|
importer_version=15
|
||||||
type="Resource"
|
type="Resource"
|
||||||
uid="uid://lao0opxww3ib"
|
uid="uid://lao0opxww3ib"
|
||||||
path="res://.godot/imported/Dialogue.dialogue-176033575bc12c347010f3a30b2e302a.tres"
|
path="res://.godot/imported/Dialogue.dialogue-176033575bc12c347010f3a30b2e302a.tres"
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
@startuml EnemyLogic
|
@startuml EnemyLogic
|
||||||
state "EnemyLogic State" as Zennysoft_Game_Ma_EnemyLogic_State {
|
state "EnemyLogic State" as Zennysoft_Game_Ma_EnemyLogic_State {
|
||||||
state "Alive" as Zennysoft_Game_Ma_EnemyLogic_State_Alive {
|
state "Alive" as Zennysoft_Game_Ma_EnemyLogic_State_Alive {
|
||||||
|
state "Idle" as Zennysoft_Game_Ma_EnemyLogic_State_Idle
|
||||||
state "Activated" as Zennysoft_Game_Ma_EnemyLogic_State_Activated {
|
state "Activated" as Zennysoft_Game_Ma_EnemyLogic_State_Activated {
|
||||||
|
state "Patrolling" as Zennysoft_Game_Ma_EnemyLogic_State_Patrolling
|
||||||
state "FollowPlayer" as Zennysoft_Game_Ma_EnemyLogic_State_FollowPlayer
|
state "FollowPlayer" as Zennysoft_Game_Ma_EnemyLogic_State_FollowPlayer
|
||||||
state "Attacking" as Zennysoft_Game_Ma_EnemyLogic_State_Attacking
|
state "Attacking" as Zennysoft_Game_Ma_EnemyLogic_State_Attacking
|
||||||
state "Patrolling" as Zennysoft_Game_Ma_EnemyLogic_State_Patrolling
|
|
||||||
}
|
}
|
||||||
state "Idle" as Zennysoft_Game_Ma_EnemyLogic_State_Idle
|
|
||||||
}
|
}
|
||||||
state "Defeated" as Zennysoft_Game_Ma_EnemyLogic_State_Defeated
|
state "Defeated" as Zennysoft_Game_Ma_EnemyLogic_State_Defeated
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ script = ExtResource("1_ytcii")
|
|||||||
|
|
||||||
[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
|
[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
|
||||||
material = SubResource("ShaderMaterial_e75a2")
|
material = SubResource("ShaderMaterial_e75a2")
|
||||||
custom_minimum_size = Vector2(1280, 960)
|
custom_minimum_size = Vector2(1280, 720)
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@@ -94,7 +94,7 @@ stretch = true
|
|||||||
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
|
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
|
||||||
transparent_bg = true
|
transparent_bg = true
|
||||||
handle_input_locally = false
|
handle_input_locally = false
|
||||||
size = Vector2i(1920, 1080)
|
size = Vector2i(1280, 720)
|
||||||
render_target_update_mode = 4
|
render_target_update_mode = 4
|
||||||
|
|
||||||
[node name="PauseContainer" type="Node3D" parent="SubViewportContainer/SubViewport"]
|
[node name="PauseContainer" type="Node3D" parent="SubViewportContainer/SubViewport"]
|
||||||
@@ -119,6 +119,7 @@ wait_time = 30.0
|
|||||||
[node name="InGameUI" parent="." instance=ExtResource("5_lxtnp")]
|
[node name="InGameUI" parent="." instance=ExtResource("5_lxtnp")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
|
custom_minimum_size = Vector2(1280, 720)
|
||||||
|
|
||||||
[node name="InGameAudio" parent="." instance=ExtResource("6_qc71l")]
|
[node name="InGameAudio" parent="." instance=ExtResource("6_qc71l")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[remap]
|
[remap]
|
||||||
|
|
||||||
importer="dialogue_manager_compiler_12"
|
importer="dialogue_manager"
|
||||||
|
importer_version=15
|
||||||
type="Resource"
|
type="Resource"
|
||||||
uid="uid://b681mabgdkg6j"
|
uid="uid://b681mabgdkg6j"
|
||||||
path="res://.godot/imported/ran.dialogue-f0ecb078c74af14bf6b7b4a9926b74f8.tres"
|
path="res://.godot/imported/ran.dialogue-f0ecb078c74af14bf6b7b4a9926b74f8.tres"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[remap]
|
[remap]
|
||||||
|
|
||||||
importer="dialogue_manager_compiler_12"
|
importer="dialogue_manager"
|
||||||
|
importer_version=15
|
||||||
type="Resource"
|
type="Resource"
|
||||||
uid="uid://cf7ycgdiihyh"
|
uid="uid://cf7ycgdiihyh"
|
||||||
path="res://.godot/imported/ratdialogue.dialogue-7389c3591865c01b56ddf5a724bb1208.tres"
|
path="res://.godot/imported/ratdialogue.dialogue-7389c3591865c01b56ddf5a724bb1208.tres"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ script = ExtResource("1_sc13i")
|
|||||||
|
|
||||||
[node name="PlayerInfoUI" parent="." instance=ExtResource("4_46s5l")]
|
[node name="PlayerInfoUI" parent="." instance=ExtResource("4_46s5l")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(1024, 768)
|
custom_minimum_size = Vector2(1280, 720)
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
||||||
[node name="MiniMap" parent="." instance=ExtResource("2_6sfje")]
|
[node name="MiniMap" parent="." instance=ExtResource("2_6sfje")]
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ layout_mode = 3
|
|||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
|
offset_bottom = 40.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
script = ExtResource("1_d8yyu")
|
script = ExtResource("1_d8yyu")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene load_steps=14 format=3 uid="uid://bea2waybmgd6u"]
|
[gd_scene load_steps=14 format=3 uid="uid://bea2waybmgd6u"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://src/ui/in_game_ui/UseTeleportPrompt.cs" id="1_x3wkp"]
|
[ext_resource type="Script" uid="uid://dvn7g207w5jaj" path="res://src/ui/in_game_ui/UseTeleportPrompt.cs" id="1_x3wkp"]
|
||||||
[ext_resource type="FontFile" uid="uid://cm8j5vcdop5x0" path="res://src/ui/fonts/Mrs-Eaves-OT-Roman_31443.ttf" id="2_i6kb2"]
|
[ext_resource type="FontFile" uid="uid://cm8j5vcdop5x0" path="res://src/ui/fonts/Mrs-Eaves-OT-Roman_31443.ttf" id="2_i6kb2"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ahhj2"]
|
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ahhj2"]
|
||||||
@@ -102,9 +102,9 @@ tracks/1/keys = {
|
|||||||
|
|
||||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_7x216"]
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_7x216"]
|
||||||
_data = {
|
_data = {
|
||||||
"RESET": SubResource("Animation_xrfau"),
|
&"RESET": SubResource("Animation_xrfau"),
|
||||||
"fade_in": SubResource("Animation_efhb5"),
|
&"fade_in": SubResource("Animation_efhb5"),
|
||||||
"fade_out": SubResource("Animation_ibgld")
|
&"fade_out": SubResource("Animation_ibgld")
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="UseTeleportPrompt" type="Control"]
|
[node name="UseTeleportPrompt" type="Control"]
|
||||||
@@ -145,8 +145,8 @@ focus_neighbor_left = NodePath(".")
|
|||||||
focus_neighbor_top = NodePath(".")
|
focus_neighbor_top = NodePath(".")
|
||||||
focus_neighbor_right = NodePath(".")
|
focus_neighbor_right = NodePath(".")
|
||||||
focus_neighbor_bottom = NodePath("../NoButton")
|
focus_neighbor_bottom = NodePath("../NoButton")
|
||||||
theme_override_colors/font_focus_color = Color(1, 0.94902, 0, 1)
|
|
||||||
theme_override_colors/font_color = Color(0.737255, 0.705882, 0.690196, 1)
|
theme_override_colors/font_color = Color(0.737255, 0.705882, 0.690196, 1)
|
||||||
|
theme_override_colors/font_focus_color = Color(1, 0.94902, 0, 1)
|
||||||
theme_override_fonts/font = ExtResource("2_i6kb2")
|
theme_override_fonts/font = ExtResource("2_i6kb2")
|
||||||
theme_override_font_sizes/font_size = 50
|
theme_override_font_sizes/font_size = 50
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_1tca4")
|
theme_override_styles/focus = SubResource("StyleBoxEmpty_1tca4")
|
||||||
@@ -162,8 +162,8 @@ focus_neighbor_left = NodePath(".")
|
|||||||
focus_neighbor_top = NodePath("../YesButton")
|
focus_neighbor_top = NodePath("../YesButton")
|
||||||
focus_neighbor_right = NodePath(".")
|
focus_neighbor_right = NodePath(".")
|
||||||
focus_neighbor_bottom = NodePath(".")
|
focus_neighbor_bottom = NodePath(".")
|
||||||
theme_override_colors/font_focus_color = Color(1, 0.94902, 0, 1)
|
|
||||||
theme_override_colors/font_color = Color(0.737255, 0.705882, 0.690196, 1)
|
theme_override_colors/font_color = Color(0.737255, 0.705882, 0.690196, 1)
|
||||||
|
theme_override_colors/font_focus_color = Color(1, 0.94902, 0, 1)
|
||||||
theme_override_fonts/font = ExtResource("2_i6kb2")
|
theme_override_fonts/font = ExtResource("2_i6kb2")
|
||||||
theme_override_font_sizes/font_size = 50
|
theme_override_font_sizes/font_size = 50
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_yoep7")
|
theme_override_styles/focus = SubResource("StyleBoxEmpty_yoep7")
|
||||||
@@ -175,5 +175,5 @@ text = "No"
|
|||||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
libraries = {
|
libraries = {
|
||||||
"": SubResource("AnimationLibrary_7x216")
|
&"": SubResource("AnimationLibrary_7x216")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user