Implemented structure relocation

This commit is contained in:
2024-07-25 21:07:59 +03:00
parent 144f45d522
commit 42ac0f19ca
8 changed files with 630 additions and 64 deletions

View File

@@ -1,13 +1,16 @@
#include <core/object.h>
#include <core/engine.h>
#include <scene/gui/control.h>
#include <scene/gui/box_container.h>
#include <scene/gui/button.h>
#include <scene/scene_string_names.h>
#include "world_editor.h"
WorldEditor::WorldEditor()
: Spatial()
, stream_world(nullptr)
, editor_menu(nullptr)
, current_mode(-1)
{
}
@@ -70,9 +73,16 @@ static std::unordered_map<String, int, StringHasher> modes = {
};
void WorldEditor::tools_button(const String &button)
{
Array change;
change.resize(2);
print_line("tools_button: " + button);
if (modes.find(button) == modes.end())
goto end;
if (current_mode == modes[button])
goto end;
change[0] = current_mode;
change[1] = modes[button];
emit_signal("editor_event", "mode_change_pre", change);
switch (modes[button]) {
case MODE_BUILDINGS:
mode_buildings();
@@ -90,82 +100,89 @@ void WorldEditor::tools_button(const String &button)
mode_npc();
break;
}
emit_signal("editor_event", "mode_change_post", change);
current_mode = modes[button];
end:;
}
#define CREATE_TOOLS_BUTTON(bname, btext) \
{ \
Vector<Variant> binds; \
binds.push_back(#bname); \
Button *bname = memnew(Button); \
bname->set_name(#bname); \
bname->set_text(btext); \
bname->set_custom_minimum_size(Vector2(188, 16)); \
bname->connect("pressed", this, "tools_button", binds); \
tools->add_child(bname); \
bname->update(); \
tools->update(); \
}
void WorldEditor::create_menu()
void WorldEditor::editor_command(const String &command, const Array &args)
{
editor_menu = memnew(Control);
editor_menu->set_name("menu");
editor_menu->set_anchor(MARGIN_LEFT, 1.0f);
editor_menu->set_anchor(MARGIN_RIGHT, 1.0f);
editor_menu->set_anchor(MARGIN_BOTTOM, 1.0f);
editor_menu->set_anchor(MARGIN_TOP, 0.0f);
editor_menu->update();
VBoxContainer *tools = memnew(VBoxContainer);
Vector2 min_size = tools->get_minimum_size();
min_size.x = 200.0f;
min_size.y = 400.0f;
tools->set_custom_minimum_size(min_size);
tools->set_name("tools");
tools->set_anchor_and_margin(MARGIN_LEFT, 1.0f, -210.0f);
tools->set_anchor_and_margin(MARGIN_RIGHT, 1.0f, 0.0f);
tools->set_anchor_and_margin(MARGIN_BOTTOM, 1.0f, 0.0f);
tools->set_anchor_and_margin(MARGIN_TOP, 0.0f, 0.0f);
tools->set_mouse_filter(Control::MOUSE_FILTER_STOP);
editor_menu->add_child(tools);
CREATE_TOOLS_BUTTON(select_buildings, "Select Buildings");
CREATE_TOOLS_BUTTON(select_navigation, "Select Navigation");
CREATE_TOOLS_BUTTON(select_poi, "Select POI");
CREATE_TOOLS_BUTTON(select_road_lines, "Select Road Lines");
CREATE_TOOLS_BUTTON(select_npc, "Select NPC");
editor_menu->update();
tools->update();
editor_menu->update();
tools->update();
print_line("Created menu");
print_line("running command: " + command);
if (command.begins_with("select_") &&
modes.find(command) != modes.end()) {
tools_button(command);
return;
} else if (command == "get_closest_building") {
if (stream_world) {
stream_world->run_command(command, args);
}
} else if (command == "update_building_transform") {
if (stream_world) {
stream_world->run_command(command, args);
}
}
}
Control *WorldEditor::get_editor_menu()
int WorldEditor::get_current_mode() const
{
if (!is_inside_tree())
return nullptr;
if (!editor_menu)
create_menu();
return editor_menu;
return current_mode;
}
StreamWorld *WorldEditor::get_stream_world()
{
return stream_world;
}
void WorldEditor::world_command_result(const String &what, const Array &data)
{
print_line("what: " + what);
emit_signal("editor_event", "result:" + what, data);
}
void WorldEditor::_notification(int which)
{
switch (which) {
case NOTIFICATION_ENTER_TREE: {
Control *c = get_editor_menu();
if (c)
add_child(c);
Node *base = get_parent();
int count = base->get_child_count();
int i;
for (i = 0; i < count; i++) {
Node *node = base->get_child(i);
StreamWorld *sw = Object::cast_to<StreamWorld>(node);
if (sw && !stream_world &&
!Engine::get_singleton()->is_editor_hint()) {
stream_world = sw;
sw->connect(SceneStringNames::get_singleton()
->tree_exiting,
this, "world_exited");
sw->connect("command_result", this,
"world_command_result");
}
}
} break;
case NOTIFICATION_EXIT_TREE:
if (editor_menu)
editor_menu->queue_delete();
break;
}
}
void WorldEditor::world_exited()
{
stream_world = nullptr;
}
void WorldEditor::_bind_methods()
{
ClassDB::bind_method(D_METHOD("tools_button", "button"),
&WorldEditor::tools_button);
ClassDB::bind_method(D_METHOD("editor_command", "command", "args"),
&WorldEditor::editor_command);
ClassDB::bind_method(D_METHOD("get_current_mode"),
&WorldEditor::get_current_mode);
ClassDB::bind_method(D_METHOD("get_stream_world"),
&WorldEditor::get_stream_world);
ClassDB::bind_method(D_METHOD("world_exited"),
&WorldEditor::world_exited);
ClassDB::bind_method(D_METHOD("world_command_result", "what", "data"),
&WorldEditor::world_command_result);
ADD_SIGNAL(MethodInfo("editor_event",
PropertyInfo(Variant::STRING, "event_name"),
PropertyInfo(Variant::ARRAY, "args")));
}