This commit is contained in:
Nyx
2025-08-26 13:24:16 -06:00
57 changed files with 5143 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="HealthResource" load_steps=2 format=3 uid="uid://bmm74325qvi5l"]
[ext_resource type="Script" uid="uid://yoaga45bppw8" path="res://Scripts/Resources/health_data_resource.gd" id="1_aml5a"]
[resource]
script = ExtResource("1_aml5a")
max_hp = 100
regen_per_second = 0.0
metadata/_custom_type_script = "uid://yoaga45bppw8"

View File

@@ -0,0 +1,38 @@
[gd_scene load_steps=7 format=3 uid="uid://djvqisfxi1l0b"]
[ext_resource type="Script" uid="uid://dpd2la1tonipl" path="res://Scripts/Characters/player.gd" id="1_gjot8"]
[ext_resource type="Script" uid="uid://gihel4imt7xk" path="res://Scripts/Components/health_component.gd" id="2_0el0d"]
[ext_resource type="Resource" uid="uid://bmm74325qvi5l" path="res://Resources/Data/Character/Player Defaults/player_health.tres" id="3_o5en2"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_gjot8"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gjot8"]
albedo_color = Color(1, 0, 1, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_gjot8"]
material = SubResource("StandardMaterial3D_gjot8")
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_gjot8")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_gjot8")
[node name="Pivot" type="Node3D" parent="."]
[node name="MeshInstance3D" type="MeshInstance3D" parent="Pivot"]
mesh = SubResource("CapsuleMesh_gjot8")
skeleton = NodePath("../..")
[node name="SpringArm3D" type="SpringArm3D" parent="Pivot"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
spring_length = 0.0
[node name="Camera3D" type="Camera3D" parent="Pivot/SpringArm3D"]
[node name="SteamAudioListener" type="SteamAudioListener" parent="Pivot/SpringArm3D/Camera3D"]
[node name="HealthComponenent" type="Node" parent="."]
script = ExtResource("2_0el0d")
data = ExtResource("3_o5en2")
metadata/_custom_type_script = "uid://gihel4imt7xk"

52
demo/Scenes/game.tscn Normal file
View File

@@ -0,0 +1,52 @@
[gd_scene load_steps=6 format=3 uid="uid://dtccwj1qujhxp"]
[ext_resource type="PackedScene" uid="uid://djvqisfxi1l0b" path="res://Scenes/Characters/Player.tscn" id="1_ebmjs"]
[ext_resource type="Texture2D" uid="uid://bj23bn0s4mt0d" path="res://icon.svg" id="1_qxrlw"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wrm1d"]
albedo_texture = ExtResource("1_qxrlw")
[sub_resource type="PlaneMesh" id="PlaneMesh_2poj3"]
material = SubResource("StandardMaterial3D_wrm1d")
size = Vector2(200, 200)
subdivide_width = 2
subdivide_depth = 2
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ebmjs"]
[node name="Game" type="Node3D"]
[node name="Floor" type="Node3D" parent="."]
[node name="MeshInstance3D" type="MeshInstance3D" parent="Floor"]
mesh = SubResource("PlaneMesh_2poj3")
skeleton = NodePath("../..")
[node name="StaticBody3D" type="StaticBody3D" parent="Floor/MeshInstance3D"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor/MeshInstance3D/StaticBody3D"]
shape = SubResource("WorldBoundaryShape3D_ebmjs")
[node name="SteamAudioStaticMesh" type="SteamAudioStaticMesh" parent="Floor/MeshInstance3D"]
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Floor"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 199.503, 0, 0)
mesh = SubResource("PlaneMesh_2poj3")
skeleton = NodePath("../..")
[node name="StaticBody3D" type="StaticBody3D" parent="Floor/MeshInstance3D2"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor/MeshInstance3D2/StaticBody3D"]
shape = SubResource("WorldBoundaryShape3D_ebmjs")
[node name="SteamAudioStaticMesh" type="SteamAudioStaticMesh" parent="Floor/MeshInstance3D2"]
[node name="Player" parent="." instance=ExtResource("1_ebmjs")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.039711, 1, -0.146652)
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.703544, 0.710652, 0, -0.710652, 0.703544, 0, 7.28685, 0)
[node name="SteamAudioManager" type="SteamAudioManager" parent="."]
[node name="SteamAudioSource" type="SteamAudioSource" parent="."]

View File

@@ -0,0 +1,52 @@
extends CharacterBody3D
class_name PlayerController
@onready var springarm:SpringArm3D = $Pivot/SpringArm3D
@export_category("Movement")
@export var speed:float = 14.0
@export var fall_acceleration:float = 75.0
@export var jump_speed:float = 10
@export_category("Camera")
@export var max_look_up:float = 80.0
@export var max_look_down:float = -80.0
@export var mouse_sensitivity:float= 0.15
@export var joystick_sensitivity:float = 100.00
var target_velocity:Vector3 = Vector3.ZERO
func _ready() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _physics_process(delta: float) -> void:
var direction_2d = Input.get_vector(&"move_left",&"move_right",&"move_back",&"move_forward")
var direction_3d = (transform.basis.x * direction_2d.x + -transform.basis.z * direction_2d.y).normalized()
velocity.x = direction_3d.x*speed
velocity.z = direction_3d.z*speed
if not is_on_floor():
velocity.y -= fall_acceleration * delta
move_and_slide()
func _process(delta: float) -> void:
var horiz = Input.get_axis(&"look_right",&"look_left")
var vert = Input.get_axis(&"look_down",&"look_up")
var camera_direction = Input.get_vector(&"look_right",&"look_left",&"look_down",&"look_up")
if camera_direction != Vector2.ZERO:
_apply_look(Vector2(horiz, vert)*(joystick_sensitivity*delta))
func _input(event: InputEvent) -> void:
# mouse look (unchanged)
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
_apply_look(Vector2(-event.relative.x, -event.relative.y) * mouse_sensitivity)
if event.is_action_pressed(&"jump") and is_on_floor():
_jump()
func _apply_look(delta: Vector2) -> void:
rotate_y(deg_to_rad(delta.x))
var new_pitch = springarm.rotation_degrees.x + delta.y
springarm.rotation_degrees.x = clamp(new_pitch,max_look_down,max_look_up)
func _jump() -> void:
velocity.y = jump_speed

View File

@@ -0,0 +1 @@
uid://dpd2la1tonipl

View File

@@ -0,0 +1,21 @@
extends Node
class_name HealthComponenent
signal hp_changed(current_hp)
signal died()
@export var data: HealthResource
var current_hp: float
func _ready() -> void:
current_hp = data.max_hp
func _take_damage(amount:float )->void:
current_hp = max(current_hp-amount,0)
emit_signal(&"hp_changed", current_hp)
if current_hp == 0:
emit_signal(&"died")
func _heal(amount:float)->void:
current_hp= min(current_hp+amount, data.max_hp)
emit_signal(&"hp_changed",current_hp)

View File

@@ -0,0 +1 @@
uid://gihel4imt7xk

View File

@@ -0,0 +1,6 @@
extends Resource
class_name HealthResource
@export var max_hp:int = 100
@export var regen_per_second:float = 0.0

View File

@@ -0,0 +1 @@
uid://yoaga45bppw8

View File

@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

View File

@@ -0,0 +1,9 @@
extends SceneTree
const CSharpGDExtensionBindgen = preload("csharp_gdextension_bindgen.gd")
func _initialize():
CSharpGDExtensionBindgen.generate_gdextension_csharp_scripts.callv(OS.get_cmdline_user_args())
quit()

View File

@@ -0,0 +1 @@
uid://najinjv0m445

View File

@@ -0,0 +1,849 @@
## GDExtension to C# binding generator
##
## The C# classes generated are not attached scripts, but rather wrappers that
## forward execution to a GodotObject using dynamic calls.
##
## Use the "Project -> Tools -> Generate C# GDExtension Bindings" menu item to
## generate C# bindings from GDExtension.
@tool
extends EditorPlugin
const MENU_ITEM_NAME = "Generate C# GDExtension Bindings"
const GENERATED_NAMESPACE = "GDExtensionBindgen"
const GENERATED_SCRIPTS_FOLDER = "res://GDExtensionBindgen"
enum StringNameType {
PROPERTY_NAME,
METHOD_NAME,
SIGNAL_NAME,
}
const StringNameTypeName = {
StringNameType.PROPERTY_NAME: "PropertyName",
StringNameType.METHOD_NAME: "MethodName",
StringNameType.SIGNAL_NAME: "SignalName",
}
const PASCAL_CASE_NAME_OVERRIDES = {
"BitMap": "Bitmap",
"JSONRPC": "JsonRpc",
"Object": "GodotObject",
"OpenXRIPBinding": "OpenXRIPBinding",
"SkeletonModification2DCCDIK": "SkeletonModification2DCcdik",
"SkeletonModification2DFABRIK": "SkeletonModification2DFabrik",
"SkeletonModification3DCCDIK": "SkeletonModification3DCcdik",
"SkeletonModification3DFABRIK": "SkeletonModification3DFabrik",
"System": "System_",
"Thread": "GodotThread",
}
const PASCAL_CASE_PART_OVERRIDES = {
"AA": "AA", # Anti Aliasing
"AO": "AO", # Ambient Occlusion
"FILENAME": "FileName",
"FADEIN": "FadeIn",
"FADEOUT": "FadeOut",
"FX": "FX",
"GI": "GI", # Global Illumination
"GZIP": "GZip",
"HBOX": "HBox", # Horizontal Box
"ID": "Id",
"IO": "IO", # Input/Output
"IP": "IP", # Internet Protocol
"IV": "IV", # Initialization Vector
"MACOS": "MacOS",
"NODEPATH": "NodePath",
"SPIRV": "SpirV",
"STDIN": "StdIn",
"STDOUT": "StdOut",
"USERNAME": "UserName",
"UV": "UV",
"UV2": "UV2",
"VBOX": "VBox", # Vertical Box
"WHITESPACE": "WhiteSpace",
"WM": "WM",
"XR": "XR",
"XRAPI": "XRApi",
}
func _enter_tree():
add_tool_menu_item(MENU_ITEM_NAME, generate_gdextension_csharp_scripts)
func _exit_tree():
remove_tool_menu_item(MENU_ITEM_NAME)
static func generate_csharp_script(
cls_name: StringName,
output_dir := GENERATED_SCRIPTS_FOLDER,
name_space := GENERATED_NAMESPACE,
):
var class_is_editor_only = _is_editor_extension_class(cls_name)
var parent_class = ClassDB.get_parent_class(cls_name)
var parent_class_is_extension = _is_extension_class(parent_class)
var no_inheritance = parent_class_is_extension
var engine_class = _first_non_extension_parent(cls_name)
var regions = PackedStringArray()
# Engine object used for calling engine methods
if not parent_class_is_extension:
regions.append("// Engine object used for calling engine methods\nprotected %s _object;" % parent_class)
# Constructors
var ctor_fmt
if parent_class_is_extension:
ctor_fmt = """
public {cls_name}() : base(NativeName)
{
}
protected {cls_name}(StringName @class) : base(@class)
{
}
protected {cls_name}(Variant variant) : base(variant)
{
}
protected {cls_name}([NotNull] {engine_class} @object) : base(@object)
{
}
"""
else:
ctor_fmt = """
public {cls_name}() : this(NativeName)
{
}
protected {cls_name}(StringName @class) : this(ClassDB.Instantiate(@class))
{
}
protected {cls_name}(Variant variant) : this(({engine_class}) variant)
{
}
protected {cls_name}([NotNull] {engine_class} @object)
{
_object = @object;
}
"""
var ctor = ctor_fmt.dedent().format({
cls_name = cls_name,
engine_class = engine_class,
}).strip_edges()
regions.append(ctor)
var casts = """
public static implicit operator {engine_class}({cls_name} self) => self?._object;
public static implicit operator Variant({cls_name} self) => self?._object;
public static explicit operator {cls_name}(Variant variant) => variant.AsGodotObject() != null ? new(variant) : null;
""".dedent().format({
cls_name = cls_name,
engine_class = engine_class,
}).strip_edges()
regions.append(casts)
# ENUMS
var enums = PackedStringArray()
for enum_name in ClassDB.class_get_enum_list(cls_name, true):
enums.append(_generate_enum(cls_name, enum_name))
# INTEGER CONSTANTS
var integer_constants = PackedStringArray()
for constant_name in ClassDB.class_get_integer_constant_list(cls_name, true):
if not ClassDB.class_get_integer_constant_enum(cls_name, constant_name, true).is_empty():
continue
integer_constants.append(_generate_integer_constant(cls_name, constant_name))
# PROPERTIES
var properties = PackedStringArray()
var property_names = PackedStringArray()
for property in ClassDB.class_get_property_list(cls_name, true):
if property["usage"] & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP):
continue
property_names.append(property["name"])
properties.append(_generate_property(cls_name, property))
var inherited_properties = PackedStringArray()
if not parent_class_is_extension:
for inherited_class in _get_parent_classes(cls_name):
for property in ClassDB.class_get_property_list(inherited_class, true):
if property["usage"] & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP):
continue
inherited_properties.append(_generate_property(inherited_class, property))
# METHODS
var methods = PackedStringArray()
var method_names = PackedStringArray()
for method in ClassDB.class_get_method_list(cls_name, true):
if method["flags"] & (METHOD_FLAG_VIRTUAL | METHOD_FLAG_VIRTUAL_REQUIRED):
continue
if method["name"].begins_with("_"):
continue
method_names.append(method["name"])
methods.append(_generate_method(cls_name, method))
var inherited_methods = PackedStringArray()
if not parent_class_is_extension:
for inherited_class in _get_parent_classes(cls_name):
for method in ClassDB.class_get_method_list(inherited_class, true):
if method["flags"] & (METHOD_FLAG_VIRTUAL | METHOD_FLAG_VIRTUAL_REQUIRED):
continue
if method["name"].begins_with("_"):
continue
inherited_methods.append(_generate_method(inherited_class, method))
# SIGNALS
var signals = PackedStringArray()
var signal_names = PackedStringArray()
for sig in ClassDB.class_get_signal_list(cls_name, true):
signal_names.append(sig["name"])
signals.append(_generate_signal(cls_name, sig))
var inherited_signals = PackedStringArray()
if not parent_class_is_extension:
for inherited_class in _get_parent_classes(cls_name):
for method in ClassDB.class_get_signal_list(inherited_class, true):
inherited_signals.append(_generate_signal(inherited_class, method))
# StringName caches
regions.append(_generate_strings_class(cls_name, StringNameType.PROPERTY_NAME, property_names))
regions.append(_generate_strings_class(cls_name, StringNameType.METHOD_NAME, method_names))
regions.append(_generate_strings_class(cls_name, StringNameType.SIGNAL_NAME, signal_names))
regions.append("private static readonly StringName NativeName = \"{cls_name}\";".format({
cls_name = cls_name,
}))
if not enums.is_empty():
regions.append("#region Enums")
regions.append("\n\n".join(enums))
regions.append("#endregion")
if not integer_constants.is_empty():
regions.append("#region Integer Constants")
regions.append("\n\n".join(integer_constants))
regions.append("#endregion")
if not properties.is_empty():
regions.append("#region Properties")
regions.append("\n\n".join(properties))
regions.append("#endregion")
if not inherited_properties.is_empty():
regions.append("#region Inherited Properties")
regions.append("\n\n".join(inherited_properties))
regions.append("#endregion")
if not methods.is_empty():
regions.append("#region Methods")
regions.append("\n\n".join(methods))
regions.append("#endregion")
if not inherited_methods.is_empty():
regions.append("#region Inherited Methods")
regions.append("\n\n".join(inherited_methods))
regions.append("#endregion")
if not signals.is_empty():
regions.append("#region Signals")
regions.append("\n\n".join(signals))
regions.append("#endregion")
if not inherited_signals.is_empty():
regions.append("#region Inherited Signals")
regions.append("\n\n".join(inherited_signals))
regions.append("#endregion")
var code = """
// This code was automatically generated by GDExtension C# Bindgen
using System;
using System.Diagnostics.CodeAnalysis;
using Godot;
namespace {name_space};
public class {cls_name}{inheritance}
{
{regions}
}
""".dedent().format({
name_space = name_space,
cls_name = cls_name,
inheritance = " : " + parent_class if parent_class_is_extension else "",
regions = "\n\n".join(regions).indent("\t"),
}).strip_edges()
if class_is_editor_only:
code = """
#if TOOLS
{code}
#endif
""".dedent().format({
code = code,
}).strip_edges()
code += "\n"
if not DirAccess.dir_exists_absolute(output_dir):
DirAccess.make_dir_recursive_absolute(output_dir)
var new_script = FileAccess.open(output_dir.path_join(cls_name + ".cs"), FileAccess.WRITE)
new_script.store_string(code)
static func generate_gdextension_csharp_scripts(
output_dir := GENERATED_SCRIPTS_FOLDER,
name_space := GENERATED_NAMESPACE,
):
var classes = ClassDB.get_class_list()
for cls_name in classes:
if _is_extension_class(cls_name):
generate_csharp_script(cls_name, output_dir, name_space)
static func _generate_enum(cls_name: StringName, enum_name: StringName) -> String:
var common_prefix = null
for constant_name in ClassDB.class_get_enum_constants(cls_name, enum_name, true):
if common_prefix == null:
common_prefix = constant_name
else:
common_prefix = _get_common_prefix(common_prefix, constant_name)
# Handle special case where one of the constants is present in all constant
# names: remove last word from prefix.
# Example case: Node.ProcessThreadMessages and FLAG_PROCESS_THREAD_MESSAGES
if common_prefix in ClassDB.class_get_enum_constants(cls_name, enum_name, true):
common_prefix = common_prefix.rsplit("_", false, 1)[0]
var constants = PackedStringArray()
for constant_name in ClassDB.class_get_enum_constants(cls_name, enum_name, true):
constants.append("{csharp_constant_name} = {constant_value}L,".format({
csharp_constant_name = constant_name.substr(common_prefix.length()).to_pascal_case(),
constant_value = ClassDB.class_get_integer_constant(cls_name, constant_name),
}))
return """
{flags}
public enum {enum_name}{maybe_enum_suffix} : long
{
{constants}
}
""".dedent().format({
flags = "[Flags]" if ClassDB.is_class_enum_bitfield(cls_name, enum_name) else "",
enum_name = enum_name,
constants = "\n".join(constants).indent("\t"),
maybe_enum_suffix = "Enum" if _needs_enum_suffix(cls_name, enum_name) else "",
}).strip_edges()
static func _generate_integer_constant(cls_name: StringName, constant_name: StringName) -> String:
return "public const long {csharp_constant_name} = {constant_value}L;".format({
csharp_constant_name = constant_name.to_pascal_case(),
constant_value = ClassDB.class_get_integer_constant(cls_name, constant_name),
})
static func _generate_property(cls_name: StringName, property: Dictionary) -> String:
var property_name = property["name"]
var csharp_property_name = property_name.to_pascal_case()
var property_type = _get_property_type(cls_name, property)
var getset = PackedStringArray()
var getter = ClassDB.class_get_property_getter(cls_name, property_name)
if getter:
if _is_extension_class(cls_name):
getset.append("get => {get_cast}_object.Get(PropertyName.{csharp_property_name});".format({
get_cast = _property_get_cast(cls_name, property),
csharp_property_name = csharp_property_name,
}))
else:
getset.append("get => _object.{csharp_property_name};".format({
csharp_property_name = csharp_property_name,
}))
var setter = ClassDB.class_get_property_setter(cls_name, property_name)
if setter:
if _is_extension_class(cls_name):
getset.append("set => _object.Set(PropertyName.{csharp_property_name}, {set_cast}value);".format({
set_cast = _property_set_cast(property),
csharp_property_name = csharp_property_name,
}))
else:
getset.append("set => _object.{csharp_property_name} = value;".format({
csharp_property_name = csharp_property_name,
}))
return """
public {property_type} {csharp_property_name}
{
{getset}
}
""".dedent().format({
property_type = property_type,
csharp_property_name = csharp_property_name,
getset = "\n".join(getset).indent("\t"),
}).strip_edges()
static func _generate_method(cls_name: StringName, method: Dictionary) -> String:
var method_name = method["name"]
var csharp_method_name = method_name.to_pascal_case()
var return_type = _get_method_return_type(cls_name, method_name, method["return"])
var is_static = method["flags"] & METHOD_FLAG_STATIC
var arg_types = PackedStringArray()
var arg_names = PackedStringArray()
var args = PackedStringArray()
for argument in method["args"]:
var arg_type = _get_property_type(cls_name, argument)
var arg_name = "@" + argument["name"]
# hardcode type that cannot be known from reflection in GDScript
if method["name"] == "connect" and arg_name == "@flags":
arg_type = "uint"
args.append("{arg_type} {arg_name}".format({
arg_type = arg_type,
arg_name = arg_name,
}))
arg_types.append(arg_type)
if _property_is_enum(argument):
arg_names.append("(int)" + arg_name)
else:
arg_names.append(arg_name)
var implementation = PackedStringArray()
var default_args = method["default_args"]
var i = args.size() - default_args.size()
for default_value in default_args:
if default_value == null:
default_value = "default"
# handle enums
elif default_value is int and arg_types[i] != "int":
default_value = ("(%s)" % arg_types[i]) + str(default_value)
# C# requires the "f" suffix for float literals
elif default_value is float and arg_types[i] == "float":
default_value = "%sf" % default_value
# NOTE: don't move this branch below the String one, since most of the
# time when arg_types[i] == StringName, default_value is String
elif default_value is StringName or arg_types[i] == "Godot.StringName":
implementation.append('%s ??= "%s";' % [arg_names[i], default_value])
default_value = "null"
elif default_value is String:
default_value = '"%s"' % default_value
elif default_value is Array:
assert(default_value.is_empty(), "Populated Array not supported yet! " + str(default_value)) # TODO: support populated array as default value
implementation.append("%s ??= new();" % arg_names[i])
default_value = "null"
elif default_value is Dictionary:
assert(default_value.is_empty(), "Populated Dictionary not supported yet! " + str(default_value)) # TODO: support populated dictionary as default value
implementation.append("%s ??= new();" % arg_names[i])
default_value = "null"
elif (
default_value is Vector2 or default_value is Vector3 or default_value is Vector4
or default_value is Color
):
args[i] = args[i].replace(arg_types[i], arg_types[i] + "?")
var impl = "%s ??= new%s;" % [arg_names[i], default_value]
if not OS.has_feature("double"):
impl = impl.replace(",", "f,").replace(")", "f)")
implementation.append(impl)
default_value = "null"
elif (
default_value is PackedByteArray
or default_value is PackedInt32Array or default_value is PackedInt64Array
or default_value is PackedFloat32Array or default_value is PackedFloat64Array
or default_value is PackedVector2Array or default_value is PackedVector3Array or default_value is PackedVector4Array
or default_value is PackedColorArray
):
assert(default_value.is_empty(), "Populated Packed Array not supported yet! " + str(default_value))
implementation.append("%s ??= System.Array.Empty<%s>();" % [arg_names[i], arg_types[i].replace("[]", "")])
default_value = "null"
elif default_value is Transform2D:
assert(default_value == Transform2D.IDENTITY, "Only identity Transform2D is supported as default value")
args[i] = args[i].replace(arg_types[i], arg_types[i] + "?")
implementation.append("%s ??= Godot.Transform2D.Identity;" % arg_names[i])
default_value = "null"
elif default_value is Transform3D:
assert(default_value == Transform3D.IDENTITY, "Only identity Transform3D is supported as default value")
args[i] = args[i].replace(arg_types[i], arg_types[i] + "?")
implementation.append("%s ??= Godot.Transform3D.Identity;" % arg_names[i])
default_value = "null"
args[i] += " = " + str(default_value)
i += 1
if method["flags"] & METHOD_FLAG_VARARG:
args.append("params Variant[] varargs")
arg_names.append("varargs")
if _is_extension_class(cls_name):
arg_names.insert(0, "MethodName.{csharp_method_name}".format({
csharp_method_name = csharp_method_name,
}))
if is_static:
implementation.append("{maybe_return}ClassDB.ClassCallStatic(NativeName, {arg_names});".format({
arg_names = ", ".join(arg_names),
maybe_return = "return " + _property_get_cast(cls_name, method["return"]) if return_type != "void" else "",
}))
else:
implementation.append("{maybe_return}_object.Call({arg_names});".format({
arg_names = ", ".join(arg_names),
maybe_return = "return " + _property_get_cast(cls_name, method["return"]) if return_type != "void" else "",
}))
else:
if is_static:
implementation.append("{maybe_return}{engine_class}.{csharp_method_name}({arg_names});".format({
arg_names = ", ".join(arg_names),
engine_class = _first_non_extension_parent(cls_name),
csharp_method_name = csharp_method_name,
maybe_return = "return " if return_type != "void" else "",
}))
else:
implementation.append("{maybe_return}_object.{csharp_method_name}({arg_names});".format({
arg_names = ", ".join(arg_names),
csharp_method_name = csharp_method_name,
maybe_return = "return " if return_type != "void" else "",
}))
return """
public {maybe_static}{maybe_override}{return_type} {csharp_method_name}({args})
{
{implementation}
}
""".dedent().format({
args = ", ".join(args),
csharp_method_name = csharp_method_name,
implementation = "\n".join(implementation).indent("\t"),
maybe_override = "override " if csharp_method_name == "ToString" else "",
maybe_static = "static " if is_static else "",
return_type = return_type,
}).strip_edges()
static func _generate_signal(cls_name: StringName, sig: Dictionary):
var signal_name = sig["name"]
var csharp_signal_name = signal_name.to_pascal_case()
var return_type = _get_method_return_type(cls_name, signal_name, sig["return"])
var arg_types = PackedStringArray()
for argument in sig["args"]:
var arg_type = _get_property_type(cls_name, argument)
arg_types.append(arg_type)
var delegate_type
if return_type == "void":
if not arg_types.is_empty():
delegate_type = "Action<{arg_types}>".format({
arg_types = ", ".join(arg_types)
})
else:
delegate_type = "Action"
else:
arg_types.append(return_type)
delegate_type = "Func<{arg_types}>".format({
arg_types = ", ".join(arg_types)
})
return """
public event {delegate_type} {csharp_signal_name}
{
add
{
Connect(SignalName.{csharp_signal_name}, Callable.From(value));
}
remove
{
Disconnect(SignalName.{csharp_signal_name}, Callable.From(value));
}
}
""".dedent().format({
delegate_type = delegate_type,
csharp_signal_name = csharp_signal_name,
}).strip_edges()
static func _property_is_enum(property: Dictionary) -> bool:
return property["usage"] & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)
static func _get_property_type(cls_name: StringName, property: Dictionary) -> String:
match property["type"]:
TYPE_NIL:
return "Variant"
TYPE_BOOL:
return "bool"
TYPE_INT:
if _property_is_enum(property):
var enum_name = property["class_name"]
if enum_name == "Error":
return "Godot.Error"
var split = enum_name.split(".")
if split.size() == 1:
return enum_name + ("Enum" if _needs_enum_suffix(cls_name, enum_name) else "")
else:
return enum_name + ("Enum" if _needs_enum_suffix(split[0], split[1]) else "")
return "int"
TYPE_FLOAT:
return "double" if OS.has_feature("double") else "float"
TYPE_STRING:
return "string"
TYPE_VECTOR2I:
return "Godot.Vector2I"
TYPE_RECT2I:
return "Godot.Rect2I"
TYPE_VECTOR3I:
return "Godot.Vector3I"
TYPE_VECTOR4I:
return "Godot.Vector4I"
TYPE_AABB:
return "Godot.Aabb"
TYPE_RID:
return "Godot.Rid"
TYPE_OBJECT:
if property["class_name"] and property["class_name"] != "Object":
return _pascal_to_pascal_case(_get_class_from_class_name(property["class_name"]))
else:
return "GodotObject"
TYPE_ARRAY:
if property["hint"] & PROPERTY_HINT_ARRAY_TYPE:
return "Godot.Collections.Array<%s>" % _get_mapped_variant_type(property["hint_string"])
else:
return "Godot.Collections.Array"
TYPE_DICTIONARY:
return "Godot.Collections.Dictionary"
TYPE_PACKED_BYTE_ARRAY:
return "byte[]"
TYPE_PACKED_INT32_ARRAY:
return "int[]"
TYPE_PACKED_INT64_ARRAY:
return "long[]"
TYPE_PACKED_FLOAT32_ARRAY:
return "float[]"
TYPE_PACKED_FLOAT64_ARRAY:
return "double[]"
TYPE_PACKED_STRING_ARRAY:
return "string[]"
TYPE_PACKED_VECTOR2_ARRAY:
return "Godot.Vector2[]"
TYPE_PACKED_VECTOR3_ARRAY:
return "Godot.Vector3[]"
TYPE_PACKED_VECTOR4_ARRAY:
return "Godot.Vector4[]"
TYPE_PACKED_COLOR_ARRAY:
return "Godot.Color[]"
var t:
return "Godot." + type_string(t)
static func _get_mapped_variant_type(variant_type_name: String) -> String:
var _type_map = {
"Variant": "Variant",
type_string(TYPE_BOOL): "bool",
type_string(TYPE_INT): "int",
type_string(TYPE_FLOAT): "double" if OS.has_feature("double") else "float",
type_string(TYPE_STRING): "string",
type_string(TYPE_STRING_NAME): "StringName",
type_string(TYPE_VECTOR2I): "Godot.Vector2I",
type_string(TYPE_RECT2I): "Godot.Rect2I",
type_string(TYPE_VECTOR3I): "Godot.Vector3I",
type_string(TYPE_VECTOR4I): "Godot.Vector4I",
type_string(TYPE_AABB): "Godot.Aabb",
type_string(TYPE_RID): "Godot.Rid",
type_string(TYPE_OBJECT): "GodotObject",
type_string(TYPE_ARRAY): "Godot.Collections.Array",
type_string(TYPE_DICTIONARY): "Godot.Collections.Dictionary",
type_string(TYPE_PACKED_BYTE_ARRAY): "byte[]",
type_string(TYPE_PACKED_INT32_ARRAY): "int[]",
type_string(TYPE_PACKED_INT64_ARRAY): "long[]",
type_string(TYPE_PACKED_FLOAT32_ARRAY): "float[]",
type_string(TYPE_PACKED_FLOAT64_ARRAY): "double[]",
type_string(TYPE_PACKED_STRING_ARRAY): "string[]",
type_string(TYPE_PACKED_VECTOR2_ARRAY): "Godot.Vector2[]",
type_string(TYPE_PACKED_VECTOR3_ARRAY): "Godot.Vector3[]",
type_string(TYPE_PACKED_VECTOR4_ARRAY): "Godot.Vector4[]",
type_string(TYPE_PACKED_COLOR_ARRAY): "Godot.Color[]",
}
return _type_map.get(variant_type_name, "Godot." + variant_type_name)
static func _property_get_cast(cls_name: StringName, property: Dictionary):
var property_type = _get_property_type(cls_name, property)
if _property_is_enum(property):
return "(%s)(int)" % property_type
else:
return "(%s)" % property_type
static func _property_set_cast(property: Dictionary):
if _property_is_enum(property):
return "(int)"
else:
return ""
static func _is_extension_class(cls_name: StringName) -> bool:
return ClassDB.class_get_api_type(cls_name) in [
ClassDB.APIType.API_EXTENSION,
ClassDB.APIType.API_EDITOR_EXTENSION,
]
static func _is_editor_extension_class(cls_name: StringName) -> bool:
return ClassDB.class_get_api_type(cls_name) == ClassDB.APIType.API_EDITOR_EXTENSION
static func _first_non_extension_parent(cls_name: StringName) -> StringName:
while _is_extension_class(cls_name):
cls_name = ClassDB.get_parent_class(cls_name)
return cls_name
static func _get_method_return_type(cls_name: StringName, method_name: StringName, method_return: Dictionary) -> String:
# hardcode type that cannot be known from reflection in GDScript
if method_name == "get_instance_id":
return "ulong"
if method_return["type"] == TYPE_NIL:
if method_return["usage"] & PROPERTY_USAGE_NIL_IS_VARIANT:
return "Variant"
else:
return "void"
else:
return _get_property_type(cls_name, method_return)
static func _get_parent_classes(cls_name: StringName) -> Array[StringName]:
var parent_classes = [] as Array[StringName]
while true:
cls_name = ClassDB.get_parent_class(cls_name)
parent_classes.append(cls_name)
if cls_name == "Object":
break
return parent_classes
static func _generate_strings_class(cls_name: StringName, string_name_type: StringNameType, string_names: PackedStringArray) -> String:
var parent_class = ClassDB.get_parent_class(cls_name)
var lines = PackedStringArray()
for name in string_names:
if string_name_type == StringNameType.METHOD_NAME and ClassDB.class_has_method(parent_class, name):
continue
if string_name_type == StringNameType.SIGNAL_NAME and ClassDB.class_has_signal(parent_class, name):
continue
lines.append("public static readonly StringName {cs_name} = \"{name}\";".format({
cs_name = name.to_pascal_case(),
name = name,
}))
return """
public {maybe_new}class {strings_class} : {parent_class}.{strings_class}
{
{lines}
}
""".dedent().format({
lines = "\n".join(lines).indent("\t"),
maybe_new = "new " if _is_extension_class(parent_class) else "",
parent_class = parent_class,
strings_class = StringNameTypeName[string_name_type],
}).strip_edges()
static func _get_common_prefix(s1: String, s2: String) -> String:
var common_length = min(s1.length(), s2.length())
for i in range(common_length):
if s1[i] != s2[i]:
return s1.substr(0, i)
return s1.substr(0, common_length)
static func _get_class_from_class_name(cls_name: String) -> String:
var classes = cls_name.split(",")
if classes.size() == 1:
return cls_name
# Handle special case where 2 or more class names are present separated
# by ",": calculate the common parent class.
# Example case: CanvasItem.material uses "CanvasItemMaterial,ShaderMaterial"
var parent_classes = _get_parent_classes(classes[0])
for i in range(1, classes.size()):
var test_cls = classes[i]
while not ClassDB.is_parent_class(test_cls, parent_classes[0]):
parent_classes.pop_front()
return parent_classes[0]
static func _needs_enum_suffix(cls_name: StringName, enum_name: String) -> bool:
var snake_case_enum_name = enum_name.to_snake_case()
if ClassDB.class_has_method(cls_name, snake_case_enum_name):
return true
if ClassDB.class_has_signal(cls_name, snake_case_enum_name):
return true
var properties = ClassDB.class_get_property_list(cls_name)
for property in properties:
if snake_case_enum_name == property["name"]:
return true
return false
# Pascal case conversion used for class names.
# Replicates the logic from `godot/modules/mono/utils/naming_utils.cpp`
static func _is_ascii_upper_case(c: String) -> bool:
return c.to_upper() == c
static func _is_ascii_lower_case(c: String) -> bool:
return c.to_lower() == c
static func _is_digit(c: String) -> bool:
return c >= "0" and c <= "9"
static func _split_pascal_case(p_identifier: String) -> PackedStringArray:
var parts := PackedStringArray()
var current_part_start := 0
var prev_was_upper := _is_ascii_upper_case(p_identifier[0])
for i in range(1, p_identifier.length()):
if prev_was_upper:
if _is_digit(p_identifier[i]) or _is_ascii_lower_case(p_identifier[i]):
if not _is_digit(p_identifier[i]):
# These conditions only apply when the separator is not a digit.
if i - current_part_start == 1:
# Upper character was only the beginning of a word.
prev_was_upper = false
continue
if i != p_identifier.length():
# If this is not the last character, the last uppercase
# character is the start of the next word.
i -= 1
if i - current_part_start > 0:
parts.append(p_identifier.substr(current_part_start, i - current_part_start))
current_part_start = i
prev_was_upper = false
else:
if _is_digit(p_identifier[i]) or _is_ascii_upper_case(p_identifier[i]):
parts.append(p_identifier.substr(current_part_start, i - current_part_start))
current_part_start = i
prev_was_upper = true
# Add the rest of the identifier as the last part.
if current_part_start != p_identifier.length():
parts.append(p_identifier.substr(current_part_start))
return parts
static func _pascal_to_pascal_case(p_identifier: String) -> String:
if p_identifier.length() == 0:
return p_identifier
if p_identifier.length() <= 2:
return p_identifier.to_upper()
if PASCAL_CASE_NAME_OVERRIDES.has(p_identifier):
return PASCAL_CASE_NAME_OVERRIDES[p_identifier]
var parts := _split_pascal_case(p_identifier)
var ret := ""
for part in parts:
if PASCAL_CASE_PART_OVERRIDES.has(part):
ret += PASCAL_CASE_PART_OVERRIDES[part]
continue
if part.length() <= 2 and _is_ascii_upper_case(part):
ret += part.to_upper()
continue
part[0] = part[0].to_upper()
for i in range(1, part.length()):
if _is_digit(part[i - 1]):
# Use uppercase after digits.
part[i] = part[i].to_upper()
else:
part[i] = part[i].to_lower()
ret += part
return ret

