Now able to create grid

This commit is contained in:
2024-11-10 05:12:47 +03:00
parent bfa2621dee
commit db2942986d
6 changed files with 319 additions and 21 deletions

View File

@@ -218,7 +218,6 @@ public:
: Object() : Object()
, editor(editor) , editor(editor)
{ {
int i;
Button *cancel_button = editor->get_as_node<Button>( Button *cancel_button = editor->get_as_node<Button>(
"%road_lines_create_new_cancel"); "%road_lines_create_new_cancel");
LineEdit *line_name = editor->get_as_node<LineEdit>( LineEdit *line_name = editor->get_as_node<LineEdit>(
@@ -245,7 +244,6 @@ public:
} }
virtual ~HandleCreateNewLine() virtual ~HandleCreateNewLine()
{ {
int i;
Button *line_buildings_close = Button *line_buildings_close =
editor->get_as_node<Button>("%line_buildings_close"); editor->get_as_node<Button>("%line_buildings_close");
TextEdit *metadata_edit = editor->get_as_node<TextEdit>( TextEdit *metadata_edit = editor->get_as_node<TextEdit>(

View File

@@ -8,9 +8,11 @@ BuildingLayoutGraph *BuildingLayoutGraph::singleton = nullptr;
BuildingLayoutGraph::BuildingLayoutGraph() BuildingLayoutGraph::BuildingLayoutGraph()
{ {
BaseData::get_singleton() flecs::world ecs = BaseData::get_singleton()->get();
->get() flecs::log::set_level(255);
.import <BuildingLayoutGraph::graph_module>(); get_layout_grid_base();
get_layout_grid_base();
ecs.import <BuildingLayoutGraph::graph_module>();
Error err = config.load("res://astream/building_layout.conf"); Error err = config.load("res://astream/building_layout.conf");
assert(err == OK); assert(err == OK);
public_rooms = config.get_value("rooms", "public", Array()); public_rooms = config.get_value("rooms", "public", Array());
@@ -22,6 +24,13 @@ BuildingLayoutGraph::~BuildingLayoutGraph()
{ {
} }
BuildingLayoutGraph *BuildingLayoutGraph::get_singleton()
{
if (!singleton)
singleton = memnew(BuildingLayoutGraph());
return singleton;
}
void BuildingLayoutGraph::get_room_data(int id, Array &result) void BuildingLayoutGraph::get_room_data(int id, Array &result)
{ {
int i; int i;
@@ -93,6 +102,8 @@ flecs::entity BuildingLayoutGraph::get_layout_grid_base() const
assert(layout_base_e.is_valid()); assert(layout_base_e.is_valid());
layout_base_e.add< layout_base_e.add<
WorldEditor::components::buildings_layout_grid_base>(); WorldEditor::components::buildings_layout_grid_base>();
assert(layout_base_e.has<
WorldEditor::components::buildings_layout_grid_base>());
return layout_base_e; return layout_base_e;
} }
} }

View File

@@ -14,12 +14,7 @@ class BuildingLayoutGraph {
public: public:
virtual ~BuildingLayoutGraph(); virtual ~BuildingLayoutGraph();
static BuildingLayoutGraph *get_singleton() static BuildingLayoutGraph *get_singleton();
{
if (!singleton)
singleton = memnew(BuildingLayoutGraph());
return singleton;
}
static void cleanup() static void cleanup()
{ {
memdelete(singleton); memdelete(singleton);

View File

@@ -218,6 +218,18 @@ void BuildingLayoutGraphUI::update_buttons(ColorRect *canvas)
args.size()); args.size());
} }
} }
if (e.has<WorldEditor::components::
buildings_layout_grid_size>()) {
int grid_size =
e.get<WorldEditor::components::
buildings_layout_grid_size>()
->grid_size;
std::vector<Variant> args = { "Grid size: " +
itos(grid_size) };
ui_field::ui_field_builder(canvas, box, "l",
args.data(),
args.size());
}
if (!e.has<WorldEditor::components:: if (!e.has<WorldEditor::components::
buildings_layout_floor>() && buildings_layout_floor>() &&
e.has<WorldEditor::components:: e.has<WorldEditor::components::
@@ -452,7 +464,6 @@ void BuildingLayoutGraphUI::command_entered(int index, Control *item,
assert(e.is_valid()); assert(e.is_valid());
int cmd = item->get_meta("cmd"); int cmd = item->get_meta("cmd");
if (cmd >= 0) { if (cmd >= 0) {
int command = index;
Vector<Variant> args; Vector<Variant> args;
WorldEditor::components::buildings_layout_commands *c = e.get_mut< WorldEditor::components::buildings_layout_commands *c = e.get_mut<
WorldEditor::components::buildings_layout_commands>(); WorldEditor::components::buildings_layout_commands>();
@@ -713,16 +724,16 @@ void BuildingLayoutGraphUI::draw_building_gen_display(Control *draw)
const List<Pair<Vector2i, Vector2i> > &edges = const List<Pair<Vector2i, Vector2i> > &edges =
e.get<WorldEditor::components::buildings_layout_skeleton>() e.get<WorldEditor::components::buildings_layout_skeleton>()
->edges; ->edges;
const List<Pair<Vector2i, Vector2i> >::Element *e = const List<Pair<Vector2i, Vector2i> >::Element *ef =
edges.front(); edges.front();
Vector2i p(10, 10); Vector2i p(10, 10);
while (e) { while (ef) {
Pair<Vector2i, Vector2i> edge = e->get(); Pair<Vector2i, Vector2i> edge = ef->get();
draw->draw_line(edge.first + p, edge.second + p, draw->draw_line(edge.first + p, edge.second + p,
Color(0, 0, 0, 1)); Color(0, 0, 0, 1));
print_line((e->get().first.operator String()) + "->" + print_line((ef->get().first.operator String()) + "->" +
(e->get().second.operator String())); (ef->get().second.operator String()));
e = e->next(); ef = ef->next();
} }
} }
} }

View File

@@ -7,6 +7,7 @@
#define MIN_ROOM_SIZE 16 /* 4 * 4 tiles */ #define MIN_ROOM_SIZE 16 /* 4 * 4 tiles */
struct state { struct state {
Rect2i bounds;
Vector2i start_position; Vector2i start_position;
Vector2i current_position; Vector2i current_position;
List<Pair<Vector2i, Vector2i> > edges; List<Pair<Vector2i, Vector2i> > edges;
@@ -50,8 +51,45 @@ struct state {
Vector2i p1 = current_position; Vector2i p1 = current_position;
Vector2i p2 = p1 + directions[direction] * amount; Vector2i p2 = p1 + directions[direction] * amount;
assert(p1 != p2); assert(p1 != p2);
int min_x = MIN(p1.x, p2.x);
int min_y = MIN(p1.y, p2.y);
if (min_x < 0) {
float adj_x = -min_x + 1;
List<Pair<Vector2i, Vector2i> >::Element *e =
edges.front();
while (e) {
e->get().first.x += adj_x;
e->get().second.x += adj_x;
bounds.expand_to(e->get().first);
bounds.expand_to(e->get().second);
e = e->next();
}
p1.x += adj_x;
p2.x += adj_x;
}
if (min_y < 0) {
float adj_y = -min_y + 1;
List<Pair<Vector2i, Vector2i> >::Element *e =
edges.front();
while (e) {
e->get().first.y += adj_y;
e->get().second.y += adj_y;
e = e->next();
}
p1.y += adj_y;
p2.y += adj_y;
}
edges.push_back(Pair<Vector2i, Vector2i>(p1, p2)); edges.push_back(Pair<Vector2i, Vector2i>(p1, p2));
current_position = p2; current_position = p2;
if (bounds.size.x * bounds.size.y == 0)
bounds.position = p1;
else
bounds.expand_to(p1);
bounds.expand_to(p2);
if (bounds.size.x < bounds.size.y)
bounds.size.x = bounds.size.y;
if (bounds.size.y < bounds.size.x)
bounds.size.y = bounds.size.x;
} }
void run_command(int command, Vector<Variant> args) void run_command(int command, Vector<Variant> args)
{ {
@@ -101,6 +139,8 @@ struct state {
BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs) BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
{ {
ecs.module<BuildingLayoutGraph::graph_module>(); ecs.module<BuildingLayoutGraph::graph_module>();
ecs.import <flecs::stats>();
ecs.set<flecs::Rest>({});
ecs.component<WorldEditor::components::buildings_layout_graph>(); ecs.component<WorldEditor::components::buildings_layout_graph>();
ecs.component<WorldEditor::components::buildings_layout_graph_node>(); ecs.component<WorldEditor::components::buildings_layout_graph_node>();
ecs.component<WorldEditor::components::buildings_layout_base>(); ecs.component<WorldEditor::components::buildings_layout_base>();
@@ -108,7 +148,28 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
ecs.component<WorldEditor::components::buildings_layout_zone>(); ecs.component<WorldEditor::components::buildings_layout_zone>();
ecs.component<WorldEditor::components::buildings_layout_unit>(); ecs.component<WorldEditor::components::buildings_layout_unit>();
ecs.component<WorldEditor::components::buildings_layout_floor>(); ecs.component<WorldEditor::components::buildings_layout_floor>();
ecs.component<WorldEditor::components::buildings_layout_floor_index>(); ecs.component<WorldEditor::components::buildings_layout_floor_index>()
.member<int>("index");
ecs.component<WorldEditor::components::buildings_layout_grid>();
ecs.component<WorldEditor::components::buildings_layout_grid_cell>();
ecs.component<WorldEditor::components::buildings_layout_grid_size>()
.member<int>("grid_size");
ecs.component<WorldEditor::components::buildings_layout_area>()
.member<float>("area");
ecs.component<WorldEditor::components::buildings_layout_order>()
.member<int>("index");
#if 0
ecs.component<
WorldEditor::components::buildings_layout_commands::command>()
.member<int>("command")
.member<Vector<Variant> >("args");
ecs.component<WorldEditor::components::buildings_layout_commands>()
.member<WorldEditor::components::buildings_layout_commands::
command>("commands");
#endif
ecs.component<WorldEditor::components::buildings_layout_commands>();
// get_layout_grid_base();
// BuildingLayoutGraph::get_singleton()->get_layout_grid_base();
const String &module_name = "::BuildingLayoutGraph::graph_module"; const String &module_name = "::BuildingLayoutGraph::graph_module";
flecs::entity GraphSolveZones = ecs.entity("GraphSolveZones") flecs::entity GraphSolveZones = ecs.entity("GraphSolveZones")
.add(flecs::Phase) .add(flecs::Phase)
@@ -183,7 +244,7 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
.each([](flecs::iter &it, size_t count, .each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_room &f, const WorldEditor::components::buildings_layout_room &f,
WorldEditor::components::buildings_layout_area &area) { WorldEditor::components::buildings_layout_area &area) {
flecs::entity room_e = it.entity(count); // flecs::entity room_e = it.entity(count);
if (area.area < MIN_ROOM_SIZE) if (area.area < MIN_ROOM_SIZE)
area.area = MIN_ROOM_SIZE; area.area = MIN_ROOM_SIZE;
}); });
@@ -677,12 +738,226 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
if (badness == 0) if (badness == 0)
graph_e.set<WorldEditor::components:: graph_e.set<WorldEditor::components::
buildings_layout_skeleton>( buildings_layout_skeleton>(
{ state.edges }); { state.edges, state.bounds });
print_line(String(graph_e.path())); print_line(String(graph_e.path()));
state.dump(); state.dump();
if (badness > 0) if (badness > 0)
print_line("BAD!"); print_line("BAD!");
}); });
#if 0
ecs.system<const WorldEditor::components::buildings_layout_skeleton>(
"MakeBuildingGrid")
.kind(GraphSolve)
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_skeleton
&skel) {
flecs::entity graph_e = it.entity(count);
flecs::entity base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_base();
String pname(graph_e.name());
String ename = "grid_" + pname;
#if 0
flecs::entity grid_e = graph_e.lookup("grid");
if (!grid_e.is_valid())
grid_e =
graph_e.world().entity("grid").child_of(
graph_e);
#endif
});
#endif
ecs.system<const WorldEditor::components::buildings_layout_graph,
const WorldEditor::components::buildings_layout_area>(
"SetGridSize")
.kind(GraphSolve)
.write<WorldEditor::components::buildings_layout_grid_size>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_graph,
const WorldEditor::components::buildings_layout_area
&area) {
int grid_size = (int)(Math::sqrt(area.area) * 1.5) + 1;
flecs::entity graph_e = it.entity(count);
List<flecs::entity> query;
query.push_back(graph_e);
List<int> floors;
while (!query.empty()) {
flecs::entity fe = query.front()->get();
query.pop_front();
if (fe.has<WorldEditor::components::
buildings_layout_floor>()) {
int index =
fe.get<WorldEditor::components::
buildings_layout_floor_index>()
->index;
if (!floors.find(index))
floors.push_back(index);
}
fe.children([&query](flecs::entity ce) {
query.push_back(ce);
});
}
graph_e.set<WorldEditor::components::
buildings_layout_grid_size>(
{ grid_size, floors });
});
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
"ResetGrid")
.kind(GraphSolve)
.immediate()
.read<WorldEditor::components::buildings_layout_grid_base>()
.write<WorldEditor::components::buildings_layout_grid_base>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_grid_size
&size) {
flecs::entity graph_e = it.entity(count);
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
flecs::entity grid_e =
grid_base_e.lookup(graph_e.name());
if (grid_e.is_valid())
grid_e.destruct();
});
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
"CreateGridEntity")
.kind(GraphSolve)
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_grid_size
&size) {
flecs::entity graph_e = it.entity(count);
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
flecs::entity grid_e =
grid_base_e.lookup(graph_e.name());
assert(!grid_e.is_valid());
grid_e = graph_e.world()
.entity(graph_e.name())
.child_of(grid_base_e);
grid_e.add<
WorldEditor::components::buildings_layout_grid>();
});
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
"SetupGrid")
.kind(GraphSolve)
.write<WorldEditor::components::buildings_layout_grid>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_grid_size
&size) {
/* TODO: use it or delete it
flecs::entity graph_e = it.entity(count);
graph_e.add<
WorldEditor::components::buildings_layout_grid>();
*/
});
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
"CreateGrid")
.kind(GraphSolve)
.write<WorldEditor::components::buildings_layout_grid>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_grid_size
&size) {
int i;
flecs::entity graph_e = it.entity(count);
flecs::log::err("CreateGrid: %s",
graph_e.path().c_str());
flecs::log::dbg("CreateGrid: %s",
graph_e.path().c_str());
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
flecs::entity grid_e =
grid_base_e.lookup(graph_e.name());
assert(grid_e.is_valid());
const List<int>::Element *me = size.floors.front();
while (me) {
String floor_name = "floor_" + itos(me->get());
flecs::entity floor_e =
grid_e.world()
.entity(floor_name.ascii().ptr())
.child_of(grid_e);
assert(floor_e.is_valid());
flecs::log::dbg(
"CreateGrid: %s floor %d grid_size %d",
graph_e.path().c_str(), me->get(),
size.grid_size);
for (i = 0; i < size.grid_size * size.grid_size;
i++) {
String pname = "cell_" + itos(i);
flecs::entity cell_e =
floor_e.world()
.entity(pname.ascii()
.ptr())
.child_of(floor_e);
assert(cell_e.is_valid());
cell_e.set<
WorldEditor::components::
buildings_layout_grid_cell>(
{ "empty" });
flecs::log::dbg(
"CreateGrid: %s floor %d cell %d %s",
graph_e.path().c_str(),
me->get(), i,
cell_e.path().c_str());
}
me = me->next();
}
#if 0
int i;
flecs::entity graph_e = it.entity(count);
List<flecs::entity> query;
query.push_back(graph_e);
HashMap<int, String> floor_list;
while (!query.empty()) {
flecs::entity fe = query.front()->get();
query.pop_front();
if (fe.has<WorldEditor::components::
buildings_layout_floor>()) {
int index =
fe.get<WorldEditor::components::
buildings_layout_floor_index>()
->index;
String floor_name =
"floor_" + itos(index);
floor_list[index] = floor_name;
}
fe.children([&query](flecs::entity ce) {
query.push_back(ce);
});
}
List<int> floors;
floor_list.get_key_list(&floors);
flecs::entity grid_e = graph_e.lookup("grid");
assert(graph_e.is_valid());
List<int>::Element *me = floors.front();
while (me) {
String floor_name = floor_list[me->get()];
flecs::entity floor_e =
grid_e.world()
.entity(floor_name.ascii().ptr())
.child_of(grid_e);
for (i = 0; i < size.grid_size * size.grid_size;
i++) {
String pname = "cell_" + itos(i);
flecs::entity cell_e =
floor_e.world()
.entity(pname.ascii()
.ptr())
.child_of(floor_e);
assert(cell_e.is_valid());
cell_e.set<
WorldEditor::components::
buildings_layout_grid_cell>(
{ "empty" });
}
me = me->next();
}
String pjson(grid_e.world().to_json());
print_line(pjson);
#endif
});
ecs.system("AssembleSkeletonEnd") ecs.system("AssembleSkeletonEnd")
.kind(GraphSolve) .kind(GraphSolve)
.run([module_name](flecs::iter &it) { .run([module_name](flecs::iter &it) {

View File

@@ -70,6 +70,9 @@ public:
struct buildings_layout_base {}; struct buildings_layout_base {};
struct buildings_layout_grid_base {}; struct buildings_layout_grid_base {};
struct buildings_layout_grid {}; struct buildings_layout_grid {};
struct buildings_layout_grid_cell {
String type;
};
struct buildings_layout_graph {}; struct buildings_layout_graph {};
struct buildings_layout_graph_node { struct buildings_layout_graph_node {
int depth; int depth;
@@ -106,6 +109,11 @@ public:
}; };
struct buildings_layout_skeleton { struct buildings_layout_skeleton {
List<Pair<Vector2i, Vector2i> > edges; List<Pair<Vector2i, Vector2i> > edges;
Rect2i bounds;
};
struct buildings_layout_grid_size {
int grid_size;
List<int> floors;
}; };
struct buildings_layout_commands { struct buildings_layout_commands {
struct command { struct command {