diff --git a/addons/ai_editor/AIEditorScene.gd b/addons/ai_editor/AIEditorScene.gd new file mode 100644 index 0000000..f4bec53 --- /dev/null +++ b/addons/ai_editor/AIEditorScene.gd @@ -0,0 +1,12 @@ +tool +extends Control + +#var _ai_action : AIAction + +func _ready(): + pass + +#func set_target(ai_action : AIAction) -> void: +# _ai_action = ai_action + +# $AIGraphEdit.set_target(ai_action) diff --git a/addons/ai_editor/AIEditorScene.tscn b/addons/ai_editor/AIEditorScene.tscn new file mode 100644 index 0000000..76c7930 --- /dev/null +++ b/addons/ai_editor/AIEditorScene.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://addons/ai_editor/AIEditorScene.gd" type="Script" id=1] +[ext_resource path="res://addons/ai_editor/AIGraphEdit.gd" type="Script" id=2] +[ext_resource path="res://addons/ai_editor/CreateActionPopup.gd" type="Script" id=3] + +[node name="AIEditorScene" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +rect_min_size = Vector2( 0, 200 ) +mouse_filter = 2 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="AIGraphEdit" type="GraphEdit" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +right_disconnects = true +script = ExtResource( 2 ) +__meta__ = { +"_edit_lock_": true, +"_edit_use_anchors_": false +} +create_action_popup = NodePath("../CreateActionPopup") + +[node name="CreateActionPopup" type="ConfirmationDialog" parent="."] +margin_left = 38.0 +margin_top = 113.0 +margin_right = 262.0 +margin_bottom = 357.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +window_title = "Add New ..." +resizable = true +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} +tree_path = NodePath("VBoxContainer/Tree") +search_le_path = NodePath("VBoxContainer/LineEdit") + +[node name="VBoxContainer" type="VBoxContainer" parent="CreateActionPopup"] +margin_left = 8.0 +margin_top = 8.0 +margin_right = 216.0 +margin_bottom = 208.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LineEdit" type="LineEdit" parent="CreateActionPopup/VBoxContainer"] +visible = false +margin_right = 208.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 +placeholder_text = "Search" + +[node name="Tree" type="Tree" parent="CreateActionPopup/VBoxContainer"] +margin_right = 208.0 +margin_bottom = 200.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +hide_folding = true +hide_root = true diff --git a/addons/ai_editor/AIGraphEdit.gd b/addons/ai_editor/AIGraphEdit.gd new file mode 100644 index 0000000..8e9786c --- /dev/null +++ b/addons/ai_editor/AIGraphEdit.gd @@ -0,0 +1,172 @@ +tool +extends GraphEdit + +export(NodePath) var create_action_popup : NodePath + +var _create_action_popup : PopupMenu +var _actions : Array + +func _ready() -> void: + _create_action_popup = get_node(create_action_popup) + _create_action_popup.connect("action_selected", self, "create_action") + + connect("popup_request", self, "popup_request") + connect("connection_request", self, "connection_request") + connect("disconnection_request", self, "disconnection_request") + + +func popup_request(position: Vector2) -> void: + _create_action_popup.rect_position = position + _create_action_popup.popup() + +func create_action(action) -> void: + var cls : Script + + var pclass = action + while cls == null and pclass != "": + var file_name : String = "res://addons/ai_editor/editors/" + pclass + "Editor.gd" + + var d : Directory = Directory.new() + + if d.file_exists(file_name): + cls = load(file_name) + else: + pclass = get_parent_class(pclass) + + if cls == null: + print("AiGraphEdit cls==null! (create_action)") + + var n : GraphNode = cls.new() as GraphNode + add_child(n) + n.owner = self + n.rect_position = _create_action_popup.rect_position + + if ClassDB.class_exists(action): + n.set_action(ClassDB.instance(action)) + else: + var gsc : Array = ProjectSettings.get("_global_script_classes") + + for i in range(gsc.size()): + var d : Dictionary = gsc[i] as Dictionary + + if action == d["class"]: + var scls : Script = load(d["path"]) + n.set_action(scls.new()) + +func connection_request(from: String, from_slot: int, to: String, to_slot: int) -> void: + var node = get_node(from) + var to_node = get_node(to) + if node.connected_to(from_slot, to_node): + connect_node(from, from_slot, to, to_slot) + save() + +func disconnection_request(from: String, from_slot: int, to: String, to_slot: int) -> void: + var node = get_node(from) + if node.disconnected_from(from_slot): + disconnect_node(from, from_slot, to, to_slot) + save() + +func save(): + for action in _actions: + ResourceSaver.save(action.resource_path, action) + +func close_request(graph_node : Node) -> void: + remove_node(graph_node) + +# { from_port: 0, from: "GraphNode name 0", to_port: 1, to: "GraphNode name 1" }. + +func remove_node(graph_node : Node) -> void: + var connections : Array = get_connection_list() + + for conn in connections: + if conn["from"] == graph_node.name: + remove_node(get_node(conn["to"])) + disconnect_node(conn["from"], conn["from_port"], conn["to"], conn["to_port"]) + + graph_node.queue_free() + +func add_action(ai_action : AIAction, position: Vector2) -> void: + _actions.append(ai_action) + + var n : GraphNode = get_graph_node_for(ai_action) + + n.rect_position = position +# n.rect_position = _create_action_popup.rect_position + n.set_action(ai_action) + +func get_parent_class(cls_name: String) -> String: + if ClassDB.class_exists(cls_name): + return ClassDB.get_parent_class(cls_name) + + var gsc : Array = ProjectSettings.get("_global_script_classes") + + for i in range(gsc.size()): + var d : Dictionary = gsc[i] as Dictionary + + if cls_name == d["class"]: + return d["base"] + + return "" + +func get_graph_node_for(action : AIAction) -> GraphNode: + var cls : Script + + var pclass : String = action.get_class() + +# if action.get_script() != null: +# var gsc : Array = ProjectSettings.get("_global_script_classes") +# +# for i in range(gsc.size()): +# var d : Dictionary = gsc[i] as Dictionary +# +# print(d) +# if cls_name == d["path"]: +# d["base"] + + while cls == null and pclass != "": + var file_name : String = "res://addons/ai_editor/editors/" + pclass + "Editor.gd" + + var d : Directory = Directory.new() + + if d.file_exists(file_name): + cls = load(file_name) + else: + pclass = get_parent_class(pclass) + + if cls == null: + print("AiGraphEdit cls==null! (get_graph_node_for)") + return null + + var n : GraphNode = cls.new() as GraphNode + add_child(n) + n.owner = self + + return n + +func can_drop_data(position, data): + if data is AIAction: + return true + + if data is Dictionary: + if data.has("type") and data["type"] == "files" and data.has("files"): + for file in data["files"]: + if ResourceLoader.exists(file): + var res : Resource = ResourceLoader.load(file) + + if res is AIAction: + return true + + return false + +func drop_data(position, data): + if data is AIAction: + return true + + if data is Dictionary: + if data.has("type") and data["type"] == "files" and data.has("files"): + for file in data["files"]: + if ResourceLoader.exists(file): + var res : Resource = ResourceLoader.load(file) + + if res is AIAction: + add_action(res, position) diff --git a/addons/ai_editor/CreateActionPopup.gd b/addons/ai_editor/CreateActionPopup.gd new file mode 100644 index 0000000..617c69c --- /dev/null +++ b/addons/ai_editor/CreateActionPopup.gd @@ -0,0 +1,59 @@ +tool +extends AcceptDialog + +signal action_selected + +export(NodePath) var tree_path : NodePath +export(NodePath) var search_le_path : NodePath + +var _search_le : LineEdit +var _tree : Tree + +var _group : ButtonGroup + +func _ready(): + _search_le = get_node(search_le_path) as LineEdit + _tree = get_node(tree_path) as Tree + _tree.connect("item_activated", self, "item_activated") + + connect("about_to_show", self, "about_to_show") + +func about_to_show(): + _tree.clear() + + var arr : PoolStringArray = PoolStringArray() + arr.append("AIAction") + arr.append_array(ClassDB.get_inheriters_from_class("AIAction")) + + var gsc : Array = ProjectSettings.get("_global_script_classes") + + var l : int = arr.size() - 1 + + while (arr.size() != l): + l = arr.size() + + for i in range(gsc.size()): + var d : Dictionary = gsc[i] as Dictionary + + var found = false + for j in range(arr.size()): + if arr[j] == d["class"]: + found = true + break + + if found: + continue + + for j in range(arr.size()): + if arr[j] == d["base"]: + arr.append(d["class"]) + + _tree.create_item() + for a in arr: + var ti : TreeItem = _tree.create_item() + ti.set_text(0, a) + + +func item_activated() -> void: + emit_signal("action_selected", _tree.get_selected().get_text(0)) + hide() diff --git a/addons/ai_editor/editors/AIActionContainerEditor.gd b/addons/ai_editor/editors/AIActionContainerEditor.gd new file mode 100644 index 0000000..1bba4bc --- /dev/null +++ b/addons/ai_editor/editors/AIActionContainerEditor.gd @@ -0,0 +1,79 @@ +extends "AIActionEditor.gd" + +var _add_button : Button +var _remove_button : Button +var _hbox : HBoxContainer +var _labels : Array + +func _ready(): + title = "AIActionContainer" + +func setup() -> void: + .setup() + + _hbox = HBoxContainer.new() + _hbox.size_flags_vertical = SIZE_EXPAND_FILL + add_child(_hbox) + _hbox.owner = self + + _add_button = Button.new() + _add_button.rect_min_size = Vector2(0, 30) + _add_button.size_flags_horizontal = SIZE_EXPAND_FILL + _add_button.text = "Add" + _add_button.connect("pressed", self, "add_pressed") + _hbox.add_child(_add_button) + _add_button.owner = _hbox + + _remove_button = Button.new() + _remove_button.rect_min_size = Vector2(0, 30) + _remove_button.size_flags_horizontal = SIZE_EXPAND_FILL + _remove_button.text = "Remove" + _remove_button.connect("pressed", self, "remove_pressed") + _hbox.add_child(_remove_button) + _remove_button.owner = _hbox + + +func add_pressed() -> void: + _action.set_num_ai_actions(_action.get_num_ai_actions() + 1) + + var button : Label = Label.new() + button.rect_min_size = Vector2(0, 30) + button.text = "Entry " + str(_labels.size()) + + if _labels.size() > 0: + add_child_below_node(_labels.back(), button) + else: + add_child(button) + + set_slot(get_child_count() - 1, false, 0, Color(1, 0, 0), true, 0, Color(1, 0, 0)) + + button.owner = self + + _labels.append(button) + +func remove_pressed() -> void: + pass + +func connected_to(from_slot, to_node) -> bool: + if from_slot > _labels.size(): + return false + + if (_action.get_ai_action(from_slot) != null): + return false + + var action : AIAction = to_node._action + + for i in range(_action.get_num_ai_actions()): + if (_action.get_ai_action(i) == action): + return false + + _action.set_ai_action(from_slot, action) + return true + +func disconnected_from(from_slot) -> bool: + if from_slot > _labels.size(): + return false + + _action.set_ai_action(from_slot, null) + + return true diff --git a/addons/ai_editor/editors/AIActionEditor.gd b/addons/ai_editor/editors/AIActionEditor.gd new file mode 100644 index 0000000..ab8f896 --- /dev/null +++ b/addons/ai_editor/editors/AIActionEditor.gd @@ -0,0 +1,52 @@ +extends GraphNode + +var _action : AIAction + +func _ready(): + title = "AIAction" + show_close = true + resizable = true + rect_min_size = Vector2(200, 40) + + connect("close_request", self, "close_request") + connect("resize_request", self, "resize_request") + + setup() + +func set_action(action) -> void: + _action = action + + if _action: + title = _action.get_class() + + if _action.has_method("get_title"): + title = _action.get_title() + + setup() + +func setup() -> void: + for ch in get_children(): + ch.queue_free() + remove_child(ch) + + var le : LineEdit = LineEdit.new() + le.rect_min_size = Vector2(0, 30) + le.placeholder_text = "Description" + add_child(le) + le.owner = self + + set_slot(0, true, 0, Color(1, 0, 0), false, 0, Color(1, 0, 0)) + + +func close_request() -> void: + get_node("..").close_request(self) +# queue_free() + +func resize_request(new_min_size: Vector2) -> void: + rect_min_size = new_min_size + +func connected_to(from_slot, to_node) -> bool: + return false + +func disconnected_from(from_slot) -> bool: + return false diff --git a/addons/ai_editor/plugin.cfg b/addons/ai_editor/plugin.cfg new file mode 100644 index 0000000..1968e6e --- /dev/null +++ b/addons/ai_editor/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="AI Editor" +description="" +author="Relintai" +version="" +script="plugin.gd" diff --git a/addons/ai_editor/plugin.gd b/addons/ai_editor/plugin.gd new file mode 100644 index 0000000..ab879c1 --- /dev/null +++ b/addons/ai_editor/plugin.gd @@ -0,0 +1,31 @@ +tool +extends EditorPlugin + +var ai_editor_scene_data : PackedScene = preload("res://addons/ai_editor/AIEditorScene.tscn") as PackedScene + +var main_scene : Control +var bottom_panel_button : ToolButton + +var edited_ai_action : AIAction + +func _enter_tree(): + main_scene = ai_editor_scene_data.instance() as Control + bottom_panel_button = add_control_to_bottom_panel(main_scene, "AI Editor") + +func _exit_tree(): + remove_control_from_bottom_panel(main_scene) + main_scene.queue_free() +# bottom_panel_button.queue_free() +# bottom_panel_button.hide() + +# +#func edit(object : Object) -> void: +# edited_ai_action = object as AIAction +# main_scene.set_target(edited_ai_action) +# +# bottom_panel_button.show() +# +# +#func handles(object : Object) -> bool: +# return object is AIAction + diff --git a/addons/ess_data/icons/empty.png b/addons/ess_data/icons/empty.png new file mode 100644 index 0000000..2504386 Binary files /dev/null and b/addons/ess_data/icons/empty.png differ diff --git a/addons/ess_data/icons/empty.png.import b/addons/ess_data/icons/empty.png.import new file mode 100644 index 0000000..5ca1d78 --- /dev/null +++ b/addons/ess_data/icons/empty.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/empty.png-7d550719aef4fbbab6c3c1fd09591e6e.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/empty.png" +dest_files=[ "res://.import/empty.png-7d550719aef4fbbab6c3c1fd09591e6e.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/gom.png b/addons/ess_data/icons/gom.png new file mode 100644 index 0000000..ca3781a Binary files /dev/null and b/addons/ess_data/icons/gom.png differ diff --git a/addons/ess_data/icons/gom.png.import b/addons/ess_data/icons/gom.png.import new file mode 100644 index 0000000..f9a1610 --- /dev/null +++ b/addons/ess_data/icons/gom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/gom.png-d698d0c3faea0ed12695dac1cd72a8b5.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/gom.png" +dest_files=[ "res://.import/gom.png-d698d0c3faea0ed12695dac1cd72a8b5.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_add.png b/addons/ess_data/icons/icon_add.png new file mode 100644 index 0000000..297be14 Binary files /dev/null and b/addons/ess_data/icons/icon_add.png differ diff --git a/addons/ess_data/icons/icon_add.png.import b/addons/ess_data/icons/icon_add.png.import new file mode 100644 index 0000000..6c606fc --- /dev/null +++ b/addons/ess_data/icons/icon_add.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_add.png-f1c162d7141223cc47cbd782b2d3c33b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_add.png" +dest_files=[ "res://.import/icon_add.png-f1c162d7141223cc47cbd782b2d3c33b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_copy.png b/addons/ess_data/icons/icon_copy.png new file mode 100644 index 0000000..d777f13 Binary files /dev/null and b/addons/ess_data/icons/icon_copy.png differ diff --git a/addons/ess_data/icons/icon_copy.png.import b/addons/ess_data/icons/icon_copy.png.import new file mode 100644 index 0000000..4a9e6cd --- /dev/null +++ b/addons/ess_data/icons/icon_copy.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_copy.png-119a754954c46d28a8bb4cf6c097bc4e.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_copy.png" +dest_files=[ "res://.import/icon_copy.png-119a754954c46d28a8bb4cf6c097bc4e.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_display-name.png b/addons/ess_data/icons/icon_display-name.png new file mode 100644 index 0000000..7c44933 Binary files /dev/null and b/addons/ess_data/icons/icon_display-name.png differ diff --git a/addons/ess_data/icons/icon_display-name.png.import b/addons/ess_data/icons/icon_display-name.png.import new file mode 100644 index 0000000..df588ab --- /dev/null +++ b/addons/ess_data/icons/icon_display-name.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_display-name.png-6dc1154c5644fb44130ce9337c2bdc41.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_display-name.png" +dest_files=[ "res://.import/icon_display-name.png-6dc1154c5644fb44130ce9337c2bdc41.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_duplicate.png b/addons/ess_data/icons/icon_duplicate.png new file mode 100644 index 0000000..320b365 Binary files /dev/null and b/addons/ess_data/icons/icon_duplicate.png differ diff --git a/addons/ess_data/icons/icon_duplicate.png.import b/addons/ess_data/icons/icon_duplicate.png.import new file mode 100644 index 0000000..66ce1fe --- /dev/null +++ b/addons/ess_data/icons/icon_duplicate.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_duplicate.png-8eb42030f197f9948b088f65267a9357.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_duplicate.png" +dest_files=[ "res://.import/icon_duplicate.png-8eb42030f197f9948b088f65267a9357.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_edit.png b/addons/ess_data/icons/icon_edit.png new file mode 100644 index 0000000..c114d2f Binary files /dev/null and b/addons/ess_data/icons/icon_edit.png differ diff --git a/addons/ess_data/icons/icon_edit.png.import b/addons/ess_data/icons/icon_edit.png.import new file mode 100644 index 0000000..77e24e0 --- /dev/null +++ b/addons/ess_data/icons/icon_edit.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_edit.png-1b2eb4935f9c052ce779434d5a5b98eb.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_edit.png" +dest_files=[ "res://.import/icon_edit.png-1b2eb4935f9c052ce779434d5a5b98eb.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_empty.png b/addons/ess_data/icons/icon_empty.png new file mode 100644 index 0000000..da163ba Binary files /dev/null and b/addons/ess_data/icons/icon_empty.png differ diff --git a/addons/ess_data/icons/icon_empty.png.import b/addons/ess_data/icons/icon_empty.png.import new file mode 100644 index 0000000..f01bf90 --- /dev/null +++ b/addons/ess_data/icons/icon_empty.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_empty.png-ee1200a4d86ed59a87bf05f5e5e7e845.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_empty.png" +dest_files=[ "res://.import/icon_empty.png-ee1200a4d86ed59a87bf05f5e5e7e845.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_load.png b/addons/ess_data/icons/icon_load.png new file mode 100644 index 0000000..cc05e98 Binary files /dev/null and b/addons/ess_data/icons/icon_load.png differ diff --git a/addons/ess_data/icons/icon_load.png.import b/addons/ess_data/icons/icon_load.png.import new file mode 100644 index 0000000..73a9800 --- /dev/null +++ b/addons/ess_data/icons/icon_load.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_load.png-58b86a3410a73664f2d01d988023e6b0.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_load.png" +dest_files=[ "res://.import/icon_load.png-58b86a3410a73664f2d01d988023e6b0.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_move_down.png b/addons/ess_data/icons/icon_move_down.png new file mode 100644 index 0000000..3934310 Binary files /dev/null and b/addons/ess_data/icons/icon_move_down.png differ diff --git a/addons/ess_data/icons/icon_move_down.png.import b/addons/ess_data/icons/icon_move_down.png.import new file mode 100644 index 0000000..44f04ec --- /dev/null +++ b/addons/ess_data/icons/icon_move_down.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_move_down.png-de4dd05da066b6cb62171d65d80c378a.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_move_down.png" +dest_files=[ "res://.import/icon_move_down.png-de4dd05da066b6cb62171d65d80c378a.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_move_up.png b/addons/ess_data/icons/icon_move_up.png new file mode 100644 index 0000000..684013d Binary files /dev/null and b/addons/ess_data/icons/icon_move_up.png differ diff --git a/addons/ess_data/icons/icon_move_up.png.import b/addons/ess_data/icons/icon_move_up.png.import new file mode 100644 index 0000000..91d5c6c --- /dev/null +++ b/addons/ess_data/icons/icon_move_up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_move_up.png-5ccb4340283b687498f5a33f13527817.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_move_up.png" +dest_files=[ "res://.import/icon_move_up.png-5ccb4340283b687498f5a33f13527817.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_multi_line.png b/addons/ess_data/icons/icon_multi_line.png new file mode 100644 index 0000000..95a029c Binary files /dev/null and b/addons/ess_data/icons/icon_multi_line.png differ diff --git a/addons/ess_data/icons/icon_multi_line.png.import b/addons/ess_data/icons/icon_multi_line.png.import new file mode 100644 index 0000000..9f34819 --- /dev/null +++ b/addons/ess_data/icons/icon_multi_line.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_multi_line.png-58479647109203a3e456a4d737bd1328.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_multi_line.png" +dest_files=[ "res://.import/icon_multi_line.png-58479647109203a3e456a4d737bd1328.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_options.png b/addons/ess_data/icons/icon_options.png new file mode 100644 index 0000000..4db4c53 Binary files /dev/null and b/addons/ess_data/icons/icon_options.png differ diff --git a/addons/ess_data/icons/icon_options.png.import b/addons/ess_data/icons/icon_options.png.import new file mode 100644 index 0000000..a2808fe --- /dev/null +++ b/addons/ess_data/icons/icon_options.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_options.png-6c0d3e25749924929760b01adc5b895b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_options.png" +dest_files=[ "res://.import/icon_options.png-6c0d3e25749924929760b01adc5b895b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_reload_small.png b/addons/ess_data/icons/icon_reload_small.png new file mode 100644 index 0000000..1397ac6 Binary files /dev/null and b/addons/ess_data/icons/icon_reload_small.png differ diff --git a/addons/ess_data/icons/icon_reload_small.png.import b/addons/ess_data/icons/icon_reload_small.png.import new file mode 100644 index 0000000..6ce2628 --- /dev/null +++ b/addons/ess_data/icons/icon_reload_small.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_reload_small.png-db1811167f43bb3e8d99174883afeb9c.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_reload_small.png" +dest_files=[ "res://.import/icon_reload_small.png-db1811167f43bb3e8d99174883afeb9c.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_remove.png b/addons/ess_data/icons/icon_remove.png new file mode 100644 index 0000000..289db46 Binary files /dev/null and b/addons/ess_data/icons/icon_remove.png differ diff --git a/addons/ess_data/icons/icon_remove.png.import b/addons/ess_data/icons/icon_remove.png.import new file mode 100644 index 0000000..5e13ceb --- /dev/null +++ b/addons/ess_data/icons/icon_remove.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_remove.png-a3408a3cd525a7aacd07e8019ee54c2b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_remove.png" +dest_files=[ "res://.import/icon_remove.png-a3408a3cd525a7aacd07e8019ee54c2b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_rename.png b/addons/ess_data/icons/icon_rename.png new file mode 100644 index 0000000..2df503f Binary files /dev/null and b/addons/ess_data/icons/icon_rename.png differ diff --git a/addons/ess_data/icons/icon_rename.png.import b/addons/ess_data/icons/icon_rename.png.import new file mode 100644 index 0000000..0d372be --- /dev/null +++ b/addons/ess_data/icons/icon_rename.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_rename.png-81d5babde7eb52ef868d3ebad1288dd1.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_rename.png" +dest_files=[ "res://.import/icon_rename.png-81d5babde7eb52ef868d3ebad1288dd1.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_save.png b/addons/ess_data/icons/icon_save.png new file mode 100644 index 0000000..8695b78 Binary files /dev/null and b/addons/ess_data/icons/icon_save.png differ diff --git a/addons/ess_data/icons/icon_save.png.import b/addons/ess_data/icons/icon_save.png.import new file mode 100644 index 0000000..0ed5838 --- /dev/null +++ b/addons/ess_data/icons/icon_save.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_save.png-62e6c0742a7d0865897693870b8c7854.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_save.png" +dest_files=[ "res://.import/icon_save.png-62e6c0742a7d0865897693870b8c7854.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/icons/icon_script.png b/addons/ess_data/icons/icon_script.png new file mode 100644 index 0000000..5aa673f Binary files /dev/null and b/addons/ess_data/icons/icon_script.png differ diff --git a/addons/ess_data/icons/icon_script.png.import b/addons/ess_data/icons/icon_script.png.import new file mode 100644 index 0000000..31a6108 --- /dev/null +++ b/addons/ess_data/icons/icon_script.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_script.png-b798d172fd493df9b9ca3cb2010c4cd4.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/ess_data/icons/icon_script.png" +dest_files=[ "res://.import/icon_script.png-b798d172fd493df9b9ca3cb2010c4cd4.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/ess_data/panels/CreateNamePopup.gd b/addons/ess_data/panels/CreateNamePopup.gd new file mode 100644 index 0000000..b8a6bf7 --- /dev/null +++ b/addons/ess_data/panels/CreateNamePopup.gd @@ -0,0 +1,64 @@ +tool +extends ConfirmationDialog + +signal ok_pressed + +export(NodePath) var line_edit_path : NodePath +export(NodePath) var option_button_path : NodePath + +var _resource_type : String + +var _line_edit : LineEdit +var _option_button : OptionButton + +func _ready(): + _line_edit = get_node(line_edit_path) as LineEdit + _option_button = get_node(option_button_path) as OptionButton + + connect("confirmed", self, "_on_OK_pressed") + connect("about_to_show", self, "about_to_show") + +func set_resource_type(resource_type : String) -> void: + _resource_type = resource_type + + +func about_to_show(): + _option_button.clear() + + if not ClassDB.class_exists(_resource_type): + return + + var arr : PoolStringArray = PoolStringArray() + arr.append(_resource_type) + arr.append_array(ClassDB.get_inheriters_from_class(_resource_type)) + + var gsc : Array = ProjectSettings.get("_global_script_classes") + + var l : int = arr.size() - 1 + + while (arr.size() != l): + l = arr.size() + + for i in range(gsc.size()): + var d : Dictionary = gsc[i] as Dictionary + + var found = false + for j in range(arr.size()): + if arr[j] == d["class"]: + found = true + break + + if found: + continue + + for j in range(arr.size()): + if arr[j] == d["base"]: + arr.append(d["class"]) + + for a in arr: + _option_button.add_item(a) + + +func _on_OK_pressed(): + emit_signal("ok_pressed", _line_edit.text, _option_button.get_item_text(_option_button.selected)) + hide() diff --git a/addons/ess_data/panels/CreateNamePopup.tscn b/addons/ess_data/panels/CreateNamePopup.tscn new file mode 100644 index 0000000..2d3d32d --- /dev/null +++ b/addons/ess_data/panels/CreateNamePopup.tscn @@ -0,0 +1,57 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/panels/CreateNamePopup.gd" type="Script" id=1] + +[node name="CreateNamePopup" type="ConfirmationDialog"] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -245.5 +margin_top = -125.5 +margin_right = 245.5 +margin_bottom = 125.5 +window_title = "Create New Resource" +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +line_edit_path = NodePath("VBoxContainer/LineEdit") +option_button_path = NodePath("VBoxContainer/OptionButton") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +margin_left = 16.0 +margin_top = 16.0 +margin_right = 475.0 +margin_bottom = 182.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Label2" type="Label" parent="VBoxContainer"] +margin_right = 449.0 +margin_bottom = 25.0 +size_flags_horizontal = 3 +text = "Type" + +[node name="OptionButton" type="OptionButton" parent="VBoxContainer"] +margin_top = 33.0 +margin_right = 449.0 +margin_bottom = 70.0 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer"] +margin_top = 78.0 +margin_right = 449.0 +margin_bottom = 103.0 +size_flags_horizontal = 3 +text = "Name" + +[node name="LineEdit" type="LineEdit" parent="VBoxContainer"] +margin_top = 111.0 +margin_right = 449.0 +margin_bottom = 156.0 +size_flags_horizontal = 3 +caret_blink = true diff --git a/addons/ess_data/panels/EntryButton.gd b/addons/ess_data/panels/EntryButton.gd new file mode 100644 index 0000000..80913e3 --- /dev/null +++ b/addons/ess_data/panels/EntryButton.gd @@ -0,0 +1,93 @@ +tool +extends Control + +signal inspect_data +signal duplicate +signal delete + +export(PackedScene) var spatial_preview : PackedScene +export(PackedScene) var node2d_preview : PackedScene +export(PackedScene) var control_preview : PackedScene +export(PackedScene) var texture_preview : PackedScene + +export(NodePath) var main_button_path : NodePath + +var _main_button : Button + +var _preview : Node +var _data : Resource + +func _ready(): + _main_button = get_node(main_button_path) as Button + +func set_resource(data : Resource) -> void: + _data = data + + _main_button.set_resource(data) + + var name_text : String = "" + + if data.has_method("get_id"): + name_text += str(data.get_id()) + " - " + + if data.has_method("get_text_name"): + name_text += str(data.get_text_name()) + else: + if data.resource_name != "": + name_text += data.resource_name + else: + name_text += data.resource_path + + if data.has_method("get_rank"): + name_text += " - Rank " + str(data.get_rank()) + + if data is Texture: + _preview = texture_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.set_texture(data as Texture) + elif data is PackedScene: + var n : Node = data.instance() + + if _preview != null: + _preview.queue_free() + + if n is Spatial: + _preview = spatial_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.preview(n as Spatial) + elif n is Node2D: + _preview = node2d_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.preview(n as Node2D) + elif n is Control: + _preview = control_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.preview(n as Control) + else: + n.queue_free() + + _main_button.text = name_text + +func can_drop_data(position, data): + return false + +func inspect(): + emit_signal("inspect_data", _data) + +func duplicate_data(): + emit_signal("duplicate", _data) + +func delete(): + emit_signal("delete", _data) diff --git a/addons/ess_data/panels/FolderEntryButton.gd b/addons/ess_data/panels/FolderEntryButton.gd new file mode 100644 index 0000000..8fc59cb --- /dev/null +++ b/addons/ess_data/panels/FolderEntryButton.gd @@ -0,0 +1,12 @@ +tool +extends Button + +export(int) var tab = 0 + +var _panel + +func _pressed(): + _panel.set_tab(tab) + +func set_main_panel(panel): + _panel = panel diff --git a/addons/ess_data/panels/FolderEntryButton.tscn b/addons/ess_data/panels/FolderEntryButton.tscn new file mode 100644 index 0000000..6d98af5 --- /dev/null +++ b/addons/ess_data/panels/FolderEntryButton.tscn @@ -0,0 +1,9 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/panels/FolderEntryButton.gd" type="Script" id=1] + +[node name="FolderEntryButton" type="Button"] +margin_right = 210.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 +script = ExtResource( 1 ) diff --git a/addons/ess_data/panels/HistoryEntry.gd b/addons/ess_data/panels/HistoryEntry.gd new file mode 100644 index 0000000..f32b6e1 --- /dev/null +++ b/addons/ess_data/panels/HistoryEntry.gd @@ -0,0 +1,39 @@ +tool +extends Button + +signal history_entry_selected + +var data : Resource setget set_data#, get_data + +func _pressed() -> void: + emit_signal("history_entry_selected", data) + +func set_data(pdata: Resource) -> void: + data = pdata + + var s : String = "(" + data.get_class() + ") " + + if data.has_method("get_id"): + s += str(data.get_id()) + " - " + + if data.has_method("get_text_name"): + s += str(data.get_text_name()) + + if data.has_method("get_rank"): + s += " (R " + str(data.get_rank()) + ")" + + text = s + +func get_data() -> Resource: + return data + +func get_drag_data(position): + if data == null: + return null + + var d : Dictionary = Dictionary() + d["type"] = "resource" + d["resource"] = data + d["from"] = self + + return d diff --git a/addons/ess_data/panels/HistoryEntry.tscn b/addons/ess_data/panels/HistoryEntry.tscn new file mode 100644 index 0000000..35a3b06 --- /dev/null +++ b/addons/ess_data/panels/HistoryEntry.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/panels/HistoryEntry.gd" type="Script" id=1] + +[node name="HistoryEntry" type="Button"] +margin_right = 236.0 +margin_bottom = 37.0 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/addons/ess_data/panels/MainPanel.gd b/addons/ess_data/panels/MainPanel.gd new file mode 100644 index 0000000..734e7bb --- /dev/null +++ b/addons/ess_data/panels/MainPanel.gd @@ -0,0 +1,261 @@ +tool +extends Control + +signal inspect_data + +export(PackedScene) var resource_scene : PackedScene +export(PackedScene) var folder_entry_button_scene : PackedScene +export(String) var base_folder : String = "res://data/" +export(NodePath) var main_container : NodePath +export(NodePath) var folder_entry_container_path : NodePath + + +var _main_container : Node +var _resource_scene : Node +var _folder_entry_container : Node + + +var _folders : Array = [ + { + "folder": base_folder + "spells/", + "type": "Spell", + "name": "Spells" + }, + { + "folder": base_folder + "auras/", + "type": "Aura", + "name": "Auras" + }, + { + "folder": base_folder + "aura_groups/", + "type": "AuraGroup", + "name": "Aura Groups" + }, + { + "folder": base_folder + "item_templates/", + "type": "ItemTemplate", + "name": "Items" + }, + { + "folder": base_folder + "crafting/", + "type": "CraftRecipe", + "name": "Craft Recipes" + }, + { + "folder": base_folder + "item_visuals/", + "type": "ItemVisual", + "name": "ItemVisuals" + }, + { + "folder": base_folder + "character_models/", + "type": "MeshDataResource", + "name": "Character Models" + }, + { + "folder": base_folder + "character_specs/", + "type": "CharacterSpec", + "name": "Character Specs" + }, + { + "folder": base_folder + "character_textures/", + "type": "Texture", + "name": "Character Textures" + }, + { + "folder": base_folder + "effect_data/", + "type": "SpellEffectVisual", + "name": "Effect Datas" + }, + { + "folder": base_folder + "entities/", + "type": "EntityData", + "name": "Entities" + }, + { + "folder": base_folder + "player_character_data/", + "type": "EntityData", + "name": "Player Characters" + }, + { + "folder": base_folder + "entity_classes/", + "type": "EntityClassData", + "name": "Entity Classes" + }, + { + "folder": base_folder + "ai/", + "type": "AIAction", + "name": "AI" + }, + { + "folder": base_folder + "planets/", + "type": "PropDataEntry", + "name": "Planets" + }, + { + "folder": base_folder + "biomes/", + "type": "BiomeData", + "name": "Biomes" + }, + { + "folder": base_folder + "dungeons/", + "type": "DungeonData", + "name": "Dungeons" + }, + { + "folder": base_folder + "dungeon_rooms/", + "type": "DungeonRoomData", + "name": "Dungeon Rooms" + }, + { + "folder": base_folder + "basic_models/", + "type": "MeshDataResource", + "name": "Basic Models" + }, + { + "folder": base_folder + "model_blocks/", + "type": "PropData", + "name": "Model Blocks" + }, + { + "folder": base_folder + "ships/", + "type": "PropData", + "name": "Ships" + }, + { + "folder": base_folder + "ship_parts/", + "type": "PropData", + "name": "Ship Parts" + }, + { + "folder": base_folder + "props/", + "type": "PropData", + "name": "Props" + }, + { + "folder": base_folder + "prop_models/", + "type": "PackedScene", + "name": "Prop Models" + }, + { + "folder": base_folder + "spell_effects/enchanter/", + "type": "Spatial", + "name": "Spell Effects -> Enchanter" + }, + { + "folder": base_folder + "spell_effects/nature/", + "type": "Spatial", + "name": "Spell Effects -> Nature" + }, + { + "folder": base_folder + "spell_effects/textures/", + "type": "Texture", + "name": "Spell Effects -> Textures" + }, + { + "folder": base_folder + "icons/", + "type": "Texture", + "name": "Icons" + }, + { + "folder": base_folder + "icons/items/", + "type": "Texture", + "name": "Icons -> Items" + }, + { + "folder": base_folder + "icons/naturalist/", + "type": "Texture", + "name": "Icons -> Naturalist" + }, + { + "folder": base_folder + "environments/", + "type": "Environment", + "name": "Environments" + }, + { + "folder": base_folder + "materials/", + "type": "Material", + "name": "Materials" + }, + { + "folder": base_folder + "models/", + "type": "CharacterSkeleton", + "name": "CharacterModels" + }, + { + "folder": base_folder + "fonts/", + "type": "Font", + "name": "Fonts" + }, + { + "folder": base_folder + "shaders/", + "type": "Shader", + "name": "Shaders" + }, + { + "folder": base_folder + "voxel_libraries/", + "type": "VoxelmanLibrary", + "name": "Voxel Libraries" + }, + { + "folder": base_folder + "voxel_surfaces/", + "type": "VoxelSurface", + "name": "Voxel Surfaces" + }, + { + "folder": base_folder + "voxel_textures/", + "type": "Texture", + "name": "Voxel Textures" + }, + { + "folder": base_folder + "xp/", + "type": "XPData", + "name": "XP Data" + }, + { + "folder": base_folder + "cursors/", + "type": "Texture", + "name": "Cursors" + }, +] + +func _ready(): + _main_container = get_node(main_container) + + _resource_scene = resource_scene.instance() + _main_container.add_child(_resource_scene) + _resource_scene.owner = _main_container + _resource_scene.connect("inspect_data", self, "inspect_data") + + _folder_entry_container = get_node(folder_entry_container_path) + + for ch in _folder_entry_container.get_children(): + ch.queue_free() + + var index = 0 + for f in _folders: + var fe : Node = folder_entry_button_scene.instance() + + _folder_entry_container.add_child(fe) + fe.owner = _folder_entry_container + + fe.text = f["name"] + fe.tab = index + + fe.set_main_panel(self) + + index += 1 + + set_tab(0) +# set_tab("test") + +func set_tab(tab_index : int) -> void: + hide_all() + + _resource_scene.show() + _resource_scene.set_resource_type(_folders[tab_index]["folder"], _folders[tab_index]["type"]) + +func hide_all() -> void: + _resource_scene.hide() + +func inspect_data(var data : Resource) -> void: + emit_signal("inspect_data", data) diff --git a/addons/ess_data/panels/MainPanel.tscn b/addons/ess_data/panels/MainPanel.tscn new file mode 100644 index 0000000..fc35a0b --- /dev/null +++ b/addons/ess_data/panels/MainPanel.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://addons/ess_data/panels/MainPanel.gd" type="Script" id=1] +[ext_resource path="res://addons/ess_data/panels/ResourcePanel.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/ess_data/panels/FolderEntryButton.tscn" type="PackedScene" id=3] + +[node name="Panel" type="MarginContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +resource_scene = ExtResource( 2 ) +folder_entry_button_scene = ExtResource( 3 ) +main_container = NodePath("HSplitContainer/MarginContainer") +folder_entry_container_path = NodePath("HSplitContainer/ScrollContainer/VBoxContainer") + +[node name="HSplitContainer" type="HSplitContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 600.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +split_offset = 210 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer"] +margin_right = 210.0 +margin_bottom = 600.0 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/ScrollContainer"] +margin_right = 210.0 +size_flags_horizontal = 3 + +[node name="MarginContainer" type="MarginContainer" parent="HSplitContainer"] +margin_left = 222.0 +margin_right = 1024.0 +margin_bottom = 600.0 diff --git a/addons/ess_data/panels/ResourcePanel.gd b/addons/ess_data/panels/ResourcePanel.gd new file mode 100644 index 0000000..9dd1e24 --- /dev/null +++ b/addons/ess_data/panels/ResourcePanel.gd @@ -0,0 +1,291 @@ +tool +extends Control + +signal inspect_data + +export(PackedScene) var resource_row_scene : PackedScene +export(PackedScene) var history_row_scene : PackedScene + +export(NodePath) var entry_container_path : NodePath + +export(NodePath) var name_popup_path : NodePath +export(NodePath) var create_popup_path : NodePath +export(NodePath) var delete_popup_path : NodePath + +export(NodePath) var history_container_path : NodePath + +var _filter_term : String + +var _entry_container : Node +var _name_popup : Node +var _create_popup : ConfirmationDialog +var _delete_popup : ConfirmationDialog + +var _history_container : Node + +var _folder : String +var _resource_type : String + +var _queue_deleted : Resource + +var _state : Dictionary +var _states : Dictionary + +func _ready(): + _history_container = get_node(history_container_path) + + _entry_container = get_node(entry_container_path) + _name_popup = get_node(name_popup_path) + _name_popup.connect("ok_pressed", self, "ok_pressed") + + _create_popup = get_node(create_popup_path) + _delete_popup = get_node(delete_popup_path) + +func set_resource_type(folder : String, resource_type : String) -> void: + if folder == _folder and _resource_type == resource_type: + return + + _states[_folder + "," + _resource_type] = _state + + if _states.has(folder + "," + resource_type): + _state = _states[folder + "," + resource_type] + else: + _state = Dictionary() + + _folder = folder + _resource_type = resource_type + +# _filter_term = "" + + _create_popup.set_resource_type(resource_type) + + refresh() + +func refresh() -> void: + for ch in _entry_container.get_children(): + ch.queue_free() + + var d : Directory = Directory.new() + + if d.open(_folder) == OK: + d.list_dir_begin() + var data_array : Array = Array() + + var file_name = d.get_next() + + while (file_name != ""): + if not d.current_is_dir(): + + if ResourceLoader.exists(_folder + file_name, _resource_type): + + var res = ResourceLoader.load(_folder + file_name, _resource_type) + + if _filter_term != "": + var ftext : String = "" + + if res.has_method("get_text_name"): + ftext = res.get_text_name() + + if ftext == "": + if res.resource_name != "": + ftext = res.resource_name + else: + ftext = res.resource_path + + ftext = ftext.to_lower() + + if ftext.find(_filter_term) == -1: + file_name = d.get_next() + continue + + var id : int = 0 + + if res.has_method("get_id"): + id = res.get_id() + + data_array.append({ + "id": id, + "resource": res + }) + + file_name = d.get_next() + + data_array.sort_custom(self, "sort_entries") + + for d in data_array: + + var resn : Node = resource_row_scene.instance() + + _entry_container.add_child(resn) + resn.owner = _entry_container + resn.set_resource(d["resource"]) + resn.connect("inspect_data", self, "inspect_data") + resn.connect("duplicate", self, "duplicate_data") + resn.connect("delete", self, "delete") + +func inspect_data(var data : Resource) -> void: + var found : bool = false + + for ch in _history_container.get_children(): + if ch.data == data: + found = true + + _history_container.move_child(ch, 0) + + break + + if not found: + var n : Node = history_row_scene.instance() + + _history_container.add_child(n) + _history_container.move_child(n, 0) + n.owner = _history_container + + n.data = data + n.connect("history_entry_selected", self, "inspect_data") + + if _history_container.get_child_count() > 20: + var ch : Node = _history_container.get_child(_history_container.get_child_count() - 1) + + ch.queue_free() + + emit_signal("inspect_data", data) + +func ok_pressed(res_name: String, pclass_name: String) -> void: + + var d : Directory = Directory.new() + + if d.open(_folder) == OK: + d.list_dir_begin() + + var file_name = d.get_next() + + var max_ind : int = 0 + + while (file_name != ""): + + if not d.current_is_dir(): + + var curr_ind : int = int(file_name.split("_")[0]) + + if curr_ind > max_ind: + max_ind = curr_ind + + file_name = d.get_next() + + max_ind += 1 + + var newfname : String = str(res_name) + newfname = newfname.replace(" ", "_") + newfname = newfname.to_lower() + newfname = str(max_ind) + "_" + newfname + ".tres" + + var res : Resource = null + + if ClassDB.class_exists(pclass_name) and ClassDB.can_instance(pclass_name): + res = ClassDB.instance(pclass_name) + else: + var gsc : Array = ProjectSettings.get("_global_script_classes") + + for i in range(gsc.size()): + var gsce : Dictionary = gsc[i] as Dictionary + + if gsce["class"] == pclass_name: + var script : Script = load(gsce["path"]) + + res = script.new() + + break + + if res == null: + print("ESSData: Error in creating resource type " + pclass_name) + return + + if res.has_method("set_id"): + res.set_id(max_ind) + + if res.has_method("set_text_name"): + res.set_text_name(str(res_name)) + + ResourceSaver.save(_folder + newfname, res) + + refresh() + +func duplicate_data(data): + if not data is Resource: + return + + var d : Directory = Directory.new() + + if d.open(_folder) == OK: + d.list_dir_begin() + + var file_name = d.get_next() + + var max_ind : int = 0 + + while (file_name != ""): + + if not d.current_is_dir(): + + var curr_ind : int = int(file_name.split("_")[0]) + + if curr_ind > max_ind: + max_ind = curr_ind + + file_name = d.get_next() + + max_ind += 1 + + var res_name : String = "" + + if data.has_method("get_text_name"): + res_name = data.get_text_name() + + var newfname : String = res_name + newfname = newfname.replace(" ", "_") + newfname = newfname.to_lower() + newfname = str(max_ind) + "_" + newfname + ".tres" + + var res : Resource = data.duplicate() + + if res.has_method("set_id"): + res.set_id(max_ind) + + if res.has_method("set_text_name"): + res.set_text_name(str(res_name)) + + ResourceSaver.save(_folder + newfname, res) + + refresh() + +func delete(data): + if data == null or data as Resource == null: + return + + _queue_deleted = data as Resource + + _delete_popup.popup_centered() + +func delete_confirm(): + if _queue_deleted == null: + return + + var d : Directory = Directory.new() + d.remove(_queue_deleted.resource_path) + + _queue_deleted = null + + refresh() + +func clear_history() -> void: + for ch in _history_container.get_children(): + ch.queue_free() + +func search(text : String) -> void: + _filter_term = text.to_lower() + + refresh() + +func sort_entries(a, b): + return a["id"] < b["id"] diff --git a/addons/ess_data/panels/ResourcePanel.tscn b/addons/ess_data/panels/ResourcePanel.tscn new file mode 100644 index 0000000..b119919 --- /dev/null +++ b/addons/ess_data/panels/ResourcePanel.tscn @@ -0,0 +1,117 @@ +[gd_scene load_steps=8 format=2] + +[ext_resource path="res://addons/ess_data/icons/icon_add.png" type="Texture" id=1] +[ext_resource path="res://addons/ess_data/panels/ResourceRow.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/ess_data/icons/icon_empty.png" type="Texture" id=3] +[ext_resource path="res://addons/ess_data/panels/ResourcePanel.gd" type="Script" id=4] +[ext_resource path="res://addons/ess_data/panels/HistoryEntry.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/ess_data/panels/CreateNamePopup.tscn" type="PackedScene" id=6] +[ext_resource path="res://addons/ess_data/icons/icon_reload_small.png" type="Texture" id=7] + +[node name="Panel" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 4 ) +__meta__ = { +"_edit_use_anchors_": false +} +resource_row_scene = ExtResource( 2 ) +history_row_scene = ExtResource( 5 ) +entry_container_path = NodePath("ResourcePanel/VBoxContainer2/ScrollContainer2/VBoxContainer") +name_popup_path = NodePath("CreateNamePopup") +create_popup_path = NodePath("CreateNamePopup") +delete_popup_path = NodePath("DeletePopup") +history_container_path = NodePath("ResourcePanel/VBoxContainer/ScrollContainer/VBoxContainer") + +[node name="ResourcePanel" type="HSplitContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +split_offset = 500 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer2" type="VBoxContainer" parent="ResourcePanel"] +margin_right = 664.0 +margin_bottom = 600.0 + +[node name="LineEdit" type="LineEdit" parent="ResourcePanel/VBoxContainer2"] +margin_right = 664.0 +margin_bottom = 45.0 +right_icon = ExtResource( 3 ) +placeholder_text = "Filter" +caret_blink = true + +[node name="CreateButton" type="Button" parent="ResourcePanel/VBoxContainer2"] +margin_top = 53.0 +margin_right = 664.0 +margin_bottom = 90.0 +rect_min_size = Vector2( 100, 0 ) +text = "Create" +icon = ExtResource( 1 ) +expand_icon = true + +[node name="HSeparator" type="HSeparator" parent="ResourcePanel/VBoxContainer2"] +margin_top = 98.0 +margin_right = 664.0 +margin_bottom = 106.0 +size_flags_horizontal = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ScrollContainer2" type="ScrollContainer" parent="ResourcePanel/VBoxContainer2"] +margin_top = 114.0 +margin_right = 664.0 +margin_bottom = 600.0 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel/VBoxContainer2/ScrollContainer2"] +margin_right = 664.0 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel"] +margin_left = 688.0 +margin_right = 1024.0 +margin_bottom = 600.0 + +[node name="Button" type="Button" parent="ResourcePanel/VBoxContainer"] +margin_right = 336.0 +margin_bottom = 37.0 +size_flags_horizontal = 3 +text = "Clear History" +icon = ExtResource( 7 ) + +[node name="HSeparator" type="HSeparator" parent="ResourcePanel/VBoxContainer"] +margin_top = 45.0 +margin_right = 336.0 +margin_bottom = 53.0 +size_flags_horizontal = 3 + +[node name="ScrollContainer" type="ScrollContainer" parent="ResourcePanel/VBoxContainer"] +margin_top = 61.0 +margin_right = 336.0 +margin_bottom = 600.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel/VBoxContainer/ScrollContainer"] +margin_right = 336.0 +size_flags_horizontal = 3 + +[node name="CreateNamePopup" parent="." instance=ExtResource( 6 )] + +[node name="DeletePopup" type="ConfirmationDialog" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -139.0 +margin_top = -55.0 +margin_right = 139.0 +margin_bottom = 55.0 +dialog_text = "Delete?" +[connection signal="text_entered" from="ResourcePanel/VBoxContainer2/LineEdit" to="." method="search"] +[connection signal="pressed" from="ResourcePanel/VBoxContainer2/CreateButton" to="CreateNamePopup" method="popup"] +[connection signal="pressed" from="ResourcePanel/VBoxContainer/Button" to="." method="clear_history"] +[connection signal="confirmed" from="DeletePopup" to="." method="delete_confirm"] diff --git a/addons/ess_data/panels/ResourceRow.tscn b/addons/ess_data/panels/ResourceRow.tscn new file mode 100644 index 0000000..64e43b8 --- /dev/null +++ b/addons/ess_data/panels/ResourceRow.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=9 format=2] + +[ext_resource path="res://addons/ess_data/panels/EntryButton.gd" type="Script" id=1] +[ext_resource path="res://addons/ess_data/icons/icon_duplicate.png" type="Texture" id=2] +[ext_resource path="res://addons/ess_data/icons/icon_remove.png" type="Texture" id=3] +[ext_resource path="res://addons/ess_data/panels/ResourceRowMainButton.gd" type="Script" id=4] +[ext_resource path="res://addons/ess_data/previews/SpatialPreview.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/ess_data/previews/Node2DPreview.tscn" type="PackedScene" id=6] +[ext_resource path="res://addons/ess_data/previews/ControlPreview.tscn" type="PackedScene" id=7] +[ext_resource path="res://addons/ess_data/previews/TexturePreview.tscn" type="PackedScene" id=8] + +[node name="ResourceRow" type="HBoxContainer"] +margin_right = 634.0 +margin_bottom = 37.0 +rect_min_size = Vector2( 100, 0 ) +size_flags_horizontal = 3 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +spatial_preview = ExtResource( 5 ) +node2d_preview = ExtResource( 6 ) +control_preview = ExtResource( 7 ) +texture_preview = ExtResource( 8 ) +main_button_path = NodePath("ResourceRowMainButton") + +[node name="ResourceRowMainButton" type="Button" parent="."] +margin_right = 570.0 +margin_bottom = 37.0 +size_flags_horizontal = 3 +script = ExtResource( 4 ) + +[node name="Button2" type="Button" parent="."] +margin_left = 574.0 +margin_right = 602.0 +margin_bottom = 37.0 +icon = ExtResource( 2 ) + +[node name="Button3" type="Button" parent="."] +margin_left = 606.0 +margin_right = 634.0 +margin_bottom = 37.0 +icon = ExtResource( 3 ) +[connection signal="pressed" from="ResourceRowMainButton" to="." method="inspect"] +[connection signal="pressed" from="Button2" to="." method="duplicate_data"] +[connection signal="pressed" from="Button3" to="." method="delete"] diff --git a/addons/ess_data/panels/ResourceRowMainButton.gd b/addons/ess_data/panels/ResourceRowMainButton.gd new file mode 100644 index 0000000..37177fc --- /dev/null +++ b/addons/ess_data/panels/ResourceRowMainButton.gd @@ -0,0 +1,18 @@ +tool +extends Button + +var _data : Resource + +func get_drag_data(position): + if _data == null: + return null + + var d : Dictionary = Dictionary() + d["type"] = "resource" + d["resource"] = _data + d["from"] = self + + return d + +func set_resource(data : Resource) -> void: + _data = data diff --git a/addons/ess_data/plugin.cfg b/addons/ess_data/plugin.cfg new file mode 100644 index 0000000..1f7b6ab --- /dev/null +++ b/addons/ess_data/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Entity Spell System Data Manager" +description="" +author="Relintai" +version="1.0" +script="plugin.gd" diff --git a/addons/ess_data/plugin.gd b/addons/ess_data/plugin.gd new file mode 100644 index 0000000..6742e48 --- /dev/null +++ b/addons/ess_data/plugin.gd @@ -0,0 +1,36 @@ +tool +extends EditorPlugin + +const _main_panel : PackedScene = preload("res://addons/ess_data/panels/MainPanel.tscn") +const _script_icon : Texture = preload("res://addons/ess_data/icons/icon_multi_line.png") + +var _main_panel_instance : Control + +func _enter_tree(): + _main_panel_instance = _main_panel.instance() as Control + _main_panel_instance.connect("inspect_data", self, "inspect_data") + + get_editor_interface().get_editor_viewport().add_child(_main_panel_instance) + + make_visible(false) + +func _exit_tree(): + _main_panel_instance.queue_free() + +func has_main_screen(): + return true + +func make_visible(visible): + if visible: + _main_panel_instance.show() + else: + _main_panel_instance.hide() + +func get_plugin_icon(): + return _script_icon + +func get_plugin_name(): + return "Data" + +func inspect_data(var data : Resource) -> void: + get_editor_interface().inspect_object(data) diff --git a/addons/ess_data/previews/ControlPreview.gd b/addons/ess_data/previews/ControlPreview.gd new file mode 100644 index 0000000..0758c3e --- /dev/null +++ b/addons/ess_data/previews/ControlPreview.gd @@ -0,0 +1,14 @@ +tool +extends ViewportContainer + +export(NodePath) var container_path : NodePath + +var _container : Node + +func _ready() -> void: + _container = get_node(container_path) + +func preview(n: Control) -> void: + _container.add_child(n) + n.owner = _container + diff --git a/addons/ess_data/previews/ControlPreview.tscn b/addons/ess_data/previews/ControlPreview.tscn new file mode 100644 index 0000000..f3536da --- /dev/null +++ b/addons/ess_data/previews/ControlPreview.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/previews/ControlPreview.gd" type="Script" id=1] + +[node name="ControlPreview" type="ViewportContainer"] +margin_right = 60.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 60, 60 ) +rect_pivot_offset = Vector2( -198.876, -96.6558 ) +stretch = true +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +container_path = NodePath("Viewport") + +[node name="Viewport" type="Viewport" parent="."] +size = Vector2( 500, 500 ) +own_world = true +handle_input_locally = false +render_target_update_mode = 3 diff --git a/addons/ess_data/previews/Node2DPreview.gd b/addons/ess_data/previews/Node2DPreview.gd new file mode 100644 index 0000000..586b8d9 --- /dev/null +++ b/addons/ess_data/previews/Node2DPreview.gd @@ -0,0 +1,14 @@ +tool +extends ViewportContainer + +export(NodePath) var container_path : NodePath + +var _container : Node + +func _ready() -> void: + _container = get_node(container_path) + +func preview(n: Node2D) -> void: + _container.add_child(n) + n.owner = _container + diff --git a/addons/ess_data/previews/Node2DPreview.tscn b/addons/ess_data/previews/Node2DPreview.tscn new file mode 100644 index 0000000..0c5bafd --- /dev/null +++ b/addons/ess_data/previews/Node2DPreview.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/previews/Node2DPreview.gd" type="Script" id=1] + +[node name="Node2DPreview" type="ViewportContainer"] +margin_right = 60.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 60, 60 ) +rect_pivot_offset = Vector2( -198.876, -96.6558 ) +stretch = true +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +container_path = NodePath("Viewport") + +[node name="Viewport" type="Viewport" parent="."] +size = Vector2( 500, 500 ) +own_world = true +handle_input_locally = false +render_target_update_mode = 3 + +[node name="Camera2D" type="Camera2D" parent="Viewport"] +current = true diff --git a/addons/ess_data/previews/SpatialPreview.gd b/addons/ess_data/previews/SpatialPreview.gd new file mode 100644 index 0000000..565cb9d --- /dev/null +++ b/addons/ess_data/previews/SpatialPreview.gd @@ -0,0 +1,14 @@ +tool +extends ViewportContainer + +export(NodePath) var container_path : NodePath + +var _container : Node + +func _ready() -> void: + _container = get_node(container_path) + +func preview(n: Spatial) -> void: + _container.add_child(n) + n.owner = _container + diff --git a/addons/ess_data/previews/SpatialPreview.tscn b/addons/ess_data/previews/SpatialPreview.tscn new file mode 100644 index 0000000..12d81a5 --- /dev/null +++ b/addons/ess_data/previews/SpatialPreview.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/previews/SpatialPreview.gd" type="Script" id=1] + +[node name="SpatialPreview" type="ViewportContainer"] +margin_right = 60.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 60, 60 ) +rect_pivot_offset = Vector2( -198.876, -96.6558 ) +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +container_path = NodePath("Viewport") + +[node name="Viewport" type="Viewport" parent="."] +size = Vector2( 60, 60 ) +size_override_stretch = true +own_world = true +handle_input_locally = false +render_target_update_mode = 3 + +[node name="Camera" type="Camera" parent="Viewport"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10.9828 ) +current = true + +[node name="DirectionalLight" type="DirectionalLight" parent="Viewport"] +transform = Transform( 0.276929, 0, -0.96089, 0, 1, 0, 0.96089, 0, 0.276929, -13.093, 0, 6.67786 ) diff --git a/addons/ess_data/previews/TexturePreview.gd b/addons/ess_data/previews/TexturePreview.gd new file mode 100644 index 0000000..5b50e16 --- /dev/null +++ b/addons/ess_data/previews/TexturePreview.gd @@ -0,0 +1,12 @@ +tool +extends TextureRect + +func set_texture(tex: Texture)-> void: + texture = tex + + if tex is PackerImageResource: + var t : ImageTexture = ImageTexture.new() + + t.create_from_image(tex.data, 0) + + texture = t diff --git a/addons/ess_data/previews/TexturePreview.tscn b/addons/ess_data/previews/TexturePreview.tscn new file mode 100644 index 0000000..e53b8c5 --- /dev/null +++ b/addons/ess_data/previews/TexturePreview.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/ess_data/previews/TexturePreview.gd" type="Script" id=1] + +[node name="TexturePreview" type="TextureRect"] +margin_bottom = 37.0 +rect_min_size = Vector2( 50, 50 ) +expand = true +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/addons/prop_tool/player/PropToolDisplayPlayer.gd b/addons/prop_tool/player/PropToolDisplayPlayer.gd new file mode 100644 index 0000000..6eeb644 --- /dev/null +++ b/addons/prop_tool/player/PropToolDisplayPlayer.gd @@ -0,0 +1,3 @@ +tool +extends Entity + diff --git a/addons/prop_tool/player/PropToolDisplayPlayer.tscn b/addons/prop_tool/player/PropToolDisplayPlayer.tscn new file mode 100644 index 0000000..5e4270c --- /dev/null +++ b/addons/prop_tool/player/PropToolDisplayPlayer.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://data/models/armature_model_orig_v2.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/prop_tool/player/PropToolDisplayPlayer.gd" type="Script" id=2] + +[node name="DisplayPlayer" type="Entity" groups=[ +"players", +]] +input_ray_pickable = false +collision_layer = 3 +collision_mask = 3 +character_skeleton_path = NodePath("character") +script = ExtResource( 2 ) + +[node name="character" parent="." instance=ExtResource( 1 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00126277, 0.085327, -0.000325084 ) +use_threads = false diff --git a/addons/prop_tool/plugin.cfg b/addons/prop_tool/plugin.cfg new file mode 100644 index 0000000..e69f789 --- /dev/null +++ b/addons/prop_tool/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Prop Tool" +description="" +author="Relintai" +version="" +script="plugin.gd" diff --git a/addons/prop_tool/plugin.gd b/addons/prop_tool/plugin.gd new file mode 100644 index 0000000..7030f07 --- /dev/null +++ b/addons/prop_tool/plugin.gd @@ -0,0 +1,280 @@ +tool +extends EditorPlugin + +const main_scene_path : String = "res://addons/prop_tool/scenes/main.tscn" +const temp_scene_path : String = "res://addons/prop_tool/scenes/main_temp.tscn" +const temp_path : String = "res://addons/prop_tool/scenes/temp/" + +var buttons_added : bool = false +var light_button : ToolButton +var mesh_button : ToolButton +var prop_button : ToolButton +var scene_button : ToolButton +var entity_button : ToolButton + +var edited_prop : PropData + +func _enter_tree(): + var dir : Directory = Directory.new() + dir.copy(main_scene_path, temp_scene_path) + + light_button = ToolButton.new() + light_button.text = "Light" + light_button.connect("pressed", self, "add_light") + + mesh_button = ToolButton.new() + mesh_button.text = "Mesh" + mesh_button.connect("pressed", self, "add_mesh") + + prop_button = ToolButton.new() + prop_button.text = "Prop" + prop_button.connect("pressed", self, "add_prop") + + scene_button = ToolButton.new() + scene_button.text = "Scene" + scene_button.connect("pressed", self, "add_scene") + + entity_button = ToolButton.new() + entity_button.text = "Entity" + entity_button.connect("pressed", self, "add_entity") + + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, light_button) + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, mesh_button) + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, prop_button) + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, scene_button) + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, entity_button) + + light_button.hide() + mesh_button.hide() + prop_button.hide() + scene_button.hide() + entity_button.hide() + + connect("scene_changed", self, "scene_changed") + + +func _exit_tree(): + var dir : Directory = Directory.new() + dir.remove(temp_scene_path) + + if is_instance_valid(light_button): + light_button.queue_free() + + if is_instance_valid(mesh_button): + mesh_button.queue_free() + + if is_instance_valid(prop_button): + prop_button.queue_free() + + if is_instance_valid(scene_button): + scene_button.queue_free() + + if is_instance_valid(entity_button): + entity_button.queue_free() + + light_button = null + mesh_button = null + prop_button = null + scene_button = null + entity_button = null + + edited_prop = null + + disconnect("scene_changed", self, "scene_changed") + +func scene_changed(scene): + if scene.has_method("set_target_prop"): + scene.plugin = self + + if not buttons_added: + light_button.show() + mesh_button.show() + prop_button.show() + scene_button.show() + entity_button.show() +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, light_button) +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, mesh_button) +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, prop_button) +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, scene_button) +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, entity_button) + + buttons_added = true + else: + if buttons_added: + light_button.hide() + mesh_button.hide() + prop_button.hide() + scene_button.hide() + entity_button.hide() +# +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, light_button) +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, mesh_button) +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, prop_button) +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, scene_button) +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, entity_button) + + buttons_added = false + +func apply_changes() -> void: + var scene : Node = get_editor_interface().get_edited_scene_root() + + if scene is PropTool: +# if scene.has_method("set_target_prop") and scene.has_method("save"): + scene.save() + +func edit(object : Object) -> void: + var pedited_prop = object as PropData + + var p : String = create_or_get_scene_path(pedited_prop) + + get_editor_interface().open_scene_from_path(p) + +func handles(object : Object) -> bool: + return object is PropData + +func add_light(): + var selection : Array = get_editor_interface().get_selection().get_selected_nodes() + var selected : Node + + if selection.size() != 1: + selected = get_editor_interface().get_edited_scene_root() + else: + selected = selection[0] + + var s : Node = selected + var n = PropToolLight.new() + + var u : UndoRedo = get_undo_redo() + u.create_action("Add Light") + u.add_do_method(s, "add_child", n) + u.add_do_property(n, "owner", get_editor_interface().get_edited_scene_root()) + u.add_undo_method(s, "remove_child", n) + u.commit_action() + + get_editor_interface().get_selection().clear() + get_editor_interface().get_selection().add_node(n) + + +func add_mesh(): + var selected : Array = get_editor_interface().get_selection().get_selected_nodes() + + if selected.size() != 1: + return + + var s : Node = selected[0] + var n = PropToolMesh.new() + + var u : UndoRedo = get_undo_redo() + u.create_action("Add Mesh") + u.add_do_method(s, "add_child", n) + u.add_do_property(n, "owner", get_editor_interface().get_edited_scene_root()) + u.add_undo_method(s, "remove_child", n) + u.commit_action() + + get_editor_interface().get_selection().clear() + get_editor_interface().get_selection().add_node(n) + + +func add_prop(): + var selected : Array = get_editor_interface().get_selection().get_selected_nodes() + + if selected.size() != 1: + return + + var s : Node = selected[0] + var n = PropTool.new() + + var u : UndoRedo = get_undo_redo() + u.create_action("Add Prop") + u.add_do_method(s, "add_child", n) + u.add_do_property(n, "owner", get_editor_interface().get_edited_scene_root()) + u.add_undo_method(s, "remove_child", n) + u.commit_action() + + get_editor_interface().get_selection().clear() + get_editor_interface().get_selection().add_node(n) + +func add_scene(): + var selected : Array = get_editor_interface().get_selection().get_selected_nodes() + + if selected.size() != 1: + return + + var s : Node = selected[0] + var n = PropToolScene.new() + + var u : UndoRedo = get_undo_redo() + u.create_action("Add Scene") + u.add_do_method(s, "add_child", n) + u.add_do_property(n, "owner", get_editor_interface().get_edited_scene_root()) + u.add_undo_method(s, "remove_child", n) + u.commit_action() + + get_editor_interface().get_selection().clear() + get_editor_interface().get_selection().add_node(n) + +func add_entity(): + var selected : Array = get_editor_interface().get_selection().get_selected_nodes() + + if selected.size() != 1: + return + + var s : Node = selected[0] + var n = PropToolEntity.new() + + var u : UndoRedo = get_undo_redo() + u.create_action("Add Entity") + u.add_do_method(s, "add_child", n) + u.add_do_property(n, "owner", get_editor_interface().get_edited_scene_root()) + u.add_undo_method(s, "remove_child", n) + u.commit_action() + + get_editor_interface().get_selection().clear() + get_editor_interface().get_selection().add_node(n) + +func create_or_get_scene_path(data: PropData) -> String: + var path : String = temp_path + data.resource_path.get_file().get_basename() + ".tscn" + + var dir : Directory = Directory.new() + + if not dir.file_exists(path): + create_scene(data) + + return path + +func create_or_get_scene(data: PropData) -> PropTool: + if data == null: + print("PropTool plugin.gd: Data is null!") + return null + + var path : String = temp_path + data.resource_path.get_file().get_basename() + ".tscn" + + var dir : Directory = Directory.new() + + var ps : PackedScene + + if not dir.file_exists(path): + ps = create_scene(data) + else: + ps = ResourceLoader.load(path, "PackedScene") + + if ps == null: + return null + + var pt : PropTool = ps.instance() as PropTool + pt.plugin = self + return pt + +func create_scene(data: PropData) -> PackedScene: + var pt : PropTool = PropTool.new() + + pt.plugin = self + pt.set_target_prop(data) + + var ps : PackedScene = PackedScene.new() + ps.pack(pt) + + var err = ResourceSaver.save(temp_path + data.resource_path.get_file().get_basename() + ".tscn", ps) + + pt.queue_free() + return ps diff --git a/addons/prop_tool/scenes/.gitignore b/addons/prop_tool/scenes/.gitignore new file mode 100644 index 0000000..2283bd2 --- /dev/null +++ b/addons/prop_tool/scenes/.gitignore @@ -0,0 +1 @@ +main_temp.tscn \ No newline at end of file diff --git a/addons/prop_tool/scenes/main.tscn b/addons/prop_tool/scenes/main.tscn new file mode 100644 index 0000000..5cb6f9e --- /dev/null +++ b/addons/prop_tool/scenes/main.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/prop_tool/tools/PropTool.gd" type="Script" id=1] + +[node name="PropTool" type="Spatial"] +script = ExtResource( 1 ) diff --git a/addons/prop_tool/scenes/temp/.gitignore b/addons/prop_tool/scenes/temp/.gitignore new file mode 100644 index 0000000..54010b9 --- /dev/null +++ b/addons/prop_tool/scenes/temp/.gitignore @@ -0,0 +1 @@ +*.tscn diff --git a/addons/prop_tool/tools/PropTool.gd b/addons/prop_tool/tools/PropTool.gd new file mode 100644 index 0000000..508ba98 --- /dev/null +++ b/addons/prop_tool/tools/PropTool.gd @@ -0,0 +1,152 @@ +tool +extends Spatial +class_name PropTool + +export(bool) var refresh : bool setget refresh_set +export(PropData) var target_prop : PropData setget target_prop_set +export(bool) var snap_to_mesh : bool = false +export(Vector3) var snap_axis : Vector3 = Vector3(0, -1, 0) +var plugin : EditorPlugin + +func save() -> void: + if target_prop == null: + return + + print("save " + target_prop.resource_path) + + while target_prop.get_prop_count() > 0: + target_prop.remove_prop(0) + + for child in get_children(): + save_node(child, transform) + + target_prop.snap_to_mesh = snap_to_mesh + target_prop.snap_axis = snap_axis + + ResourceSaver.save(target_prop.resource_path, target_prop) + +func save_node(node : Node, parent_transform: Transform) -> void: + if node is Spatial and node.has_method("get_data"): + var prop : PropDataEntry = node.get_data() + + if prop: + prop.transform = parent_transform * (node as Spatial).transform + + target_prop.add_prop(prop) + + if node.has_method("evaluate_children") and not node.evaluate_children(): + return + + for child in node.get_children(): + save_node(child, parent_transform * node.transform) + else: + if node.has_method("set_target_prop"): + if node.target_prop: + var prop : PropDataProp = PropDataProp.new() + + prop.prop = node.target_prop + + prop.transform = parent_transform * (node as Spatial).transform + + target_prop.add_prop(prop) + else: + for child in node.get_children(): + save_node(child, parent_transform) + +func rebuild_hierarchy() -> void: + for ch in get_children(): + ch.queue_free() + + if target_prop == null: + return + + snap_to_mesh = target_prop.snap_to_mesh + snap_axis = target_prop.snap_axis + + for i in range(target_prop.get_prop_count()): + print(i) + var prop : PropDataEntry = target_prop.get_prop(i) + + if prop is PropDataLight: + var l : PropToolLight = PropToolLight.new() + + add_child(l) + l.owner = self + l.transform = prop.transform + + l.set_data(prop as PropDataLight) + elif prop is PropDataMesh: + var m : PropToolMesh = PropToolMesh.new() + + add_child(m) + m.owner = self + m.transform = prop.transform + + m.set_data(prop as PropDataMesh) + elif prop is PropDataScene: + var s : PropToolScene = PropToolScene.new() + + add_child(s) + s.owner = self + s.transform = prop.transform + + s.set_data(prop as PropDataScene) + elif prop is PropDataProp: + var s : Node = plugin.create_or_get_scene(prop.prop) + + add_child(s) + s.owner = self + s.transform = prop.transform +# s.set_target_prop(prop.prop) + elif prop is PropDataEntity: + var s : PropToolEntity = PropToolEntity.new() + + add_child(s) + s.owner = self + s.transform = prop.transform + + s.set_data(prop as PropDataEntity) + +func refresh_set(value): + if value: + rebuild_hierarchy() + +func set_target_prop(prop: PropData) -> void: +# if prop == null: +# return + + target_prop = prop + + rebuild_hierarchy() + +func get_plugin(): + return plugin + +func target_prop_set(prop: PropData) -> void: + target_prop = prop + + if prop == null: + return + + var last_prop_tool : PropTool = self + var root : Node = self + while root.get_parent() != null: + root = root.get_parent() + + if root and root.has_method("target_prop_set"): + last_prop_tool = root as PropTool + + if last_prop_tool == self: + return + + last_prop_tool.load_scene_for(self, prop) + +func load_scene_for(t: PropTool, prop: PropData): + if not plugin: + return + + t.queue_free() + var s : Node = plugin.create_or_get_scene(prop) + + add_child(s) + s.owner = self diff --git a/addons/prop_tool/tools/PropToolEntity.gd b/addons/prop_tool/tools/PropToolEntity.gd new file mode 100644 index 0000000..834db06 --- /dev/null +++ b/addons/prop_tool/tools/PropToolEntity.gd @@ -0,0 +1,71 @@ +tool +extends Spatial +class_name PropToolEntity + +export(EntityData) var entity_data : EntityData setget set_entity_data +export(int) var entity_data_id : int +export(int) var level : int = 1 + +var _prop_entity : PropDataEntity +var _entity : Entity + +func get_data() -> PropDataEntity: + if not visible or entity_data == null: + return null + + if _prop_entity == null: + _prop_entity = PropDataEntity.new() + + _prop_entity.entity_data_id = entity_data.id + _prop_entity.level = level + + return _prop_entity + +func set_data(scene: PropDataEntity) -> void: + _prop_entity = scene + + entity_data_id = _prop_entity.entity_data_id + level = _prop_entity.level + + var dir = Directory.new() + if dir.open("res://data/entities/") == OK: + dir.list_dir_begin() + var file_name = dir.get_next() + + while (file_name != ""): + if not dir.current_is_dir(): + var ed : EntityData = ResourceLoader.load("res://data/entities/" + file_name, "EntityData") + + if ed != null and ed.id == entity_data_id: + set_entity_data(ed) + return + + file_name = dir.get_next() + + print("PropToolEntity: Entity not found!") + +func set_entity_data(ed: EntityData) -> void: + entity_data = ed + + if entity_data == null: + return + + if _entity == null: + var scene : PackedScene = load("res://addons/prop_tool/player/PropToolDisplayPlayer.tscn") + + _entity = scene.instance() as Entity + + add_child(_entity) +# _entity.owner = owner + +# _entity.get_node(_entity.character_skeleton_path).owner = owner + _entity.get_node(_entity.character_skeleton_path).refresh_in_editor = true + # _entity.get_character_skeleton().refresh_in_editor = true + + _entity.sentity_data = entity_data + + name = entity_data.text_name + + +func evaluate_children() -> bool: + return false diff --git a/addons/prop_tool/tools/PropToolLight.gd b/addons/prop_tool/tools/PropToolLight.gd new file mode 100644 index 0000000..55c8694 --- /dev/null +++ b/addons/prop_tool/tools/PropToolLight.gd @@ -0,0 +1,36 @@ +tool +extends OmniLight +class_name PropToolLight + +var _prop_light : PropDataLight + +#func _ready(): +# set_notify_transform(true) + +func get_data() -> PropDataLight: + if not visible: + return null + + if _prop_light == null: + _prop_light = PropDataLight.new() + + _prop_light.light_color = light_color + _prop_light.light_size = omni_range + + return _prop_light + +func set_data(light : PropDataLight) -> void: + _prop_light = light + + light_color = _prop_light.light_color + omni_range = _prop_light.light_size + light_energy = _prop_light.light_size + +#func save(): +# if get_node("..").has_method("save"): +# get_node("..").save() +# +#func _notification(what): +# if what == NOTIFICATION_TRANSFORM_CHANGED: +# save() + diff --git a/addons/prop_tool/tools/PropToolMesh.gd b/addons/prop_tool/tools/PropToolMesh.gd new file mode 100644 index 0000000..45baee8 --- /dev/null +++ b/addons/prop_tool/tools/PropToolMesh.gd @@ -0,0 +1,84 @@ +tool +extends MeshInstance +class_name PropToolMesh + +export(MeshDataResource) var mesh_data : MeshDataResource setget set_prop_mesh +export(Texture) var texture : Texture setget set_texture +export(bool) var snap_to_mesh : bool = false +export(Vector3) var snap_axis : Vector3 = Vector3(0, -1, 0) + +export(bool) var generate : bool setget set_generate + +var _prop_mesh : PropDataMesh +var _material : SpatialMaterial + +func get_data() -> PropDataMesh: + if not visible or mesh_data == null: + return null + + if _prop_mesh == null: + _prop_mesh = PropDataMesh.new() + + _prop_mesh.mesh = mesh_data + _prop_mesh.texture = texture + _prop_mesh.snap_to_mesh = snap_to_mesh + _prop_mesh.snap_axis = snap_axis + + return _prop_mesh + +func set_data(data : PropDataMesh) -> void: + _prop_mesh = data + + set_texture(_prop_mesh.texture) + set_prop_mesh(_prop_mesh.mesh) + + snap_to_mesh = _prop_mesh.snap_to_mesh + snap_axis = _prop_mesh.snap_axis + +func set_prop_mesh(md : MeshDataResource) -> void: + mesh_data = md + + set_generate(true) + +func set_texture(tex : Texture) -> void: + texture = tex + +func set_generate(val : bool) -> void: + if val: + if !mesh_data: + mesh = null + return + + var m : ArrayMesh = ArrayMesh.new() + + var arr = [] + arr.resize(ArrayMesh.ARRAY_MAX) + + var v : PoolVector3Array = PoolVector3Array() + v.append_array(mesh_data.array[Mesh.ARRAY_VERTEX]) + arr[Mesh.ARRAY_VERTEX] = v + + var norm : PoolVector3Array = PoolVector3Array() + norm.append_array(mesh_data.array[Mesh.ARRAY_NORMAL]) + arr[Mesh.ARRAY_NORMAL] = norm + + var uv : PoolVector2Array = PoolVector2Array() + uv.append_array(mesh_data.array[Mesh.ARRAY_TEX_UV]) + arr[Mesh.ARRAY_TEX_UV] = uv + + var ind : PoolIntArray = PoolIntArray() + ind.append_array(mesh_data.array[Mesh.ARRAY_INDEX]) + arr[Mesh.ARRAY_INDEX] = ind + + m.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) + + mesh = m + + if texture != null: + if _material == null: + _material = SpatialMaterial.new() + + _material.albedo_texture = texture + + material_override = _material + diff --git a/addons/prop_tool/tools/PropToolProp.gd b/addons/prop_tool/tools/PropToolProp.gd new file mode 100644 index 0000000..c2b3a0a --- /dev/null +++ b/addons/prop_tool/tools/PropToolProp.gd @@ -0,0 +1,32 @@ +tool +extends Spatial +class_name PropToolProp + +export(PropData) var prop_data : PropData +export(bool) var snap_to_mesh : bool = false +export(Vector3) var snap_axis : Vector3 = Vector3(0, -1, 0) + +var _prop_prop : PropDataProp + +func get_data() -> PropDataProp: + if not visible or prop_data == null: + return null + + if _prop_prop == null: + _prop_prop = PropDataProp.new() + + _prop_prop.prop = prop_data + _prop_prop.snap_to_mesh = snap_to_mesh + _prop_prop.snap_axis = snap_axis + + return _prop_prop + +func set_data(prop: PropDataProp) -> void: + _prop_prop = prop + + prop_data = _prop_prop.prop + snap_to_mesh = prop_data.snap_to_mesh + snap_axis = prop_data.snap_axis + +func refresh() -> void: + return diff --git a/addons/prop_tool/tools/PropToolScene.gd b/addons/prop_tool/tools/PropToolScene.gd new file mode 100644 index 0000000..4a1191c --- /dev/null +++ b/addons/prop_tool/tools/PropToolScene.gd @@ -0,0 +1,30 @@ +tool +extends Spatial +class_name PropToolScene + +export(PackedScene) var scene_data : PackedScene +export(bool) var snap_to_mesh : bool = false +export(Vector3) var snap_axis : Vector3 = Vector3(0, -1, 0) + +var _prop_scene : PropDataScene + +func get_data() -> PropDataScene: + if not visible or scene_data == null: + return null + + if _prop_scene == null: + _prop_scene = PropDataScene.new() + + _prop_scene.scene = scene_data + _prop_scene.snap_to_mesh = snap_to_mesh + _prop_scene.snap_axis = snap_axis + + return _prop_scene + +func set_data(scene: PropDataScene) -> void: + _prop_scene = scene + + scene_data = _prop_scene.scene + snap_to_mesh = _prop_scene.snap_to_mesh + snap_axis = _prop_scene.snap_axis +