debug console init
parent
213358a2ba
commit
ad29c9cd29
|
@ -0,0 +1,29 @@
|
|||
namespace SupaLidlGame.Debug;
|
||||
|
||||
internal sealed class CharIterator : Iterator<char>
|
||||
{
|
||||
public CharIterator(string str) : base(str.ToCharArray())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public CharIterator(char[] chars) : base(chars)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override char MoveNext()
|
||||
{
|
||||
char c = base.MoveNext();
|
||||
if (c == '\n')
|
||||
{
|
||||
Line++;
|
||||
Column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Column++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
|
@ -2,21 +2,97 @@ using Godot;
|
|||
|
||||
namespace SupaLidlGame.Debug;
|
||||
|
||||
public partial class DebugConsole : Node
|
||||
public sealed partial class DebugConsole : Control
|
||||
{
|
||||
public void SetProp(
|
||||
Utils.World world,
|
||||
string entityName,
|
||||
string property,
|
||||
string value)
|
||||
private Node _context;
|
||||
public Node Context
|
||||
{
|
||||
var ent = world.CurrentMap.Entities.GetNodeOrNull(entityName);
|
||||
if (ent is not null)
|
||||
get => _context;
|
||||
private set
|
||||
{
|
||||
ent.Set(property, value);
|
||||
if (value is not null)
|
||||
{
|
||||
_context = value;
|
||||
if (_entry is not null)
|
||||
{
|
||||
_entry.PlaceholderText = "Enter Godot expression from " +
|
||||
_context.GetPath();
|
||||
GetParent<Window>().Title = "Supa Developer Console: " +
|
||||
_context.GetPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Entry _entry;
|
||||
|
||||
private RichTextLabel _output;
|
||||
|
||||
private Node ctx => Context;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_entry = GetNode<Entry>("%Entry");
|
||||
_output = GetNode<RichTextLabel>("%Output");
|
||||
Context = Utils.World.Instance;
|
||||
|
||||
_entry.ConsoleInput += (string input) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Execute(input);
|
||||
}
|
||||
catch (InterpreterException ex)
|
||||
{
|
||||
_output.Text += ex.Message + '\n';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
enum PathType
|
||||
{
|
||||
Node,
|
||||
Property
|
||||
};
|
||||
|
||||
public Variant From(NodePath path)
|
||||
{
|
||||
CharIterator iterator = new(path);
|
||||
Variant variant = Context ?? this;
|
||||
foreach (var subpath in NodePathParser.ParseNodePath(iterator))
|
||||
{
|
||||
if (variant.VariantType == Variant.Type.Object)
|
||||
{
|
||||
if (variant.AsGodotObject() is Node n)
|
||||
{
|
||||
if (subpath.Type == NodePathTokenType.Node)
|
||||
{
|
||||
if (subpath.Path != "")
|
||||
{
|
||||
variant = n.GetNode(subpath.Path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
variant = n.GetIndexed(subpath.Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
public void SetProp(NodePath path, Variant value)
|
||||
{
|
||||
var node = GetNode(path.GetAsPropertyPath());
|
||||
//var ent = CurrentMap.Entities.GetNodeOrNull(entityName);
|
||||
//if (ent is not null)
|
||||
//{
|
||||
// ent.Set(property, value);
|
||||
//}
|
||||
}
|
||||
|
||||
public string CallMethod(
|
||||
Utils.World world,
|
||||
string entityName,
|
||||
|
@ -31,4 +107,54 @@ public partial class DebugConsole : Node
|
|||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public void Print(string text)
|
||||
{
|
||||
GD.Print(text);
|
||||
}
|
||||
|
||||
public void Execute(string str)
|
||||
{
|
||||
str = Sanitizer.Sanitize(str);
|
||||
string inputMirror = $"[b]{Context.GetPath()}:[/b] {str}";
|
||||
_output.Text += inputMirror + "\n";
|
||||
var context = Context;
|
||||
|
||||
Godot.Expression exp = new();
|
||||
|
||||
string[] reserved = { "from", "set_context", "context" };
|
||||
Godot.Collections.Array reservedMap = new();
|
||||
reservedMap.Add(new Callable(this, MethodName.From));
|
||||
reservedMap.Add(new Callable(this, MethodName.SetContext));
|
||||
reservedMap.Add(Context);
|
||||
|
||||
var err = exp.Parse(str, reserved);
|
||||
if (err != Error.Ok)
|
||||
{
|
||||
throw new InterpreterException(
|
||||
"Error occurred while parsing Godot.Expression: \n" +
|
||||
exp.GetErrorText(),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
Variant result = exp.Execute(reservedMap, context);
|
||||
if (exp.HasExecuteFailed())
|
||||
{
|
||||
throw new InterpreterException(
|
||||
"Error occurred while evaluating Godot.Expression: \n" +
|
||||
exp.GetErrorText(),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
// send result to output
|
||||
if (result.VariantType != Variant.Type.Nil)
|
||||
{
|
||||
_output.Text += result + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
public void SetContext(Node node)
|
||||
{
|
||||
Context = node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using Godot;
|
||||
|
||||
namespace SupaLidlGame.Debug;
|
||||
|
||||
public partial class Entry : LineEdit
|
||||
{
|
||||
[Signal]
|
||||
public delegate void ConsoleInputEventHandler(string input);
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
GuiInput += OnGuiInput;
|
||||
}
|
||||
|
||||
public void OnGuiInput(InputEvent @event)
|
||||
{
|
||||
if (@event is InputEventKey key)
|
||||
{
|
||||
if (key.KeyLabel == Key.Enter && !key.Pressed)
|
||||
{
|
||||
EmitSignal(SignalName.ConsoleInput, Text);
|
||||
|
||||
if (!key.CtrlPressed)
|
||||
{
|
||||
Text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace SupaLidlGame.Debug;
|
||||
|
||||
public class Iterator<T> where T : struct
|
||||
{
|
||||
public int Line { get; protected set; } = 1;
|
||||
|
||||
public int Column { get; protected set; } = 0;
|
||||
|
||||
public int Index { get; protected set; } = -1;
|
||||
|
||||
protected List<T> _elements;
|
||||
|
||||
public Iterator(T[] elements)
|
||||
{
|
||||
_elements = new List<T>(elements);
|
||||
}
|
||||
|
||||
public Iterator(List<T> elements)
|
||||
{
|
||||
_elements = new List<T>(elements);
|
||||
}
|
||||
|
||||
public T GetNext(int offset = 0)
|
||||
{
|
||||
if (Index + offset + 1 < _elements.Count)
|
||||
{
|
||||
return _elements[Index + offset + 1];
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual T MoveNext()
|
||||
{
|
||||
T next = GetNext();
|
||||
Index++;
|
||||
return next;
|
||||
}
|
||||
|
||||
public virtual void MoveBack()
|
||||
{
|
||||
Index--;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SupaLidlGame.Debug;
|
||||
|
||||
internal static class NodePathParser
|
||||
{
|
||||
internal static IEnumerable<NodePathToken> ParseNodePath(CharIterator iterator)
|
||||
{
|
||||
// Some/Node/Path:And:Property/More/Paths
|
||||
// ->
|
||||
// Some/Node/Path (Node)
|
||||
// :And:Property (Property)
|
||||
// More/Paths (Node)
|
||||
|
||||
NodePathTokenType curType = NodePathTokenType.Node;
|
||||
string path = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char curChar = iterator.MoveNext();
|
||||
|
||||
if (curChar == ':')
|
||||
{
|
||||
// if we have been parsing a nodepath, yield a nodepath
|
||||
if (curType == NodePathTokenType.Node)
|
||||
{
|
||||
if (path.Length > 0)
|
||||
{
|
||||
yield return new NodePathToken(path, curType);
|
||||
path = "";
|
||||
curType = NodePathTokenType.Property;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
path += curChar;
|
||||
}
|
||||
}
|
||||
else if (curChar == '/')
|
||||
{
|
||||
// if we have been parsing property, yield a property
|
||||
if (curType == NodePathTokenType.Property)
|
||||
{
|
||||
yield return new NodePathToken(path, curType);
|
||||
path = "";
|
||||
curType = NodePathTokenType.Node;
|
||||
}
|
||||
else
|
||||
{
|
||||
path += curChar;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
path += curChar;
|
||||
}
|
||||
}
|
||||
|
||||
// reached the end
|
||||
if (path.Length > 0)
|
||||
{
|
||||
yield return new NodePathToken(path, curType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using Godot;
|
||||
|
||||
public enum NodePathTokenType
|
||||
{
|
||||
Node,
|
||||
Property
|
||||
}
|
||||
|
||||
public struct NodePathToken
|
||||
{
|
||||
public NodePath Path { get; set; }
|
||||
|
||||
public NodePathTokenType Type { get; set; }
|
||||
|
||||
public NodePathToken(NodePath path, NodePathTokenType type)
|
||||
{
|
||||
Path = path;
|
||||
Type = type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
using Godot;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SupaLidlGame.Debug;
|
||||
|
||||
public static class Sanitizer
|
||||
{
|
||||
private static Regex _nonAlphanum = new("[^a-zA-Z0-9_]");
|
||||
|
||||
private static Regex _nonNodeName = new("[^a-zA-Z0-9_\\-\\/]");
|
||||
|
||||
private static string ScanString(CharIterator iterator)
|
||||
{
|
||||
string ret = "";
|
||||
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.MoveNext();
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
char escape = iterator.MoveNext();
|
||||
|
||||
switch (escape)
|
||||
{
|
||||
case 'n':
|
||||
ret += '\n';
|
||||
break;
|
||||
case 't':
|
||||
ret += '\t';
|
||||
break;
|
||||
case '\0':
|
||||
throw new InterpreterException("Unexpected EOL",
|
||||
iterator.Line, iterator.Column); default:
|
||||
ret += escape;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret += c;
|
||||
}
|
||||
throw new InterpreterException("Unexpected EOL, expected '\"'",
|
||||
iterator.Line, iterator.Column);
|
||||
}
|
||||
|
||||
private static string ScanNodePath(CharIterator iterator)
|
||||
{
|
||||
string ret = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.MoveNext();
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
return ScanString(iterator);
|
||||
}
|
||||
else if (_nonNodeName.IsMatch(c.ToString()))
|
||||
{
|
||||
iterator.MoveBack();
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static string ScanUntilOrEOL(CharIterator iterator, char delim)
|
||||
{
|
||||
string ret = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.GetNext();
|
||||
if (c == delim)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static string ScanGlobalCommand(CharIterator iterator)
|
||||
{
|
||||
string ret = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.MoveNext();
|
||||
if (_nonAlphanum.IsMatch(c.ToString()))
|
||||
{
|
||||
iterator.MoveBack();
|
||||
return ret;
|
||||
}
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string Sanitize(string input)
|
||||
{
|
||||
CharIterator iterator = new(input);
|
||||
string ret = "";
|
||||
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.MoveNext();
|
||||
|
||||
if (c == '$')
|
||||
{
|
||||
string nodePath = ScanNodePath(iterator);
|
||||
ret += $"from.call(\"{nodePath}\")";
|
||||
}
|
||||
else if (c == '"')
|
||||
{
|
||||
string str = ScanString(iterator);
|
||||
ret += $"\"{str}\"";
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
// \global -> global.call
|
||||
string command = ScanGlobalCommand(iterator);
|
||||
ret += $"{command}.call";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += c;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
namespace SupaLidlGame.Debug;
|
||||
|
||||
public enum TokenType
|
||||
{
|
||||
None,
|
||||
Identifier,
|
||||
String,
|
||||
GodotExpression,
|
||||
Command,
|
||||
End
|
||||
};
|
||||
|
||||
public struct Token
|
||||
{
|
||||
public TokenType Type { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public int Line { get; set; }
|
||||
|
||||
public int Column { get; set; }
|
||||
|
||||
public Token(TokenType type, string value, int line, int col)
|
||||
{
|
||||
Type = type;
|
||||
Value = value;
|
||||
Line = line;
|
||||
Column = col;
|
||||
}
|
||||
|
||||
public bool CompareTypeValue(Token token)
|
||||
{
|
||||
return Type == token.Type && Value == token.Value;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(Token left, Token right) => left.Equals(right);
|
||||
|
||||
public static bool operator !=(Token left, Token right) => !left.Equals(right);
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace SupaLidlGame.Debug;
|
||||
|
||||
internal sealed class Tokenizer
|
||||
{
|
||||
private static readonly HashSet<char> WHITESPACE = new HashSet<char> { ' ', '\n' };
|
||||
|
||||
private static string ScanString(CharIterator iterator)
|
||||
{
|
||||
string ret = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.MoveNext();
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
char escape = iterator.MoveNext();
|
||||
|
||||
switch (escape)
|
||||
{
|
||||
case 'n':
|
||||
ret += '\n';
|
||||
break;
|
||||
case 't':
|
||||
ret += '\t';
|
||||
break;
|
||||
case '\0':
|
||||
throw new InterpreterException("Unexpected EOL",
|
||||
iterator.Line, iterator.Column);
|
||||
default:
|
||||
ret += escape;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret += c;
|
||||
}
|
||||
throw new InterpreterException("Unexpected EOL, expected '\"'",
|
||||
iterator.Line, iterator.Column);
|
||||
}
|
||||
|
||||
private static string ScanNodePath(CharIterator iterator)
|
||||
{
|
||||
string ret = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.GetNext();
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
ret += ScanString(iterator);
|
||||
}
|
||||
else if (WHITESPACE.Contains(c))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
private static string ScanUntil(CharIterator iterator)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
private static string ScanExpression(CharIterator iterator)
|
||||
{
|
||||
int level = 0;
|
||||
string exp = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.GetNext();
|
||||
|
||||
if (c == '(')
|
||||
{
|
||||
level++;
|
||||
}
|
||||
else if (c == ')')
|
||||
{
|
||||
level--;
|
||||
}
|
||||
|
||||
if (level < 0)
|
||||
{
|
||||
return exp;
|
||||
}
|
||||
|
||||
exp += c;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
private static string ScanUntilOrEOL(CharIterator iterator, char delim)
|
||||
{
|
||||
string ret = "";
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char c = iterator.GetNext();
|
||||
if (c == delim)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static IEnumerable<Token> Tokenize(CharIterator iterator)
|
||||
{
|
||||
System.Diagnostics.Debug.Print("hi");
|
||||
while (iterator.GetNext() != '\0')
|
||||
{
|
||||
char curChar = iterator.MoveNext();
|
||||
System.Diagnostics.Debug.Print(curChar.ToString());
|
||||
|
||||
int line = iterator.Line;
|
||||
int col = iterator.Column;
|
||||
|
||||
if (WHITESPACE.Contains(curChar))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (curChar == '\\')
|
||||
{
|
||||
string command = ScanUntilOrEOL(iterator, ' ');
|
||||
if (command == "")
|
||||
{
|
||||
throw new InterpreterException(
|
||||
"Expected a command name",
|
||||
iterator.Line,
|
||||
iterator.Column);
|
||||
}
|
||||
yield return new Token(TokenType.Command,
|
||||
command,
|
||||
line,
|
||||
col);
|
||||
}
|
||||
else if (curChar == '(')
|
||||
{
|
||||
string exp = ScanExpression(iterator);
|
||||
yield return new Token(TokenType.GodotExpression,
|
||||
exp,
|
||||
line,
|
||||
col);
|
||||
}
|
||||
else if (curChar == '"')
|
||||
{
|
||||
yield return new Token(TokenType.String,
|
||||
ScanString(iterator),
|
||||
line,
|
||||
col);
|
||||
}
|
||||
else
|
||||
{
|
||||
// parse this as expression
|
||||
string exp = ScanUntilOrEOL(iterator, ' ');
|
||||
yield return new Token(TokenType.GodotExpression,
|
||||
exp,
|
||||
line,
|
||||
col);
|
||||
}
|
||||
/*
|
||||
else if (curChar == '$')
|
||||
{
|
||||
yield return new Token(TokenType.NodePath,
|
||||
ScanNodePath(iterator),
|
||||
line,
|
||||
col);
|
||||
}
|
||||
*/
|
||||
}
|
||||
yield return new Token(TokenType.End, "",
|
||||
iterator.Line, iterator.Column);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
namespace SupaLidlGame;
|
||||
|
||||
public class InterpreterException : System.Exception
|
||||
{
|
||||
public int Line { get; set; }
|
||||
public int Column { get; set; }
|
||||
|
||||
public InterpreterException(string msg, int line, int column) : base(msg)
|
||||
{
|
||||
Line = line;
|
||||
Column = column;
|
||||
}
|
||||
}
|
|
@ -4,28 +4,6 @@ namespace SupaLidlGame.Extensions;
|
|||
|
||||
public static class NodeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Iterates through each ancestor until it finds an ancestor of type
|
||||
/// <c>T</c>
|
||||
/// </summary>
|
||||
[System.Obsolete]
|
||||
public static T GetAncestorDeprecated<T>(this Node node) where T : Node
|
||||
{
|
||||
Node parent;
|
||||
|
||||
while ((parent = node.GetParent()) != null)
|
||||
{
|
||||
if (parent is T t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
node = parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A version <c>GetNode</c> that returns null rather than cause an
|
||||
/// exception if the node is not found or is not the same type.
|
||||
|
|
|
@ -29,6 +29,7 @@ stretch = true
|
|||
stretch_shrink = 3
|
||||
|
||||
[node name="UIViewport" type="SubViewport" parent="SubViewportContainer"]
|
||||
disable_3d = true
|
||||
transparent_bg = true
|
||||
handle_input_locally = false
|
||||
size = Vector2i(640, 360)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
[gd_scene format=3 uid="uid://be8bc4eivsg4s"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://be8bc4eivsg4s"]
|
||||
|
||||
[ext_resource type="Script" path="res://Debug/DebugConsole.cs" id="1_3fw5a"]
|
||||
[ext_resource type="Script" path="res://Debug/Entry.cs" id="2_kdlsh"]
|
||||
|
||||
[node name="DebugUI" type="Control"]
|
||||
layout_mode = 3
|
||||
|
@ -8,11 +11,47 @@ anchor_bottom = 1.0
|
|||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 12
|
||||
anchor_top = 1.0
|
||||
[node name="Window" type="Window" parent="."]
|
||||
disable_3d = true
|
||||
gui_embed_subwindows = true
|
||||
title = "Supa Developer Console"
|
||||
position = Vector2i(32, 32)
|
||||
size = Vector2i(1280, 720)
|
||||
always_on_top = true
|
||||
|
||||
[node name="DebugConsole" type="Control" parent="Window"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_3fw5a")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Window/DebugConsole"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Output" type="RichTextLabel" parent="Window/DebugConsole/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_font_sizes/normal_font_size = 24
|
||||
theme_override_font_sizes/bold_font_size = 24
|
||||
bbcode_enabled = true
|
||||
text = "[b]/root/World:[/b] \\echo :CurrentPlayer:Health
|
||||
100
|
||||
"
|
||||
scroll_following = true
|
||||
|
||||
[node name="Entry" type="LineEdit" parent="Window/DebugConsole/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 24
|
||||
placeholder_text = "Enter a GDScript expression or \\command..."
|
||||
draw_control_chars = true
|
||||
script = ExtResource("2_kdlsh")
|
||||
|
|
|
@ -23,8 +23,8 @@ EventBus="*res://Events/EventBus.cs"
|
|||
BaseUI="*res://UI/Base.tscn"
|
||||
World="*res://Scenes/Level.tscn"
|
||||
AudioManager="*res://Audio/AudioManager.cs"
|
||||
DebugConsole="*res://Debug/DebugConsole.cs"
|
||||
Panku="*res://addons/panku_console/console.tscn"
|
||||
DebugUi="*res://UI/Debug/DebugUI.tscn"
|
||||
|
||||
[dialogue_manager]
|
||||
|
||||
|
|
Loading…
Reference in New Issue