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");
}
void menu_pressed(int id, Control *button)
void menu_pressed(int id, Control *button, const String &path)
{
assert(button);
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()
{
@@ -84,8 +127,11 @@ public:
if (e.is_valid())
return;
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.set<WorldEditor::components::buildings_layout_floor>(
{ 0 });
}
}
flecs::entity get_current_layout()
{
@@ -133,8 +179,11 @@ public:
selected = i;
break;
}
if (selected >= 0)
if (selected >= 0) {
item_list->select(selected);
select_layout(selected);
update_graph();
}
if (!item_list->is_connected("item_selected", this,
"select_layout"))
item_list->connect("item_selected", this,
@@ -178,22 +227,57 @@ public:
void update_buttons(ColorRect *canvas)
{
assert(current_layout.length() > 0);
flecs::entity e = get_current_layout();
flecs::entity layout_e = get_current_layout();
List<flecs::entity> queue;
bool layout_empty = true;
queue.push_back(e);
HashMap<int, int> depth_height;
depth_height[0] = 0;
buttons.clear();
queue.push_back(layout_e);
layout_e.set<
WorldEditor::components::buildings_layout_graph_node>(
{ 0, 0, 0 });
queue.clear();
queue.push_back(layout_e);
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;
flecs::entity e = queue.front()->get();
queue.pop_front();
if (!e.has<WorldEditor::components::
buildings_layout_graph_node>()) {
e.set<WorldEditor::components::
buildings_layout_graph_node>(
{ 0, 0 });
assert(false);
}
int depth = e.get<WorldEditor::components::
buildings_layout_graph_node>()
@@ -201,18 +285,109 @@ public:
int y = e.get<WorldEditor::components::
buildings_layout_graph_node>()
->y_pos;
e.get_mut<WorldEditor::components::
buildings_layout_graph_node>()
->y_pos = y;
/* make button here */
Vector2 pt(depth * 100 + 40, y * 60 + 40);
buttons.push_back(pt);
Vector2 pt(depth * 120 + 40, y * 110 + 40);
{
MenuButton *button = memnew(MenuButton);
button->set_text("XXX");
button->set_text("");
canvas->add_child(button);
button->set_size(Vector2(80, 40));
button->set_position(pt);
if (e.has<WorldEditor::components::
buildings_layout_graph>()) {
button->set_text("Entry");
buildings_layout_floor>()) {
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(
"Create block unit", 100);
button->get_popup()->add_item(
@@ -221,34 +396,38 @@ public:
"Create public zone", 102);
button->get_popup()->add_item(
"Create hallway", 103);
button->get_popup()->connect(
"id_pressed", this,
"menu_pressed", varray(button));
#endif
}
#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 offset = y;
e.children([depth, y, &count, &queue,
&depth_height](flecs::entity e) {
e.set<WorldEditor::components::
buildings_layout_graph_node>(
{ depth + 1, y + count });
queue.push_back(e);
if (!depth_height.has(depth + 1))
depth_height[depth + 1] = 0;
depth_height[depth + 1] =
MAX(depth_height[depth + 1],
y + count) +
1;
&offset](flecs::entity fe) {
int size =
fe.get<WorldEditor::components::
buildings_layout_graph_node>()
->size;
fe.set<WorldEditor::components::
buildings_layout_graph_node>(
{ depth + 1, offset, size });
offset += size;
queue.push_back(fe);
count++;
});
if (!depth_height.has(depth))
depth_height[depth] = y + count + 1;
else {
y = MAX(depth_height[depth], y);
e.set<WorldEditor::components::
buildings_layout_graph_node>(
{ depth, y });
depth_height[depth] = y + count + 1;
}
// if (count > 1)
// height += count - 1;
// // height++;
}
#if 0
if (layout_empty) {
@@ -307,11 +486,58 @@ public:
}
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->get_size()),
Color(0.2, 0.2, 0.25, 1.0));
canvas_item->draw_circle(Vector2(40, 45) + Vector2(40, 20),
40.0f, Color(0.4, 0.4, 0.55, 1.0));
while (!queue.empty()) {
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)
{
@@ -334,7 +560,8 @@ public:
}
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);
ClassDB::bind_method(D_METHOD("tree_entered"),
&BuildingLayoutGraphUI::tree_entered);

View File

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