View File

@@ -0,0 +1 @@
uid://cy4tmwy5iyogu

Binary file not shown.

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://blckign68biqs"
path="res://.godot/imported/icon.png-6749c396fd9e755f292f935bb84594b0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/csharp_gdextension_bindgen/icon.png"
dest_files=["res://.godot/imported/icon.png-6749c396fd9e755f292f935bb84594b0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

View File

@@ -0,0 +1,7 @@
[plugin]
name="C# GDExtension Bindgen"
description="Automatic C# bindings generator for GDExtension classes (Godot 4.4+)"
author="gilzoide"
version="0.3.1"
script="csharp_gdextension_bindgen.gd"

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016-2023 The Godot Engine community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
[configuration]
entry_symbol = "git_plugin_init"
compatibility_minimum = "4.1.0"
[libraries]
macos.editor = "macos/libgit_plugin.macos.editor.universal.dylib"
windows.editor.x86_64 = "win64/libgit_plugin.windows.editor.x86_64.dll"
linux.editor.x86_64 = "linux/libgit_plugin.linux.editor.x86_64.so"
linux.editor.arm64 = "linux/libgit_plugin.linux.editor.arm64.so"
linux.editor.rv64 = ""

View File

@@ -0,0 +1 @@
uid://dd53bxo7wl2cm

View File

@@ -0,0 +1,7 @@
[plugin]
name="Godot Git Plugin"
description="This plugin lets you interact with Git without leaving the Godot editor. More information can be found at https://github.com/godotengine/godot-git-plugin/wiki"
author="twaritwaikar"
version="v3.1.1"
script="godot-git-plugin.gd"

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Marius Hanl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,65 @@
# Script IDE
Transforms the Script UI into an IDE like UI.
Tabs are used for navigating between scripts.
The default Outline got an overhaul and now shows all members of the script (not just methods) with unique icons for faster navigation.
Enhanced keyboard navigation for Scripts and Outline.
Fast quick search functionality.
Quick function Override functionality.
Features:
- Scripts are now shown as Tabs inside a TabContainer
- The Outline got an overhaul and shows more than just the methods of the script. It includes the following members with a unique icon:
- Classes (Red Square)
- Constants (Red Circle)
- Signals (Yellow)
- Export variables (Orange)
- (Static) Variables (Red)
- Engine callback functions (Blue)
- (Static) Functions (Green)
- Setter functions (Green circle, with an arrow inside it pointing to the right)
- Getter functions (Green circle, with an arrow inside it pointing to the left)
- All the different members of the script can be hidden or made visible again by the outline filter. This allows fine control what should be visible (e.g. only signals, (Godot) functions, ...)
- A `Right Click` enables only the clicked filter, another `Right Click` will enable all filters again
- The Outline can be opened in a Popup with a defined shortcut for quick navigation between methods
- You can navigate through the Outline with the `Arrow` keys (or `Page up/Page down`) and scroll to the selected item by pressing `ENTER`
- Scripts can be opened in a Popup with a defined shortcut or when clicking the three dots on the top right of the TabContainer for quick navigation between scripts
- The currently edited script is automatically selected in the Filesystem Dock
- Files can be quickly searched by the Quick Search Popup with `Shift`+`Shift`
- You can find and quickly override any method from your super classes with `Alt`+`Ins`
- The plugin is written with performance in mind, everything is very fast and works without any lags or stuttering
Customization:
- The Outline is on the right side (can be changed to be on the left side again)
- The Outline can be toggled via `File -> Toggle Scripts Panel`. This will hide or show it
- The order in the Outline can be changed
- There is also the possibility to hide private members, this is all members starting with a `_`
- The Script ItemList is not visible by default, but can be made visible again
All settings can be changed in the `Editor Settings` under `Plugin` -> `Script Ide`:
- `Open Outline Popup` = Shortcut to control how the Outline Popup should be triggered (default=CTRL+O or META+O)
- `Outline Position Right` = Flag to control whether the outline should be on the right or on the left side of the script editor (default=true)
- `Outline Order` = List which specifies the order of all different types in the Outline
- `Hide Private Members` = Flag to control whether private members (methods/variables/constants starting with '_') should be hidden in the Outline or not (default=false)
- `Open Script Popup` = Shortcut to control how the Script Popup should be triggered (default=CTRL+U or META+U)
- `Script List Visible` = Flag to control whether the script list should still be visible or not (above the outline) (default=false)
- `Script Tabs Visible` = Flag to control whether the script tabs should be visible or not (default=true)
- `Script Tabs Position Top` = Flag to control whether the script tabs should be on the top or on the bottom (default=true)
- `Auto Navigate in FileSystem Dock` = Flag to control whether the script that is currently edited should be automatically selected in the Filesystem Dock (default=true)
- `Open Quick Search Popup` = Shortcut to control how the Quick Search Popup should be triggered (default=Shift+Shift, double press behavior is hardcoded for now)
- `Open Override Popup` = Shortcut to control how the Override Popup should be triggered (default=Alt+Ins)
- `Cycle Tab forward` = Shortcut to cycle the script tabs in the forward direction (only works in the 'Script' Editor Tab) (default=CTRL+TAB)
- `Cycle Tab backward` = Shortcut to cycle the script tabs in the backward direction (only works in the 'Script' Editor Tab) (default=CTRL+SHIFT+TAB)
- All outline visibility settings
![Example of the Outline](https://github.com/user-attachments/assets/1729cb2b-01ae-4365-b77a-45edcb94b978)
![Example of the Outline Popup](https://github.com/user-attachments/assets/995c721f-9708-40d9-a4e8-57b1a99e9c29)
![Example of the TabContainer Script ItemList Popup](https://github.com/user-attachments/assets/484d498c-bd1c-4c77-a693-ac31a8500fbe)
![Example of the Script ItemList Popup](https://github.com/user-attachments/assets/bb976604-6049-4ce1-a28e-377fc62899f6)
![Example of the Quick Search Popup](https://github.com/user-attachments/assets/01141f05-e07c-4059-8d6f-e4c7490cbd40)
![Example of the Plugin Editor Settings](https://github.com/user-attachments/assets/0450e423-bc49-4076-862b-c95a62190df1)

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="14" height="14" fill="#ff7085"/></svg>

After

Width:  |  Height:  |  Size: 127 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://csik7oxvt7tq3"
path="res://.godot/imported/class.svg-e6f2816a1f06041fb421c2af52817a4a.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/class.svg"
dest_files=["res://.godot/imported/class.svg-e6f2816a1f06041fb421c2af52817a4a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7s7-3.134 7-7c0-3.866-3.134-7-7-7zm0 2c2.7614 0 5 2.2386 5 5 0 2.7614-2.2386 5-5 5-2.7614 0-5-2.2386-5-5 0-2.7614 2.2386-5 5-5z" fill="#ff7085"/></svg>

After

Width:  |  Height:  |  Size: 268 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cawc456ja8vf5"
path="res://.godot/imported/constant.svg-f6e857276565573c7540f3c32801842a.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/constant.svg"
dest_files=["res://.godot/imported/constant.svg-f6e857276565573c7540f3c32801842a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7 3.866 0 7-3.134 7-7 0-3.866-3.134-7-7-7z" fill="#57b3ff"/></svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cupb0polhqrwj"
path="res://.godot/imported/engine_func.svg-91320e42f9cc7bdd7576002e82fa6ab8.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/engine_func.svg"
dest_files=["res://.godot/imported/engine_func.svg-91320e42f9cc7bdd7576002e82fa6ab8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7 3.866 0 7-3.134 7-7 0-3.866-3.134-7-7-7z" fill="#ffb273"/></svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bvu2gnj8fv2kw"
path="res://.godot/imported/export.svg-d2d18132258a7a219ec1af1f0316c91c.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/export.svg"
dest_files=["res://.godot/imported/export.svg-d2d18132258a7a219ec1af1f0316c91c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7 3.866 0 7-3.134 7-7 0-3.866-3.134-7-7-7z" fill="#8eef97"/></svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://rni04cl446ov"
path="res://.godot/imported/func.svg-139842caa5b4b7e4839711b6c756d0f7.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/func.svg"
dest_files=["res://.godot/imported/func.svg-139842caa5b4b7e4839711b6c756d0f7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 15c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm0.5-2a1 1 0 0 1-0.70703-0.29297l-4-4a1 1 0 0 1-0.25977-0.62695 1.0001 1.0001 0 0 1 0-0.16016 1 1 0 0 1 0.25977-0.62695l4-4a1 1 0 0 1 1.4141 0 1 1 0 0 1 0 1.4141l-2.293 2.293h4.5859a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-4.5859l2.293 2.293a1 1 0 0 1 0 1.4141 1 1 0 0 1-0.70703 0.29297z" fill="#8eef97"/></svg>

After

Width:  |  Height:  |  Size: 435 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c2a3aowyhxj5x"
path="res://.godot/imported/func_get.svg-093f0ce02889d1f102ff9cc3e7f72654.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/func_get.svg"
dest_files=["res://.godot/imported/func_get.svg-093f0ce02889d1f102ff9cc3e7f72654.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7s7-3.134 7-7c0-3.866-3.134-7-7-7zm-0.5 2a1 1 0 0 1 0.70703 0.29297l4 4a1 1 0 0 1 0.25977 0.62695 1.0001 1.0001 0 0 1 0 0.16016 1 1 0 0 1-0.25977 0.62695l-4 4a1 1 0 0 1-1.4141 0 1 1 0 0 1 0-1.4141l2.293-2.293h-4.5859a1 1 0 0 1-1-1 1 1 0 0 1 1-1h4.5859l-2.293-2.293a1 1 0 0 1 0-1.4141 1 1 0 0 1 0.70703-0.29297z" fill="#8eef97"/></svg>

After

Width:  |  Height:  |  Size: 451 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bvjkrti6kj6o2"
path="res://.godot/imported/func_set.svg-c31168d90866ff1707ad9834754bd2c9.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/func_set.svg"
dest_files=["res://.godot/imported/func_set.svg-c31168d90866ff1707ad9834754bd2c9.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7 3.866 0 7-3.134 7-7 0-3.866-3.134-7-7-7z" fill="#ff7085"/></svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dbwlgnwv5e8kl"
path="res://.godot/imported/property.svg-9e228499f30651faad74aa99e4499d7e.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/property.svg"
dest_files=["res://.godot/imported/property.svg-9e228499f30651faad74aa99e4499d7e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7 3.866 0 7-3.134 7-7 0-3.866-3.134-7-7-7z" fill="#ffdd65"/></svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bnccvnaloqnte"
path="res://.godot/imported/signal.svg-97182e1498b520a1ff5b8b9017c3b480.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/script-ide/icon/signal.svg"
dest_files=["res://.godot/imported/signal.svg-97182e1498b520a1ff5b8b9017c3b480.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,336 @@
@tool
extends PopupPanel
const FUNC_META: StringName = &"func"
@onready var filter_txt: LineEdit = %FilterTxt
@onready var class_func_tree: Tree = %ClassFuncTree
@onready var ok_btn: Button = %OkBtn
@onready var cancel_btn: Button = %CancelBtn
var plugin: EditorPlugin
var selections: Dictionary[String, bool] = {} # Used as Set.
var class_to_functions: Dictionary[StringName, PackedStringArray]
func _ready() -> void:
filter_txt.text_changed.connect(update_tree_filter.unbind(1))
class_func_tree.multi_selected.connect(func(item: TreeItem, col: int, selected: bool): save_selection(selected, item))
class_func_tree.item_activated.connect(generate_functions)
cancel_btn.pressed.connect(hide)
ok_btn.pressed.connect(generate_functions)
about_to_popup.connect(on_show)
if (plugin != null):
filter_txt.gui_input.connect(navigate_on_tree)
func navigate_on_tree(event: InputEvent):
if (event.is_action_pressed(&"ui_down", true)):
var selected: TreeItem = get_selected_tree_item()
if (selected == null):
return
var item: TreeItem = selected.get_next_in_tree()
if (item == null):
return
focus_tree_item(item)
elif (event.is_action_pressed(&"ui_up", true)):
var selected: TreeItem = get_selected_tree_item()
if (selected == null):
return
var item: TreeItem = selected.get_prev_in_tree()
if (item == null):
return
focus_tree_item(item)
elif (event.is_action_pressed(&"ui_page_down", true)):
var selected: TreeItem = get_selected_tree_item()
if (selected == null):
return
var item: TreeItem = selected.get_next_in_tree()
if (item == null):
return
for index: int in 4:
var next: TreeItem = item.get_next_in_tree()
if (next == null):
break
item = next
focus_tree_item(item)
elif (event.is_action_pressed(&"ui_page_up", true)):
var selected: TreeItem = get_selected_tree_item()
if (selected == null):
return
var item: TreeItem = selected.get_prev_in_tree()
if (item == null):
return
for index: int in 4:
var prev: TreeItem = item.get_prev_in_tree()
if (prev == null):
break
item = prev
focus_tree_item(item)
elif (event.is_action_pressed(&"ui_select", true)):
var selected: TreeItem = get_selected_tree_item()
if (selected == null):
return
if (!selected.is_selectable(0)):
selected.collapsed = !selected.collapsed
class_func_tree.accept_event()
return
if (selected.is_selected(0)):
selected.deselect(0)
save_selection(false, selected)
else:
selected.select(0)
save_selection(true, selected)
class_func_tree.accept_event()
elif (event.is_action_pressed(&"ui_text_submit", true)):
if (selections.size() == 0):
return
generate_functions()
class_func_tree.accept_event()
func get_selected_tree_item() -> TreeItem:
var selected: TreeItem = class_func_tree.get_selected()
if (selected == null):
selected = class_func_tree.get_root()
return selected
func focus_tree_item(item: TreeItem):
var was_selected: bool = item.is_selected(0)
item.select(0)
item.deselect(0)
if (was_selected):
item.select(0)
class_func_tree.ensure_cursor_is_visible()
class_func_tree.accept_event()
func update_tree_filter():
update_tree()
func save_selection(selected: bool, item: TreeItem):
if (selected):
selections[item.get_text(0)] = true
else:
selections.erase(item.get_text(0))
ok_btn.disabled = selections.size() == 0
func on_show():
class_func_tree.clear()
selections.clear()
ok_btn.disabled = true
filter_txt.text = &""
var script: Script = EditorInterface.get_script_editor().get_current_script()
class_to_functions = collect_all_class_functions(script) # [StringName, PackedStringArray]
if (class_to_functions.is_empty()):
return
update_tree()
filter_txt.grab_focus()
func update_tree():
class_func_tree.clear()
var text: String = filter_txt.text
var root: TreeItem = class_func_tree.create_item()
for class_name_str: StringName in class_to_functions.keys():
var class_item: TreeItem = root.create_child(0)
class_item.set_selectable(0, false)
class_item.set_text(0, class_name_str)
for function: String in class_to_functions.get(class_name_str):
var is_preselected: bool = selections.has(function)
if (is_preselected || text.is_empty() || text.is_subsequence_ofn(function)):
var func_item: TreeItem = class_item.create_child()
func_item.set_text(0, function)
if (plugin.keywords.has(function.get_slice("(", 0))):
func_item.set_icon(0, plugin.engine_func_icon)
else:
func_item.set_icon(0, plugin.func_icon)
if (is_preselected):
func_item.select(0)
func collect_all_class_functions(script: Script) -> Dictionary[StringName, PackedStringArray]:
var existing_funcs: Dictionary[String, bool] = {} # Used as Set.
for func_str: String in plugin.outline_cache.engine_funcs:
existing_funcs[func_str] = true
for func_str: String in plugin.outline_cache.funcs:
existing_funcs[func_str] = true
var class_to_functions: Dictionary[StringName, PackedStringArray] = collect_super_class_functions(script.get_base_script(), existing_funcs)
var native_class_to_functions: Dictionary[StringName, PackedStringArray] = collect_native_class_functions(script.get_instance_base_type(), existing_funcs)
return native_class_to_functions.merged(class_to_functions)
func collect_super_class_functions(base_script: Script, existing_funcs: Dictionary[String, bool]) -> Dictionary[StringName, PackedStringArray]:
var super_classes: Array[Script] = []
while (base_script != null):
super_classes.insert(0, base_script)
base_script = base_script.get_base_script()
var class_to_functions: Dictionary[StringName, PackedStringArray] = {}
for super_class: Script in super_classes:
var functions: PackedStringArray = collect_script_functions(super_class, existing_funcs)
if (functions.is_empty()):
continue
class_to_functions[super_class.get_global_name()] = functions
return class_to_functions
func collect_native_class_functions(native_class: StringName, existing_funcs: Dictionary[String, bool]) -> Dictionary[StringName, PackedStringArray]:
var super_native_classes: Array[StringName] = []
while (native_class != &""):
super_native_classes.insert(0, native_class)
native_class = ClassDB.get_parent_class(native_class)
var class_to_functions: Dictionary[StringName, PackedStringArray] = {}
for super_native_class: StringName in super_native_classes:
var functions: PackedStringArray = collect_class_functions(super_native_class, existing_funcs)
if (functions.is_empty()):
continue
class_to_functions[super_native_class] = functions
return class_to_functions
func collect_class_functions(native_class: StringName, existing_funcs: Dictionary[String, bool]):
var functions: PackedStringArray = []
for method: Dictionary in ClassDB.class_get_method_list(native_class, true):
if (method[&"flags"] & METHOD_FLAG_VIRTUAL <= 0):
continue
var func_name: String = method[&"name"]
if (existing_funcs.has(func_name)):
continue
func_name = create_function_signature(method)
functions.append(func_name)
return functions
func collect_script_functions(super_class: Script, existing_funcs: Dictionary[String, bool]) -> PackedStringArray:
var functions: PackedStringArray = []
for method: Dictionary in super_class.get_script_method_list():
var func_name: String = method[&"name"]
if (existing_funcs.has(func_name)):
continue
existing_funcs[func_name] = true
func_name = create_function_signature(method)
functions.append(func_name)
return functions
func create_function_signature(method: Dictionary) -> String:
var func_name: String = method[&"name"]
func_name += "("
var args: Array = method[&"args"]
var default_args: Array = method[&"default_args"]
var arg_index: int = 0
var default_arg_index: int = 0
var arg_str: String = ""
for arg: Dictionary in args:
if (arg_str != ""):
arg_str += ", "
arg_str += arg[&"name"]
var type: String = get_type(arg)
if (type != ""):
arg_str += ": " + type
if (args.size() - arg_index <= default_args.size()):
var default_arg: Variant = default_args[default_arg_index]
if (!default_arg):
var type_hint: int = arg[&"type"]
if (is_dictionary(type_hint)):
default_arg = {}
elif (is_array(type_hint)):
default_arg = []
arg_str += " = " + var_to_str(default_arg)
default_arg_index += 1
arg_index += 1
func_name += arg_str + ")"
var return_str: String = get_type(method[&"return"])
if (return_str == ""):
return_str = "void"
func_name += " -> " + return_str
return func_name
func generate_functions():
if (selections.size() == 0):
return
var generated_text: String = ""
for function: String in selections.keys():
generated_text += "\nfunc " + function + ":\n\tpass\n"
var editor: CodeEdit = EditorInterface.get_script_editor().get_current_editor().get_base_editor()
editor.text += generated_text
plugin.goto_line(editor.get_line_count() - 1)
hide()
func get_type(dict: Dictionary) -> String:
var type: String = dict[&"class_name"]
if (type != &""):
return type
var type_hint: int = dict[&"type"]
if (type_hint == 0):
return &""
type = type_string(type_hint)
if (is_dictionary(type_hint)):
var generic: String = dict[&"hint_string"]
if (generic != &""):
var generic_parts: PackedStringArray = generic.split(";")
if (generic_parts.size() == 2):
return type + "[" + generic_parts[0] + ", " + generic_parts[1] + "]"
if (is_array(type_hint)):
var generic: String = dict[&"hint_string"]
if (generic != &""):
return type + "[" + generic + "]"
return type
func is_dictionary(type_hint: int):
return type_hint == 27
func is_array(type_hint: int):
return type_hint == 28

View File

@@ -0,0 +1 @@
uid://gtyj60r7yti6

View File

@@ -0,0 +1,59 @@
[gd_scene load_steps=2 format=3 uid="uid://bb1n82qxlqanh"]
[ext_resource type="Script" uid="uid://jwla7ovpvhdw" path="res://addons/script-ide/override/override_panel.gd" id="1_c3eqr"]
[node name="OverridePanel" type="PopupPanel"]
size = Vector2i(551, 194)
visible = true
script = ExtResource("1_c3eqr")
[node name="PanelContainer" type="PanelContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 9.0
offset_top = 9.0
offset_right = -9.0
offset_bottom = -9.0
grow_horizontal = 2
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
layout_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 4
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "Select Functions to Override/Implement"
[node name="FilterTxt" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
placeholder_text = "Filter Methods"
[node name="ClassFuncTree" type="Tree" parent="PanelContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
hide_root = true
select_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 4
alignment = 2
[node name="OkBtn" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(64, 0)
layout_mode = 2
text = "Ok"
[node name="CancelBtn" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(64, 0)
layout_mode = 2
text = "Cancel"

View File

@@ -0,0 +1,7 @@
[plugin]
name="Script-IDE"
description="Transforms the Script UI into an IDE like UI. Tabs are used for navigating between scripts. The default Outline got an overhaul and now shows all members of the script (not just methods) with unique icons for faster navigation. Enhanced keyboard navigation for Scripts and Outline. Fast quick search functionality."
author="Marius Hanl"
version="1.9.1"
script="plugin.gd"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
uid://baqmg1xsni4de

View File

@@ -0,0 +1,234 @@
## Quick open panel to quickly access all resources that are in the project.
## Initially shows all resources, but can be changed to more specific resources
## or filtered down with text.
@tool
extends PopupPanel
const ADDONS: StringName = &"res://addons"
const SEPARATOR: StringName = &" - "
const STRUCTURE_START: StringName = &"("
const STRUCTURE_END: StringName = &")"
#region UI
@onready var filter_bar: TabBar = %FilterBar
@onready var search_option_btn: OptionButton = %SearchOptionBtn
@onready var filter_txt: LineEdit = %FilterTxt
@onready var files_list: ItemList = %FilesList
#endregion
var plugin: EditorPlugin
var scenes: Array[FileData]
var scripts: Array[FileData]
var resources: Array[FileData]
var others: Array[FileData]
# For performance and memory considerations, we add all files into one reusable array.
var all_files: Array[FileData]
var is_rebuild_cache: bool = true
#region Plugin and Shortcut processing
func _ready() -> void:
files_list.item_selected.connect(open_file)
search_option_btn.item_selected.connect(rebuild_cache_and_ui.unbind(1))
filter_txt.text_changed.connect(fill_files_list.unbind(1))
filter_bar.tab_changed.connect(change_fill_files_list.unbind(1))
about_to_popup.connect(on_show)
var file_system: EditorFileSystem = EditorInterface.get_resource_filesystem()
file_system.filesystem_changed.connect(schedule_rebuild)
if (plugin != null):
filter_txt.gui_input.connect(plugin.navigate_on_list.bind(files_list, open_file))
func _shortcut_input(event: InputEvent) -> void:
if (!event.is_pressed() || event.is_echo()):
return
if (plugin.tab_cycle_forward_shc.matches_event(event)):
get_viewport().set_input_as_handled()
var new_tab: int = filter_bar.current_tab + 1
if (new_tab == filter_bar.get_tab_count()):
new_tab = 0
filter_bar.current_tab = new_tab
elif (plugin.tab_cycle_backward_shc.matches_event(event)):
get_viewport().set_input_as_handled()
var new_tab: int = filter_bar.current_tab - 1
if (new_tab == -1):
new_tab = filter_bar.get_tab_count() - 1
filter_bar.current_tab = new_tab
#endregion
func open_file(index: int):
hide()
var file: String = files_list.get_item_metadata(index)
if (ResourceLoader.exists(file)):
var res: Resource = load(file)
EditorInterface.edit_resource(res)
if (res is PackedScene):
EditorInterface.open_scene_from_path(file)
func schedule_rebuild():
is_rebuild_cache = true
func on_show():
if (search_option_btn.selected != 0):
search_option_btn.selected = 0
is_rebuild_cache = true
var rebuild_ui: bool = false
var all_tab_not_pressed: bool = filter_bar.current_tab != 0
rebuild_ui = is_rebuild_cache || all_tab_not_pressed
if (is_rebuild_cache):
rebuild_cache()
if (rebuild_ui):
if (all_tab_not_pressed):
# Triggers the ui update.
filter_bar.current_tab = 0
else:
fill_files_list()
filter_txt.select_all()
focus_and_select_first()
func rebuild_cache():
is_rebuild_cache = false
all_files.clear()
scenes.clear()
scripts.clear()
resources.clear()
others.clear()
build_file_cache()
func rebuild_cache_and_ui():
rebuild_cache()
fill_files_list()
focus_and_select_first()
func focus_and_select_first():
filter_txt.grab_focus()
if (files_list.item_count > 0):
files_list.select(0)
func build_file_cache():
var dir: EditorFileSystemDirectory = EditorInterface.get_resource_filesystem().get_filesystem()
build_file_cache_dir(dir)
all_files.append_array(scenes)
all_files.append_array(scripts)
all_files.append_array(resources)
all_files.append_array(others)
func build_file_cache_dir(dir: EditorFileSystemDirectory):
for index: int in dir.get_subdir_count():
build_file_cache_dir(dir.get_subdir(index))
for index: int in dir.get_file_count():
var file: String = dir.get_file_path(index)
if (search_option_btn.get_selected_id() == 0 && file.begins_with(ADDONS)):
continue
var last_delimiter: int = file.rfind(&"/")
var file_name: String = file.substr(last_delimiter + 1)
var file_structure: String = &""
if (file_name.length() + 6 != file.length()):
file_structure = SEPARATOR + STRUCTURE_START + file.substr(6, last_delimiter - 6) + STRUCTURE_END
var file_data: FileData = FileData.new()
file_data.file = file
file_data.file_name = file_name
file_data.file_name_structure = file_name + file_structure
file_data.file_type = dir.get_file_type(index)
# Needed, as otherwise we have no icon.
if (file_data.file_type == &"Resource"):
file_data.file_type = &"Object"
match (file.get_extension()):
&"tscn": scenes.append(file_data)
&"gd": scripts.append(file_data)
&"tres": resources.append(file_data)
&"gdshader": resources.append(file_data)
_: others.append(file_data)
func change_fill_files_list():
fill_files_list()
focus_and_select_first()
func fill_files_list():
files_list.clear()
if (filter_bar.current_tab == 0):
fill_files_list_with(all_files)
elif (filter_bar.current_tab == 1):
fill_files_list_with(scenes)
elif (filter_bar.current_tab == 2):
fill_files_list_with(scripts)
elif (filter_bar.current_tab == 3):
fill_files_list_with(resources)
elif (filter_bar.current_tab == 4):
fill_files_list_with(others)
func fill_files_list_with(files: Array[FileData]):
var filter_text: String = filter_txt.text
files.sort_custom(sort_by_filter)
for file_data: FileData in files:
var file: String = file_data.file
if (filter_text.is_empty() || filter_text.is_subsequence_ofn(file)):
var icon: Texture2D = EditorInterface.get_base_control().get_theme_icon(file_data.file_type, &"EditorIcons")
files_list.add_item(file_data.file_name_structure, icon)
files_list.set_item_metadata(files_list.item_count - 1, file)
files_list.set_item_tooltip(files_list.item_count - 1, file)
func sort_by_filter(file_data1: FileData, file_data2: FileData) -> bool:
var filter_text: String = filter_txt.text
var name1: String = file_data1.file_name
var name2: String = file_data2.file_name
for index: int in filter_text.length():
var a_oob: bool = index >= name1.length()
var b_oob: bool = index >= name2.length()
if (a_oob):
if (b_oob):
return false;
return true
if (b_oob):
return false
var char: String = filter_text[index]
var a_match: bool = char == name1[index]
var b_match: bool = char == name2[index]
if (a_match && !b_match):
return true
if (b_match && !a_match):
return false
return name1 < name2
class FileData:
var file: String
var file_name: String
var file_name_structure: String
var file_type: StringName

View File

@@ -0,0 +1 @@
uid://cfcwyfqojcli6

View File

@@ -0,0 +1,148 @@
[gd_scene load_steps=14 format=3 uid="uid://d2pttchmj3n7q"]
[ext_resource type="Script" path="res://addons/script-ide/quickopen/quick_open_panel.gd" id="1_3tl1s"]
[sub_resource type="Image" id="Image_dfysb"]
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, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 16, 225, 225, 225, 134, 224, 224, 224, 209, 224, 224, 224, 245, 224, 224, 224, 245, 224, 224, 224, 208, 224, 224, 224, 131, 236, 236, 236, 13, 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, 224, 224, 224, 73, 224, 224, 224, 228, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 225, 225, 225, 225, 68, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 73, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 183, 224, 224, 224, 198, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 198, 224, 224, 224, 189, 224, 224, 224, 255, 224, 224, 224, 254, 224, 224, 224, 65, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 16, 224, 224, 224, 228, 224, 224, 224, 255, 224, 224, 224, 120, 226, 226, 226, 60, 224, 224, 224, 255, 225, 225, 225, 109, 225, 225, 225, 110, 224, 224, 224, 255, 226, 226, 226, 60, 224, 224, 224, 128, 224, 224, 224, 255, 225, 225, 225, 223, 234, 234, 234, 12, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 134, 224, 224, 224, 255, 225, 225, 225, 183, 255, 255, 255, 0, 224, 224, 224, 153, 224, 224, 224, 243, 255, 255, 255, 4, 255, 255, 255, 4, 224, 224, 224, 244, 225, 225, 225, 151, 255, 255, 255, 1, 225, 225, 225, 191, 224, 224, 224, 255, 225, 225, 225, 127, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 209, 224, 224, 224, 255, 224, 224, 224, 72, 255, 255, 255, 0, 224, 224, 224, 216, 224, 224, 224, 198, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 199, 224, 224, 224, 214, 255, 255, 255, 0, 226, 226, 226, 78, 224, 224, 224, 255, 224, 224, 224, 206, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 243, 224, 224, 224, 255, 226, 226, 226, 78, 255, 255, 255, 0, 224, 224, 224, 244, 225, 225, 225, 151, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 152, 224, 224, 224, 242, 255, 255, 255, 1, 227, 227, 227, 81, 224, 224, 224, 255, 224, 224, 224, 241, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 245, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 229, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 147, 225, 225, 225, 149, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 230, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 244, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 208, 224, 224, 224, 255, 224, 224, 224, 147, 224, 224, 224, 161, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 235, 224, 224, 224, 235, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 160, 225, 225, 225, 150, 224, 224, 224, 255, 224, 224, 224, 205, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 131, 224, 224, 224, 255, 224, 224, 224, 189, 255, 255, 255, 1, 224, 224, 224, 152, 224, 224, 224, 243, 255, 255, 255, 4, 255, 255, 255, 4, 224, 224, 224, 244, 225, 225, 225, 151, 255, 255, 255, 2, 225, 225, 225, 199, 224, 224, 224, 255, 225, 225, 225, 127, 255, 255, 255, 0, 255, 255, 255, 0, 236, 236, 236, 13, 224, 224, 224, 225, 224, 224, 224, 255, 224, 224, 224, 128, 225, 225, 225, 67, 224, 224, 224, 255, 225, 225, 225, 110, 226, 226, 226, 111, 224, 224, 224, 255, 225, 225, 225, 67, 225, 225, 225, 135, 224, 224, 224, 255, 224, 224, 224, 221, 234, 234, 234, 12, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 68, 224, 224, 224, 254, 224, 224, 224, 255, 224, 224, 224, 194, 224, 224, 224, 220, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 219, 224, 224, 224, 196, 224, 224, 224, 255, 224, 224, 224, 253, 227, 227, 227, 62, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 66, 224, 224, 224, 225, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 220, 226, 226, 226, 61, 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, 237, 237, 237, 14, 224, 224, 224, 130, 224, 224, 224, 206, 224, 224, 224, 244, 224, 224, 224, 244, 224, 224, 224, 205, 225, 225, 225, 124, 230, 230, 230, 10, 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, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_p6ab8"]
image = SubResource("Image_dfysb")
[sub_resource type="Image" id="Image_blafy"]
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, 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, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 25, 226, 226, 226, 70, 229, 229, 229, 39, 255, 255, 255, 0, 226, 226, 226, 103, 224, 224, 224, 219, 224, 224, 224, 156, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 26, 225, 225, 225, 25, 255, 255, 255, 0, 224, 224, 224, 74, 224, 224, 224, 177, 226, 226, 226, 111, 255, 255, 255, 0, 224, 224, 224, 98, 224, 224, 224, 255, 225, 225, 225, 182, 255, 255, 255, 0, 228, 228, 228, 46, 224, 224, 224, 255, 224, 224, 224, 197, 255, 255, 255, 0, 224, 224, 224, 57, 224, 224, 224, 255, 224, 224, 224, 187, 255, 255, 255, 0, 225, 225, 225, 42, 224, 224, 224, 255, 224, 224, 224, 232, 255, 255, 255, 6, 224, 224, 224, 8, 225, 225, 225, 182, 224, 224, 224, 153, 255, 255, 255, 7, 255, 255, 255, 0, 228, 228, 228, 37, 255, 255, 255, 7, 255, 255, 255, 0, 229, 229, 229, 19, 224, 224, 224, 237, 224, 224, 224, 198, 225, 225, 225, 17, 255, 255, 255, 0, 227, 227, 227, 71, 224, 224, 224, 48, 255, 255, 255, 4, 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, 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, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 228, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 73, 224, 224, 224, 226, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 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),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_bbwjp"]
image = SubResource("Image_blafy")
[sub_resource type="Image" id="Image_4wc14"]
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, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 33, 224, 224, 224, 255, 224, 224, 224, 255, 231, 231, 231, 31, 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, 226, 226, 226, 95, 224, 224, 224, 57, 255, 255, 255, 0, 224, 224, 224, 99, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 93, 255, 255, 255, 0, 224, 224, 224, 57, 224, 224, 224, 90, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 93, 224, 224, 224, 255, 224, 224, 224, 254, 224, 224, 224, 165, 224, 224, 224, 217, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 214, 225, 225, 225, 167, 224, 224, 224, 254, 224, 224, 224, 254, 224, 224, 224, 88, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 228, 228, 228, 55, 224, 224, 224, 254, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 253, 225, 225, 225, 51, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 166, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 160, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 33, 224, 224, 224, 99, 224, 224, 224, 217, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 186, 224, 224, 224, 32, 224, 224, 224, 33, 224, 224, 224, 187, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 215, 224, 224, 224, 98, 224, 224, 224, 32, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 33, 255, 255, 255, 0, 255, 255, 255, 0, 227, 227, 227, 36, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 33, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 38, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 231, 231, 231, 31, 226, 226, 226, 95, 224, 224, 224, 216, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 187, 225, 225, 225, 34, 226, 226, 226, 35, 224, 224, 224, 192, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 213, 226, 226, 226, 95, 231, 231, 231, 31, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 166, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 163, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 57, 224, 224, 224, 254, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 254, 227, 227, 227, 54, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 90, 224, 224, 224, 254, 224, 224, 224, 253, 224, 224, 224, 161, 225, 225, 225, 215, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 213, 224, 224, 224, 162, 224, 224, 224, 253, 224, 224, 224, 253, 226, 226, 226, 86, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 88, 225, 225, 225, 51, 255, 255, 255, 0, 224, 224, 224, 98, 224, 224, 224, 255, 224, 224, 224, 255, 226, 226, 226, 95, 255, 255, 255, 0, 227, 227, 227, 53, 226, 226, 226, 86, 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, 224, 224, 224, 32, 224, 224, 224, 255, 224, 224, 224, 255, 231, 231, 231, 31, 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, 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_ghict"]
image = SubResource("Image_4wc14")
[sub_resource type="Image" id="Image_7rebo"]
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, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 4, 224, 224, 224, 99, 224, 224, 224, 213, 224, 224, 224, 212, 224, 224, 224, 97, 255, 255, 255, 4, 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, 4, 224, 224, 224, 99, 224, 224, 224, 222, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 220, 224, 224, 224, 97, 255, 255, 255, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 4, 224, 224, 224, 99, 224, 224, 224, 222, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 213, 226, 226, 226, 87, 224, 224, 224, 88, 224, 224, 224, 214, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 220, 224, 224, 224, 97, 255, 255, 255, 4, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 199, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 215, 224, 224, 224, 89, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 2, 224, 224, 224, 90, 224, 224, 224, 216, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 194, 255, 255, 255, 0, 255, 255, 255, 4, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 221, 224, 224, 224, 99, 255, 255, 255, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 5, 225, 225, 225, 101, 225, 225, 225, 223, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 3, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 213, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 222, 225, 225, 225, 100, 225, 225, 225, 100, 225, 225, 225, 223, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 3, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 2, 226, 226, 226, 87, 224, 224, 224, 213, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 2, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 2, 226, 226, 226, 87, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 1, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 100, 255, 255, 255, 5, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 196, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 223, 225, 225, 225, 101, 255, 255, 255, 5, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 193, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 3, 225, 225, 225, 93, 224, 224, 224, 218, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 223, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 216, 225, 225, 225, 91, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 3, 225, 225, 225, 93, 224, 224, 224, 218, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 216, 225, 225, 225, 91, 255, 255, 255, 2, 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, 3, 225, 225, 225, 93, 224, 224, 224, 208, 225, 225, 225, 207, 225, 225, 225, 91, 255, 255, 255, 2, 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, 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_grjtr"]
image = SubResource("Image_7rebo")
[sub_resource type="Image" id="Image_e7nb8"]
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, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 181, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 77, 225, 225, 225, 76, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 222, 224, 224, 224, 221, 224, 224, 224, 8, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 120, 224, 224, 224, 32, 224, 224, 224, 128, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 127, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 226, 226, 226, 35, 224, 224, 224, 248, 224, 224, 224, 195, 224, 224, 224, 247, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 247, 225, 225, 225, 34, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 224, 224, 224, 180, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 178, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 181, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 180, 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_xupch"]
image = SubResource("Image_e7nb8")
[sub_resource type="Image" id="Image_gfvg1"]
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, 255, 255, 0, 225, 225, 225, 68, 224, 224, 224, 184, 224, 224, 224, 240, 224, 224, 224, 232, 224, 224, 224, 186, 227, 227, 227, 62, 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, 224, 224, 224, 129, 224, 224, 224, 254, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 122, 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, 225, 225, 225, 68, 224, 224, 224, 254, 224, 224, 224, 254, 224, 224, 224, 123, 224, 224, 224, 32, 224, 224, 224, 33, 225, 225, 225, 125, 224, 224, 224, 254, 224, 224, 224, 254, 226, 226, 226, 69, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 123, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 125, 224, 224, 224, 255, 225, 225, 225, 174, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 240, 224, 224, 224, 255, 231, 231, 231, 31, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 35, 224, 224, 224, 255, 224, 224, 224, 233, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 232, 224, 224, 224, 255, 224, 224, 224, 32, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 228, 228, 228, 37, 224, 224, 224, 255, 224, 224, 224, 228, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 186, 224, 224, 224, 255, 224, 224, 224, 123, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 130, 224, 224, 224, 255, 224, 224, 224, 173, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 227, 227, 227, 62, 224, 224, 224, 255, 224, 224, 224, 254, 225, 225, 225, 126, 225, 225, 225, 34, 227, 227, 227, 36, 224, 224, 224, 131, 224, 224, 224, 255, 224, 224, 224, 255, 226, 226, 226, 77, 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, 224, 224, 224, 122, 224, 224, 224, 254, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 210, 231, 231, 231, 21, 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, 226, 226, 226, 69, 225, 225, 225, 174, 224, 224, 224, 233, 224, 224, 224, 228, 224, 224, 224, 173, 226, 226, 226, 77, 224, 224, 224, 210, 224, 224, 224, 255, 224, 224, 224, 210, 231, 231, 231, 21, 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, 231, 231, 231, 21, 224, 224, 224, 210, 224, 224, 224, 255, 224, 224, 224, 210, 231, 231, 231, 21, 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, 231, 231, 231, 21, 224, 224, 224, 210, 224, 224, 224, 255, 224, 224, 224, 210, 231, 231, 231, 21, 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, 231, 231, 231, 21, 224, 224, 224, 210, 224, 224, 224, 227, 225, 225, 225, 34, 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, 231, 231, 231, 21, 225, 225, 225, 34, 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_w6vkw"]
image = SubResource("Image_gfvg1")
[node name="QuickOpenPanel" type="PopupPanel"]
size = Vector2i(624, 100)
visible = true
script = ExtResource("1_3tl1s")
[node name="PanelContainer" type="PanelContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 5
theme_override_constants/margin_top = 5
theme_override_constants/margin_right = 5
theme_override_constants/margin_bottom = 5
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 5
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 4
[node name="FilterBar" type="TabBar" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
current_tab = 0
clip_tabs = false
scrolling_enabled = false
tab_count = 5
tab_0/title = "All"
tab_0/icon = SubResource("ImageTexture_p6ab8")
tab_1/title = "Scene"
tab_1/icon = SubResource("ImageTexture_bbwjp")
tab_2/title = "GDscript"
tab_2/icon = SubResource("ImageTexture_ghict")
tab_3/title = "Resource"
tab_3/icon = SubResource("ImageTexture_grjtr")
tab_4/title = "Other"
tab_4/icon = SubResource("ImageTexture_xupch")
[node name="SearchOptionBtn" type="OptionButton" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
selected = 0
item_count = 2
popup/item_0/text = "Project"
popup/item_0/id = 0
popup/item_1/text = "Project+Addons"
popup/item_1/id = 1
[node name="FilterTxt" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
placeholder_text = "Filter files"
right_icon = SubResource("ImageTexture_w6vkw")
[node name="FilesList" type="ItemList" parent="PanelContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
allow_reselect = true

View File

@@ -0,0 +1,15 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://6pefe8sf513q"]
[resource]
bus/1/name = &"Effects"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = &"Master"
bus/2/name = &"Weather"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = &"Master"