Finally implemented interior graph

This commit is contained in:
2024-10-26 21:56:07 +03:00
parent 69b807bf22
commit 5b4fcdd0f6
2 changed files with 279 additions and 42 deletions

View File

@@ -34,10 +34,53 @@ public:
{ {
dlg->connect("tree_entered", this, "tree_entered"); dlg->connect("tree_entered", this, "tree_entered");
} }
void menu_pressed(int id, Control *button) void menu_pressed(int id, Control *button, const String &path)
{ {
assert(button); assert(button);
print_line(itos(id)); print_line(itos(id));
print_line(path);
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity base_e = ecs.lookup(path.ascii().ptr());
switch (id) {
case 100:
case 101:
case 102:
case 103: {
int count = 0;
String type_name;
switch (id) {
case 100:
type_name = "unit";
break;
case 101:
case 102:
type_name = "zone";
break;
}
if (type_name.length() == 0)
return;
base_e.children([type_name, &count](flecs::entity e) {
String name(e.name());
if (name.begins_with(type_name + "_" +
itos(count)))
count++;
});
String ename = type_name + "_" + itos(count);
flecs::entity new_e =
ecs.entity(ename.ascii().ptr()).child_of(base_e);
if (id == 100) {
new_e.set<WorldEditor::components::
buildings_layout_unit>({ 0 });
} else if (id == 101) {
new_e.set<WorldEditor::components::
buildings_layout_zone>({ 0 });
} else if (id == 102) {
new_e.set<WorldEditor::components::
buildings_layout_zone>({ 1 });
}
} break;
}
update_graph();
} }
flecs::entity get_layout_base() flecs::entity get_layout_base()
{ {
@@ -84,8 +127,11 @@ public:
if (e.is_valid()) if (e.is_valid())
return; return;
e = ecs.entity(layout_name.ascii().ptr()).child_of(base); e = ecs.entity(layout_name.ascii().ptr()).child_of(base);
if (e.is_valid()) if (e.is_valid()) {
e.add<WorldEditor::components::buildings_layout_graph>(); e.add<WorldEditor::components::buildings_layout_graph>();
e.set<WorldEditor::components::buildings_layout_floor>(
{ 0 });
}
} }
flecs::entity get_current_layout() flecs::entity get_current_layout()
{ {
@@ -133,8 +179,11 @@ public:
selected = i; selected = i;
break; break;
} }
if (selected >= 0) if (selected >= 0) {
item_list->select(selected); item_list->select(selected);
select_layout(selected);
update_graph();
}
if (!item_list->is_connected("item_selected", this, if (!item_list->is_connected("item_selected", this,
"select_layout")) "select_layout"))
item_list->connect("item_selected", this, item_list->connect("item_selected", this,
@@ -178,22 +227,57 @@ public:
void update_buttons(ColorRect *canvas) void update_buttons(ColorRect *canvas)
{ {
assert(current_layout.length() > 0); assert(current_layout.length() > 0);
flecs::entity e = get_current_layout(); flecs::entity layout_e = get_current_layout();
List<flecs::entity> queue; List<flecs::entity> queue;
bool layout_empty = true; bool layout_empty = true;
queue.push_back(e); queue.push_back(layout_e);
HashMap<int, int> depth_height; layout_e.set<
depth_height[0] = 0; WorldEditor::components::buildings_layout_graph_node>(
buttons.clear(); { 0, 0, 0 });
queue.clear();
queue.push_back(layout_e);
while (!queue.empty()) { while (!queue.empty()) {
flecs::entity e = queue.front()->get();
queue.pop_front();
int size = 1;
bool readd = false;
e.children([&readd, &size, &queue](flecs::entity fe) {
if (!fe.has<WorldEditor::components::
buildings_layout_graph_node>()) {
fe.set<WorldEditor::components::
buildings_layout_graph_node>(
{ 0, 0, 0 });
readd = true;
}
size += fe.get<WorldEditor::components::
buildings_layout_graph_node>()
->size;
queue.push_back(fe);
});
if (readd)
queue.push_back(e);
if (e.get<WorldEditor::components::
buildings_layout_graph_node>()
->size != size) {
e.get_mut<WorldEditor::components::
buildings_layout_graph_node>()
->size = size;
if (e.parent()
.has<WorldEditor::components::
buildings_layout_graph_node>())
queue.push_back(e);
}
}
queue.clear();
queue.push_back(layout_e);
while (!queue.empty()) {
buttons.clear();
layout_empty = false; layout_empty = false;
flecs::entity e = queue.front()->get(); flecs::entity e = queue.front()->get();
queue.pop_front(); queue.pop_front();
if (!e.has<WorldEditor::components:: if (!e.has<WorldEditor::components::
buildings_layout_graph_node>()) { buildings_layout_graph_node>()) {
e.set<WorldEditor::components:: assert(false);
buildings_layout_graph_node>(
{ 0, 0 });
} }
int depth = e.get<WorldEditor::components:: int depth = e.get<WorldEditor::components::
buildings_layout_graph_node>() buildings_layout_graph_node>()
@@ -201,18 +285,109 @@ public:
int y = e.get<WorldEditor::components:: int y = e.get<WorldEditor::components::
buildings_layout_graph_node>() buildings_layout_graph_node>()
->y_pos; ->y_pos;
e.get_mut<WorldEditor::components::
buildings_layout_graph_node>()
->y_pos = y;
/* make button here */ /* make button here */
Vector2 pt(depth * 100 + 40, y * 60 + 40); Vector2 pt(depth * 120 + 40, y * 110 + 40);
buttons.push_back(pt);
{ {
MenuButton *button = memnew(MenuButton); MenuButton *button = memnew(MenuButton);
button->set_text("XXX"); button->set_text("");
canvas->add_child(button); canvas->add_child(button);
button->set_size(Vector2(80, 40)); button->set_size(Vector2(80, 40));
button->set_position(pt); button->set_position(pt);
if (e.has<WorldEditor::components:: if (e.has<WorldEditor::components::
buildings_layout_graph>()) { buildings_layout_floor>()) {
button->set_text("Entry"); button->set_text(button->get_text() +
"Floor\n" +
String(e.name()));
button->get_popup()->add_item(
"Create block unit", 100);
button->get_popup()->add_item(
"Create private zone", 101);
button->get_popup()->add_item(
"Create public zone", 102);
}
if (e.has<WorldEditor::components::
buildings_layout_unit>()) {
button->set_text(button->get_text() +
"Unit\n" +
String(e.name()));
button->get_popup()->add_item(
"Create private zone", 101);
button->get_popup()->add_item(
"Create public zone", 102);
}
if (e.has<WorldEditor::components::
buildings_layout_zone>()) {
int zone_type =
e.get<WorldEditor::components::
buildings_layout_zone>()
->type;
if (zone_type == 0) {
button->set_text(
button->get_text() +
"Private Zone\n");
button->get_popup()->add_item(
"Create WC", 200);
button->get_popup()->add_item(
"Create Bathroom", 201);
button->get_popup()->add_item(
"Create Bedroom", 202);
button->get_popup()->add_item(
"Create Holding Cell",
203);
button->get_popup()->add_item(
"Create Torture Room",
203);
} else if (zone_type == 1) {
button->set_text(
button->get_text() +
"Public Zone\n");
button->get_popup()->add_item(
"Create Living Room",
300);
button->get_popup()->add_item(
"Create Family Room",
301);
button->get_popup()->add_item(
"Create Kitchen", 302);
button->get_popup()->add_item(
"Create Dinging Room",
303);
button->get_popup()->add_item(
"Create Enterance",
304);
button->get_popup()->add_item(
"Create Stair", 305);
button->get_popup()->add_item(
"Create Elevator", 306);
button->get_popup()->add_item(
"Create Storage Room",
307);
button->get_popup()->add_item(
"Create Cellar", 308);
button->get_popup()->add_item(
"Create Office", 309);
button->get_popup()->add_item(
"Create Server Room",
310);
button->get_popup()->add_item(
"Create Room", 311);
PopupMenu *mp =
memnew(PopupMenu);
mp->add_child(memnew(LineEdit));
button->get_popup()->add_child(
mp);
mp->set_name("subedit");
button->get_popup()
->add_submenu_item(
"SubEdit Moo",
"subedit", 400);
}
button->set_text(button->get_text() +
String(e.name()));
#if 0
button->get_popup()->add_item( button->get_popup()->add_item(
"Create block unit", 100); "Create block unit", 100);
button->get_popup()->add_item( button->get_popup()->add_item(
@@ -221,34 +396,38 @@ public:
"Create public zone", 102); "Create public zone", 102);
button->get_popup()->add_item( button->get_popup()->add_item(
"Create hallway", 103); "Create hallway", 103);
button->get_popup()->connect( #endif
"id_pressed", this,
"menu_pressed", varray(button));
} }
#if 0
button->set_text(
button->get_text() + "size: \n" +
itos(e.get<WorldEditor::components::
buildings_layout_graph_node>()
->size));
#endif
button->get_popup()->connect(
"id_pressed", this, "menu_pressed",
varray(button, String(e.path())));
} }
int count = 0; int count = 0;
int offset = y;
e.children([depth, y, &count, &queue, e.children([depth, y, &count, &queue,
&depth_height](flecs::entity e) { &offset](flecs::entity fe) {
e.set<WorldEditor::components:: int size =
fe.get<WorldEditor::components::
buildings_layout_graph_node>()
->size;
fe.set<WorldEditor::components::
buildings_layout_graph_node>( buildings_layout_graph_node>(
{ depth + 1, y + count }); { depth + 1, offset, size });
queue.push_back(e); offset += size;
if (!depth_height.has(depth + 1)) queue.push_back(fe);
depth_height[depth + 1] = 0; count++;
depth_height[depth + 1] =
MAX(depth_height[depth + 1],
y + count) +
1;
}); });
if (!depth_height.has(depth))
depth_height[depth] = y + count + 1; // if (count > 1)
else { // height += count - 1;
y = MAX(depth_height[depth], y); // // height++;
e.set<WorldEditor::components::
buildings_layout_graph_node>(
{ depth, y });
depth_height[depth] = y + count + 1;
}
} }
#if 0 #if 0
if (layout_empty) { if (layout_empty) {
@@ -307,11 +486,58 @@ public:
} }
void draw_graph() void draw_graph()
{ {
List<flecs::entity> queue;
if (current_layout.length() == 0) {
canvas_item->draw_rect(Rect2(Vector2(),
canvas_item->get_size()),
Color(0.4, 0.4, 0.65, 1.0));
// canvas_item->draw_string()
return;
}
flecs::entity layout_e = get_current_layout();
queue.push_back(layout_e);
canvas_item->draw_rect(Rect2(Vector2(), canvas_item->draw_rect(Rect2(Vector2(),
canvas_item->get_size()), canvas_item->get_size()),
Color(0.2, 0.2, 0.25, 1.0)); Color(0.2, 0.2, 0.25, 1.0));
canvas_item->draw_circle(Vector2(40, 45) + Vector2(40, 20), while (!queue.empty()) {
40.0f, Color(0.4, 0.4, 0.55, 1.0)); Vector2 p1;
flecs::entity button_e = queue.front()->get();
if (button_e.has<WorldEditor::components::
buildings_layout_graph_node>()) {
int depth =
button_e.get<WorldEditor::components::
buildings_layout_graph_node>()
->depth;
int y = button_e.get<WorldEditor::components::
buildings_layout_graph_node>()
->y_pos;
Vector2 pt(depth * 120 + 40, y * 110 + 40);
canvas_item->draw_circle(
pt + Vector2(40, 20), 40.0f,
Color(0.4, 0.4, 0.55, 1.0));
p1 = pt + Vector2(40, 20);
}
queue.pop_front();
button_e.children([&queue, this, p1](flecs::entity e) {
int depth =
e.get<WorldEditor::components::
buildings_layout_graph_node>()
->depth;
int y = e.get<WorldEditor::components::
buildings_layout_graph_node>()
->y_pos;
Vector2 p2(depth * 120 + 40, y * 110 + 40);
p2 += Vector2(40, 20);
Vector2 p3(p1.x, p2.y);
canvas_item->draw_line(p1, p3,
Color(0.4, 0.4, 0.55),
4.0f, true);
canvas_item->draw_line(p3, p2,
Color(0.4, 0.4, 0.55),
4.0f, true);
queue.push_back(e);
});
}
} }
void setup_layout_tab(Control *tab, const String &header) void setup_layout_tab(Control *tab, const String &header)
{ {
@@ -334,7 +560,8 @@ public:
} }
static void _bind_methods() static void _bind_methods()
{ {
ClassDB::bind_method(D_METHOD("menu_pressed", "id", "button"), ClassDB::bind_method(D_METHOD("menu_pressed", "id", "button",
"path"),
&BuildingLayoutGraphUI::menu_pressed); &BuildingLayoutGraphUI::menu_pressed);
ClassDB::bind_method(D_METHOD("tree_entered"), ClassDB::bind_method(D_METHOD("tree_entered"),
&BuildingLayoutGraphUI::tree_entered); &BuildingLayoutGraphUI::tree_entered);

View File

@@ -71,6 +71,16 @@ public:
struct buildings_layout_graph_node { struct buildings_layout_graph_node {
int depth; int depth;
int y_pos; int y_pos;
int size;
};
struct buildings_layout_unit {
int flags;
};
struct buildings_layout_zone {
int type;
};
struct buildings_layout_floor {
int flags;
}; };
}; };
}; };