Roworking enterance handling

This commit is contained in:
2024-12-10 19:31:50 +03:00
parent d2cd99d325
commit af490a5eb4
4 changed files with 140 additions and 13 deletions

View File

@@ -1,5 +1,6 @@
#include <core/os/memory.h>
#include <core/io/config_file.h>
#include "base_data.h"
class BuildingLayoutGraph {
static BuildingLayoutGraph *singleton;

View File

@@ -119,7 +119,10 @@ void grow_job_queue::job_initial(struct grow_job *job)
clip_rect.grow(-1), grid_size * grid_size, false, false,
false, true },
Vector<struct region_tree *>(),
nullptr });
nullptr,
false,
false,
-1 });
struct region_tree *rtree = grid_floor_e.get_mut<region_tree>();
flecs::log::dbg("region rect: %s",
(rtree->region.rect.operator String()).ascii().ptr());

View File

@@ -4,6 +4,7 @@
#include <core/list.h>
#include <core/hashfuncs.h>
#include <core/hash_map.h>
#include "building_layout_graph.h"
#include "region_tree.h"
void region_tree::split(flecs::entity grid_floor_e,
@@ -16,6 +17,11 @@ void region_tree::split(flecs::entity grid_floor_e,
const List<struct region>::Element *e = regions.front();
int count = 0;
assert(base_rtree->check(grid_floor_e));
assert(!is_a_room(grid_floor_e));
assert(!flag_room);
flecs::entity room_c = grid_floor_e.world().lookup(
"::graph_module::buildings_layout_room");
assert(room_c.is_valid());
while (e) {
flecs::log::warn(
"%lx: %s -> %s", region.region_et,
@@ -25,6 +31,23 @@ void region_tree::split(flecs::entity grid_floor_e,
struct region_tree *child = memnew(struct region_tree);
child->parent = this;
child->region = e->get();
flecs::entity region_e =
grid_floor_e.world().entity(child->region.region_et);
assert(region_e.is_valid());
if (region_e.has(room_c)) {
child->flag_room = true;
flecs::entity room_e = region_e;
int room = room_e.get<WorldEditor::components::
buildings_layout_room>()
->room_type;
bool special = BuildingLayoutGraph::get_singleton()
->get_room_type_property(
room, "special");
child->flag_special = special;
child->room_type = room;
} else
child->flag_room = false;
children.push_back(child);
base_rtree->dump(grid_floor_e);
flecs::log::dbg(
@@ -107,10 +130,12 @@ void region_tree::dump(flecs::entity grid_floor_e) const
void region_tree::grow(flecs::entity grid_floor_e, bool limited)
{
List<struct region_tree *> grow_list;
List<struct region_tree *> special_grow_list;
List<struct region_tree *> queue;
List<struct region_tree *>::Element *e, *e1;
const struct region_tree *base_rtree = grid_floor_e.get<region_tree>();
assert(base_rtree);
make_random r(11365);
#ifdef TESTS
flecs::log::warn("grow");
#endif
@@ -118,15 +143,27 @@ void region_tree::grow(flecs::entity grid_floor_e, bool limited)
queue.push_back(this);
else
flecs::log::warn("incomplete");
flecs::entity room_c = grid_floor_e.world().lookup(
"::graph_module::buildings_layout_room");
assert(room_c.is_valid());
while (!queue.empty()) {
int i;
struct region_tree *item = queue.front()->get();
queue.pop_front();
if (item->region.can_grow || item->region.can_grow_square)
continue;
/* special treatment for enterance */
for (i = 0; i < (int)item->children.size(); i++) {
if (item->children[i]->region.can_grow)
grow_list.push_back(item->children[i]);
if (item->children[i]->region.can_grow) {
if (item->children[i]->is_a_room() &&
item->children[i]->is_special() &&
item->children[i]->room_type == 304 &&
false)
special_grow_list.push_back(
item->children[i]);
else
grow_list.push_back(item->children[i]);
}
queue.push_back(item->children[i]);
}
}
@@ -140,6 +177,73 @@ void region_tree::grow(flecs::entity grid_floor_e, bool limited)
return hash_one_uint64((uint64_t)ptr);
}
};
while (1) {
e = special_grow_list.front();
int count = 0;
int bad_count = 0;
int variant = 0;
while (e) {
struct region_tree *item = e->get();
if (!item->region.can_move) {
e = e->next();
continue;
}
struct region backup = item->region;
RegionRect2i parent_rect = item->parent->region.rect;
switch (variant) {
case 0:
item->region.rect.position.x =
parent_rect.position.x +
parent_rect.size.x - 1;
break;
case 1:
item->region.rect.position.x =
parent_rect.position.x;
break;
case 2:
item->region.rect.position.y =
parent_rect.position.y +
parent_rect.size.y - 1;
break;
case 3:
item->region.rect.position.y =
parent_rect.position.y;
break;
}
if (variant > 3) {
do {
item->region.rect.position.x =
parent_rect.position.x +
r.get() % (parent_rect.size.x -
1);
item->region.rect.position.y =
parent_rect.position.y +
r.get() % (parent_rect.size.y -
1);
} while (!base_rtree->check(grid_floor_e));
bad_count++;
assert(bad_count < 100);
variant = 0;
continue;
}
if (!base_rtree->check(grid_floor_e)) {
item->region = backup;
variant++;
continue;
} else {
item->region.can_move = false;
item->region.can_grow_square = false;
item->region.can_grow = false;
grow_list.push_back(item);
e = e->next();
count++;
bad_count = 0;
continue;
}
}
if (count == 0)
break;
}
HashMap<struct region_tree *, int, pointer_hasher> state;
while (1) {
e = grow_list.front();
@@ -271,10 +375,10 @@ bool region_tree::check(flecs::entity grid_floor_e) const
int i, j;
if (children.size() == 0)
return true;
int grid_size = grid_floor_e
.get<WorldEditor::components::
buildings_layout_grid_floor>()
->grid_size;
// int grid_size = grid_floor_e
// .get<WorldEditor::components::
// buildings_layout_grid_floor>()
// ->grid_size;
for (i = 0; i < children.size(); i++)
root_regions.push_back(children[i]->region.rect);
flecs::log::dbg("root regions count: %d", root_regions.size());
@@ -582,9 +686,22 @@ void region_tree::get_leaf_nodes(List<struct region_tree *> *node_list)
bool region_tree::is_a_room(flecs::entity grid_floor_e) const
{
return grid_floor_e.world()
.entity(region.region_et)
.has<WorldEditor::components::buildings_layout_room>();
bool ret =
grid_floor_e.world()
.entity(region.region_et)
.has<WorldEditor::components::buildings_layout_room>();
assert(flag_room == ret);
return ret;
}
bool region_tree::is_a_room() const
{
return flag_room;
}
bool region_tree::is_special() const
{
return flag_special;
}
bool region_tree::check_candidate(int i, const RegionRect2i &candidate) const
@@ -637,7 +754,7 @@ flecs::entity region_tree::update_cell(flecs::entity grid_floor_e,
flecs::entity_t region_et, int id) const
{
flecs::entity region_e = grid_floor_e.world().entity(region_et);
flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
// flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
flecs::log::dbg("create_cell: %s %d", region_e.path().c_str(), id);
String pname("cell_" + itos(id));
flecs::entity cell_e = grid_floor_e.lookup(pname.ascii().ptr());
@@ -684,7 +801,7 @@ flecs::entity region_tree::create_corridoor_cell(flecs::entity grid_floor_e,
int id) const
{
// flecs::entity region_e = grid_floor_e.world().entity(region_et);
flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
// flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
String pname("cell_" + itos(id));
flecs::entity cell_e = grid_floor_e.lookup(pname.ascii().ptr());
if (!cell_e.is_valid()) {
@@ -712,7 +829,7 @@ bool region_tree::check_cell(flecs::entity grid_floor_e,
flecs::entity_t region_et, int id) const
{
flecs::entity region_e = grid_floor_e.world().entity(region_et);
flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
// flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
flecs::log::dbg("check_cell: %s %d", region_e.path().c_str(), id);
String pname("cell_" + itos(id));
flecs::entity cell_e = grid_floor_e.lookup(pname.ascii().ptr());

View File

@@ -6,6 +6,10 @@ struct region_tree {
struct region region;
Vector<struct region_tree *> children;
struct region_tree *parent;
bool flag_room;
bool flag_special;
int room_type;
void split(flecs::entity grid_floor_e,
const List<struct region> &regions);
const struct region_tree *find(flecs::entity_t which) const;
@@ -23,6 +27,8 @@ struct region_tree {
void get_leaf_nodes(List<const struct region_tree *> *node_list) const;
void get_leaf_nodes(List<struct region_tree *> *node_list);
bool is_a_room(flecs::entity grid_floor_e) const;
bool is_a_room() const;
bool is_special() const;
private:
bool check_candidate(int i, const RegionRect2i &candidate) const;