Now generating layouts with corridoors
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -18,7 +18,8 @@ public = [
|
|||||||
[308, "Cellar", { "window": true }],
|
[308, "Cellar", { "window": true }],
|
||||||
[309, "Office", { "window": true }],
|
[309, "Office", { "window": true }],
|
||||||
[310, "Server Room", { "window": true }],
|
[310, "Server Room", { "window": true }],
|
||||||
[311, "Room", { "window": true }]
|
[311, "Room", { "window": true }],
|
||||||
|
[312, "Studio", { "window": true }]
|
||||||
]
|
]
|
||||||
parts_library_path = "res://astream/building-layouts/building-elements-v2.glb"
|
parts_library_path = "res://astream/building-layouts/building-elements-v2.glb"
|
||||||
[commands]
|
[commands]
|
||||||
@@ -33,3 +34,96 @@ commands = [
|
|||||||
[7, "PopPosition"]
|
[7, "PopPosition"]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
; private rooms
|
||||||
|
|
||||||
|
[rooms/200]
|
||||||
|
name = "WC"
|
||||||
|
window = false
|
||||||
|
grow = false
|
||||||
|
private = true
|
||||||
|
|
||||||
|
[rooms/201]
|
||||||
|
name = "Bathroom"
|
||||||
|
window = false
|
||||||
|
grow = false
|
||||||
|
private = true
|
||||||
|
|
||||||
|
[rooms/202]
|
||||||
|
name = "Bedroom"
|
||||||
|
private = true
|
||||||
|
|
||||||
|
[rooms/203]
|
||||||
|
name = "Holding Cell"
|
||||||
|
window = false
|
||||||
|
private = true
|
||||||
|
|
||||||
|
[rooms/204]
|
||||||
|
name = "Dormitory"
|
||||||
|
private = true
|
||||||
|
|
||||||
|
[rooms/205]
|
||||||
|
name = "Torture Room"
|
||||||
|
window = false
|
||||||
|
private = true
|
||||||
|
|
||||||
|
|
||||||
|
; public rooms
|
||||||
|
|
||||||
|
[rooms/300]
|
||||||
|
name = "Living Room"
|
||||||
|
|
||||||
|
[rooms/301]
|
||||||
|
name = "Family Room"
|
||||||
|
|
||||||
|
[rooms/302]
|
||||||
|
name = "Kitchen"
|
||||||
|
|
||||||
|
[rooms/303]
|
||||||
|
name = "Dining Room"
|
||||||
|
|
||||||
|
[rooms/304]
|
||||||
|
name = "Enterance"
|
||||||
|
wall = true
|
||||||
|
window = false
|
||||||
|
special = true
|
||||||
|
|
||||||
|
[rooms/305]
|
||||||
|
name = "Stair"
|
||||||
|
window = false
|
||||||
|
special = true
|
||||||
|
|
||||||
|
[rooms/306]
|
||||||
|
name = "Elevator"
|
||||||
|
window = false
|
||||||
|
special = true
|
||||||
|
|
||||||
|
[rooms/307]
|
||||||
|
name = "Storage Room"
|
||||||
|
|
||||||
|
[rooms/308]
|
||||||
|
name = "Cellar"
|
||||||
|
window = false
|
||||||
|
|
||||||
|
[rooms/309]
|
||||||
|
name = "Office"
|
||||||
|
|
||||||
|
[rooms/310]
|
||||||
|
name = "Server Room"
|
||||||
|
|
||||||
|
[rooms/311]
|
||||||
|
name = "Room"
|
||||||
|
|
||||||
|
[rooms/312]
|
||||||
|
name = "Studio"
|
||||||
|
|
||||||
|
[rooms/313]
|
||||||
|
name = "General Store"
|
||||||
|
|
||||||
|
[rooms/default]
|
||||||
|
name = "Unknown Room"
|
||||||
|
wall = false
|
||||||
|
window = true
|
||||||
|
grow = true
|
||||||
|
private = false
|
||||||
|
special = false
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ BuildingLayoutGraph::BuildingLayoutGraph()
|
|||||||
ecs.import <growth_module>();
|
ecs.import <growth_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());
|
|
||||||
private_rooms = config.get_value("rooms", "private", Array());
|
|
||||||
load_layouts();
|
load_layouts();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,35 +37,6 @@ BuildingLayoutGraph *BuildingLayoutGraph::get_singleton()
|
|||||||
return singleton;
|
return singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingLayoutGraph::get_room_data(int id, Array &result)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Array rooms;
|
|
||||||
rooms.append_array(private_rooms);
|
|
||||||
rooms.append_array(public_rooms);
|
|
||||||
int index = -1;
|
|
||||||
for (i = 0; i < rooms.size(); i++) {
|
|
||||||
Array room_data = rooms[i];
|
|
||||||
int room_id = room_data[0];
|
|
||||||
if (room_id == id) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Array room = rooms[index];
|
|
||||||
result = room;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Array &BuildingLayoutGraph::get_private_rooms() const
|
|
||||||
{
|
|
||||||
return private_rooms;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Array &BuildingLayoutGraph::get_public_rooms() const
|
|
||||||
{
|
|
||||||
return public_rooms;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildingLayoutGraph::destroy_graph_entity(const String &path)
|
void BuildingLayoutGraph::destroy_graph_entity(const String &path)
|
||||||
{
|
{
|
||||||
flecs::world ecs = BaseData::get_singleton()->get();
|
flecs::world ecs = BaseData::get_singleton()->get();
|
||||||
@@ -301,25 +270,19 @@ void BuildingLayoutGraph::get_menu_entries(flecs::entity e,
|
|||||||
int zone_type =
|
int zone_type =
|
||||||
e.get<WorldEditor::components::buildings_layout_zone>()
|
e.get<WorldEditor::components::buildings_layout_zone>()
|
||||||
->type;
|
->type;
|
||||||
if (zone_type == 0) {
|
for (i = 0; i < 10000; i++) {
|
||||||
const Array &private_rooms = get_private_rooms();
|
if (config.has_section("rooms/" + itos(i))) {
|
||||||
for (i = 0; i < private_rooms.size(); i++) {
|
String room_name = config.get_value(
|
||||||
Array room_data = private_rooms[i];
|
"rooms/" + itos(i), "name",
|
||||||
int id = room_data[0];
|
"Invalid Room");
|
||||||
String room_name = room_data[1];
|
bool private_room = config.get_value(
|
||||||
Pair<int, String> item(
|
"rooms/" + itos(i), "private", false);
|
||||||
{ id, "Create " + room_name });
|
if ((private_room && zone_type == 0) ||
|
||||||
list->push_back(item);
|
(!private_room && zone_type == 1)) {
|
||||||
}
|
Pair<int, String> item(
|
||||||
} else if (zone_type == 1) {
|
{ i, "Create " + room_name });
|
||||||
const Array &public_rooms = get_public_rooms();
|
list->push_back(item);
|
||||||
for (i = 0; i < public_rooms.size(); i++) {
|
}
|
||||||
Array room_data = public_rooms[i];
|
|
||||||
int id = room_data[0];
|
|
||||||
String room_name = room_data[1];
|
|
||||||
Pair<int, String> item(
|
|
||||||
{ id, "Create " + room_name });
|
|
||||||
list->push_back(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ class BuildingLayoutGraph {
|
|||||||
BuildingLayoutGraph();
|
BuildingLayoutGraph();
|
||||||
|
|
||||||
ConfigFile config;
|
ConfigFile config;
|
||||||
Array public_rooms;
|
|
||||||
Array private_rooms;
|
|
||||||
|
|
||||||
flecs::entity create_graph_entity(const String &base_path,
|
flecs::entity create_graph_entity(const String &base_path,
|
||||||
const String &entity_type);
|
const String &entity_type);
|
||||||
@@ -20,9 +18,8 @@ public:
|
|||||||
memdelete(singleton);
|
memdelete(singleton);
|
||||||
singleton = nullptr;
|
singleton = nullptr;
|
||||||
}
|
}
|
||||||
void get_room_data(int id, Array &result);
|
bool has_room_type(int id) const;
|
||||||
const Array &get_private_rooms() const;
|
Variant get_room_type_property(int id, const String &property) const;
|
||||||
const Array &get_public_rooms() const;
|
|
||||||
void create_zone(const String &base_path, int zone_type);
|
void create_zone(const String &base_path, int zone_type);
|
||||||
void create_unit(const String &base_path);
|
void create_unit(const String &base_path);
|
||||||
void create_floor(const String &base_path);
|
void create_floor(const String &base_path);
|
||||||
|
|||||||
@@ -192,255 +192,11 @@ void graph_module::create_floor_components(
|
|||||||
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
void growth_regions::create_region(flecs::entity floor_e, flecs::entity seed_e,
|
|
||||||
flecs::entity parent_e,
|
|
||||||
flecs::entity region_e,
|
|
||||||
const Vector2i &position, float area,
|
|
||||||
int parent_index)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct growth_regions::region r;
|
|
||||||
r.parent = parent_e.id();
|
|
||||||
r.seed_et = seed_e.id();
|
|
||||||
r.region_et = region_e.id();
|
|
||||||
r.rect.position = position;
|
|
||||||
r.rect.size = Vector2i(1, 1);
|
|
||||||
r.remains_area = MAX((int)(area * 2.0f) / 16 + 1, 16);
|
|
||||||
r.can_grow_square = true;
|
|
||||||
r.can_grow = true;
|
|
||||||
r.complete = false;
|
|
||||||
r.parent_region = parent_index;
|
|
||||||
flecs::log::dbg("create region %s in %s",
|
|
||||||
(r.rect.operator String()).ascii().ptr(),
|
|
||||||
(parent_regions[parent_index].rect.operator String())
|
|
||||||
.ascii()
|
|
||||||
.ptr());
|
|
||||||
assert(parent_regions[parent_index].rect.encloses(r.rect));
|
|
||||||
bool ok = true;
|
|
||||||
assert(check_region(-1, r.rect));
|
|
||||||
const struct growth_regions *reg = floor_e.get<growth_regions>();
|
|
||||||
for (i = 0; i < reg->regions.size(); i++) {
|
|
||||||
if (reg->regions[i].region_et == r.region_et) {
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (reg->regions[i].rect.position == r.rect.position) {
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r.remains_area -= 1;
|
|
||||||
assert(ok);
|
|
||||||
if (ok) {
|
|
||||||
floor_e.get_mut<growth_regions>()->complete = false;
|
|
||||||
floor_e.get_mut<growth_regions>()->regions.push_back(r);
|
|
||||||
floor_e.modified<growth_regions>();
|
|
||||||
flecs::log::warn("region created for %s",
|
|
||||||
region_e.path().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
flecs::entity growth_regions::create_cell(flecs::entity floor_e,
|
|
||||||
flecs::entity region_e, int id)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
flecs::entity ret;
|
|
||||||
flecs::log::dbg("create_cell: %s %d", region_e.path().c_str(), id);
|
|
||||||
if (floor_e.get<WorldEditor::components::buildings_layout_grid_floor>()
|
|
||||||
->cells.has(id)) {
|
|
||||||
flecs::log::err("cell %d already exists", id);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
String pname("cell_" + itos(id));
|
|
||||||
flecs::entity cell_e = floor_e.lookup(pname.ascii().ptr());
|
|
||||||
if (cell_e.is_valid())
|
|
||||||
flecs::log::err("cell %d already exists", id);
|
|
||||||
assert(!cell_e.is_valid());
|
|
||||||
cell_e = floor_e.world().entity(pname.ascii().ptr()).child_of(floor_e);
|
|
||||||
floor_e.get_mut<WorldEditor::components::buildings_layout_grid_floor>()
|
|
||||||
->cells.insert(id);
|
|
||||||
floor_e.get_mut<WorldEditor::components::buildings_layout_grid_floor>()
|
|
||||||
->size_left--;
|
|
||||||
floor_e.modified<WorldEditor::components::buildings_layout_grid_floor>();
|
|
||||||
if (cell_e.is_valid()) {
|
|
||||||
cell_e.set<WorldEditor::components::buildings_layout_grid_cell>(
|
|
||||||
{ String(region_e.name()), id });
|
|
||||||
cell_e.add<WorldEditor::components::belongs>(region_e);
|
|
||||||
if (region_e.has<
|
|
||||||
WorldEditor::components::buildings_layout_room>()) {
|
|
||||||
int mcount = 0;
|
|
||||||
cell_e.each<WorldEditor::components::belongs_room>(
|
|
||||||
[&mcount, region_e](flecs::entity e) {
|
|
||||||
if (e.id() != region_e.id())
|
|
||||||
assert(false);
|
|
||||||
mcount++;
|
|
||||||
});
|
|
||||||
if (mcount == 0)
|
|
||||||
cell_e.add<WorldEditor::components::belongs_room>(
|
|
||||||
region_e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cell_e;
|
|
||||||
}
|
|
||||||
flecs::entity growth_regions::update_cell(flecs::entity floor_e,
|
|
||||||
flecs::entity parent_e,
|
|
||||||
flecs::entity region_e, int id)
|
|
||||||
{
|
|
||||||
flecs::log::dbg("create_cell: %s %d", region_e.path().c_str(), id);
|
|
||||||
String pname("cell_" + itos(id));
|
|
||||||
flecs::entity cell_e = floor_e.lookup(pname.ascii().ptr());
|
|
||||||
if (!cell_e.is_valid()) {
|
|
||||||
flecs::log::warn("creating new cell %s", cell_e.path());
|
|
||||||
cell_e = floor_e.world()
|
|
||||||
.entity(pname.ascii().ptr())
|
|
||||||
.child_of(floor_e);
|
|
||||||
assert(cell_e.is_valid());
|
|
||||||
}
|
|
||||||
// assert(cell_e.has<WorldEditor::components::belongs>(parent_e));
|
|
||||||
/* already there */
|
|
||||||
floor_e.get_mut<WorldEditor::components::buildings_layout_grid_floor>()
|
|
||||||
->cells.insert(id);
|
|
||||||
floor_e.modified<WorldEditor::components::buildings_layout_grid_floor>();
|
|
||||||
cell_e.set<WorldEditor::components::buildings_layout_grid_cell>(
|
|
||||||
{ String(region_e.name()), id });
|
|
||||||
cell_e.remove<WorldEditor::components::belongs>(parent_e);
|
|
||||||
cell_e.add<WorldEditor::components::belongs>(region_e);
|
|
||||||
if (region_e.has<WorldEditor::components::buildings_layout_room>()) {
|
|
||||||
int mcount = 0;
|
|
||||||
cell_e.each<WorldEditor::components::belongs_room>(
|
|
||||||
[&mcount, region_e, cell_e](flecs::entity e) {
|
|
||||||
flecs::log::err("adding region %s to cell %s",
|
|
||||||
region_e.path().c_str(),
|
|
||||||
cell_e.path().c_str());
|
|
||||||
flecs::log::err("already belongs to %s",
|
|
||||||
e.path().c_str());
|
|
||||||
assert(mcount == 0);
|
|
||||||
assert(region_e.id() == e.id());
|
|
||||||
mcount++;
|
|
||||||
});
|
|
||||||
if (mcount == 0)
|
|
||||||
cell_e.add<WorldEditor::components::belongs_room>(
|
|
||||||
region_e);
|
|
||||||
}
|
|
||||||
return cell_e;
|
|
||||||
}
|
|
||||||
static inline int int_distance(const Vector2i &v1, const Vector2i &v2)
|
static inline int int_distance(const Vector2i &v1, const Vector2i &v2)
|
||||||
{
|
{
|
||||||
Vector2i l = v2 - v1;
|
Vector2i l = v2 - v1;
|
||||||
return l.x * l.x + l.y * l.y;
|
return l.x * l.x + l.y * l.y;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
void growth_regions::split_region(
|
|
||||||
flecs::entity grid_floor_e, int region_index,
|
|
||||||
const List<Pair<flecs::entity, float> > ®ion_list)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
struct make_random r(173);
|
|
||||||
int grid_size = grid_floor_e
|
|
||||||
.get<WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor>()
|
|
||||||
->grid_size;
|
|
||||||
growth_regions::region parent_region = regions[region_index];
|
|
||||||
// can't split rooms
|
|
||||||
assert(!grid_floor_e.world()
|
|
||||||
.entity(parent_region.region_et)
|
|
||||||
.has<WorldEditor::components::buildings_layout_room>());
|
|
||||||
regions.remove(region_index);
|
|
||||||
RegionRect2i clip_rect = parent_region.rect;
|
|
||||||
int parent_region_index = parent_regions.size();
|
|
||||||
parent_regions.push_back(parent_region);
|
|
||||||
flecs::log::warn("moved parent region %d", region_index);
|
|
||||||
assert(clip_rect.get_area() > region_list.size());
|
|
||||||
const List<Pair<flecs::entity, float> >::Element *e =
|
|
||||||
region_list.front();
|
|
||||||
Set<Vector2i> positions;
|
|
||||||
LocalVector<Pair<flecs::entity, Vector2i> > new_start;
|
|
||||||
int base_index = 0;
|
|
||||||
while (e) {
|
|
||||||
Vector2i pos;
|
|
||||||
int iterations = 1000;
|
|
||||||
while (1) {
|
|
||||||
int i;
|
|
||||||
pos = clip_rect.position +
|
|
||||||
Vector2i(r.get() % clip_rect.size.x,
|
|
||||||
r.get() % clip_rect.size.y);
|
|
||||||
assert(clip_rect.has_point(pos));
|
|
||||||
if (!positions.has(pos)) {
|
|
||||||
bool ok = true;
|
|
||||||
for (i = 0; i < (int)new_start.size(); i++) {
|
|
||||||
if (iterations < 100 &&
|
|
||||||
int_distance(new_start[i].second,
|
|
||||||
pos) < 2) {
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (iterations < 200 &&
|
|
||||||
int_distance(new_start[i].second,
|
|
||||||
pos) < 1) {
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ok) {
|
|
||||||
positions.insert(pos);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iterations--;
|
|
||||||
if (iterations < 0) {
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < regions.size(); i++) {
|
|
||||||
if (parent_region_index == regions[i].parent_region)
|
|
||||||
flecs::log::dbg(
|
|
||||||
"sibling regions: %d: %s", i,
|
|
||||||
(regions[i].rect.operator String())
|
|
||||||
.ascii()
|
|
||||||
.ptr());
|
|
||||||
}
|
|
||||||
flecs::log::dbg("cell: position: %d, %d", pos.x, pos.y);
|
|
||||||
for (i = 0; i < regions.size(); i++)
|
|
||||||
assert(parent_regions[regions[i].parent_region]
|
|
||||||
.rect.encloses(regions[i].rect));
|
|
||||||
for (i = 0; i < regions.size(); i++)
|
|
||||||
for (j = 0; j < regions.size(); j++) {
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
if (regions[i].rect.encloses(regions[j].rect) ||
|
|
||||||
regions[j].rect.intersects(
|
|
||||||
regions[i].rect) ||
|
|
||||||
regions[i].rect.intersects(regions[j].rect))
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
assert(parent_region.rect.has_point(pos));
|
|
||||||
struct region reg;
|
|
||||||
new_start.push_back({ e->get().first, pos });
|
|
||||||
reg.can_grow = true;
|
|
||||||
reg.can_grow_square = true;
|
|
||||||
reg.complete = false;
|
|
||||||
reg.parent = parent_region.region_et;
|
|
||||||
reg.parent_region = parent_region_index;
|
|
||||||
reg.rect = RegionRect2i(pos, Vector2i(1, 1));
|
|
||||||
reg.region_et = e->get().first.id();
|
|
||||||
reg.remains_area = (int)Math::ceil(e->get().second);
|
|
||||||
int cell_id = pos.x + grid_size * pos.y;
|
|
||||||
flecs::entity parent_e =
|
|
||||||
grid_floor_e.world().entity(reg.parent);
|
|
||||||
flecs::entity cell_e = update_cell(grid_floor_e, parent_e,
|
|
||||||
e->get().first, cell_id);
|
|
||||||
reg.seed_et = cell_e.id();
|
|
||||||
regions.push_back(reg);
|
|
||||||
e = e->next();
|
|
||||||
base_index++;
|
|
||||||
complete = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void graph_module::zones_graph_module(flecs::world &ecs,
|
void graph_module::zones_graph_module(flecs::world &ecs,
|
||||||
const String &module_name)
|
const String &module_name)
|
||||||
{
|
{
|
||||||
@@ -629,8 +385,27 @@ void graph_module::zones_graph_module(flecs::world &ecs,
|
|||||||
buildings_layout_floor_index
|
buildings_layout_floor_index
|
||||||
&rindex) {
|
&rindex) {
|
||||||
if (index.index == rindex.index) {
|
if (index.index == rindex.index) {
|
||||||
sum += MAX(rarea.area, MIN_ROOM_SIZE) *
|
int rsize = (int)Math::sqrt(rarea.area /
|
||||||
10 / 8;
|
16.0f) +
|
||||||
|
1;
|
||||||
|
bool priv =
|
||||||
|
BuildingLayoutGraph::get_singleton()
|
||||||
|
->get_room_type_property(
|
||||||
|
r.room_type,
|
||||||
|
"private");
|
||||||
|
bool window =
|
||||||
|
BuildingLayoutGraph::get_singleton()
|
||||||
|
->get_room_type_property(
|
||||||
|
r.room_type,
|
||||||
|
"window");
|
||||||
|
RegionRect2i xr(0, 0, rsize, rsize);
|
||||||
|
if (priv && !window)
|
||||||
|
xr = xr.grow(2);
|
||||||
|
else
|
||||||
|
xr = xr.grow(1);
|
||||||
|
int xarea = xr.size.x * xr.size.y * 16;
|
||||||
|
sum += MAX(xarea, MIN_ROOM_SIZE) * 10 /
|
||||||
|
8;
|
||||||
assert(sum >= 0.0f);
|
assert(sum >= 0.0f);
|
||||||
count_rooms++;
|
count_rooms++;
|
||||||
}
|
}
|
||||||
@@ -1380,6 +1155,22 @@ BuildingLayoutGraph::create_graph_entity(const String &base_path,
|
|||||||
return new_e;
|
return new_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BuildingLayoutGraph::has_room_type(int id) const
|
||||||
|
{
|
||||||
|
return (config.has_section("rooms/" + itos(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant
|
||||||
|
BuildingLayoutGraph::get_room_type_property(int id,
|
||||||
|
const String &property) const
|
||||||
|
{
|
||||||
|
assert(has_room_type(id));
|
||||||
|
Variant ret = config.get_value("rooms/" + itos(id), property,
|
||||||
|
config.get_value("rooms/default",
|
||||||
|
property, Variant()));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void BuildingLayoutGraph::create_zone(const String &base_path, int zone_type)
|
void BuildingLayoutGraph::create_zone(const String &base_path, int zone_type)
|
||||||
{
|
{
|
||||||
flecs::entity new_e = create_graph_entity(base_path, "zone");
|
flecs::entity new_e = create_graph_entity(base_path, "zone");
|
||||||
@@ -1416,11 +1207,13 @@ void BuildingLayoutGraph::create_floor(const String &base_path)
|
|||||||
void BuildingLayoutGraph::create_room(const String &base_path, int id)
|
void BuildingLayoutGraph::create_room(const String &base_path, int id)
|
||||||
{
|
{
|
||||||
Array room;
|
Array room;
|
||||||
BuildingLayoutGraph::get_singleton()->get_room_data(id, room);
|
assert(config.has_section("rooms/" + itos(id)));
|
||||||
assert(!room.empty());
|
bool window = config.get_value("rooms/" + itos(id), "window",
|
||||||
String type_name = room[1];
|
config.get_value("rooms/default",
|
||||||
Dictionary room_options = room[2];
|
"window", true));
|
||||||
bool window = room_options.get("window", false);
|
String type_name = config.get_value(
|
||||||
|
"rooms/" + itos(id), "name",
|
||||||
|
config.get_value("rooms/default", "name", "Unknown"));
|
||||||
type_name = type_name.replace(" ", "_").to_lower();
|
type_name = type_name.replace(" ", "_").to_lower();
|
||||||
flecs::entity new_e = create_graph_entity(base_path, type_name);
|
flecs::entity new_e = create_graph_entity(base_path, type_name);
|
||||||
new_e.set<WorldEditor::components::buildings_layout_room>(
|
new_e.set<WorldEditor::components::buildings_layout_room>(
|
||||||
|
|||||||
@@ -63,56 +63,6 @@ out:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void grid_misc::place_regions(flecs::entity grid_floor_e)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int grid_size = grid_floor_e
|
|
||||||
.get<WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor>()
|
|
||||||
->grid_size;
|
|
||||||
// flecs::log::dbg("###=== %s", grid_floor_e.path().c_str());
|
|
||||||
flecs::entity grid_e = grid_floor_e.parent();
|
|
||||||
assert(grid_e.is_valid());
|
|
||||||
growth_regions::region parent_reg;
|
|
||||||
parent_reg.can_grow = false;
|
|
||||||
parent_reg.complete = true;
|
|
||||||
parent_reg.rect.position = Vector2i();
|
|
||||||
parent_reg.rect.size = Vector2i(grid_size, grid_size);
|
|
||||||
parent_reg.can_grow_square = false;
|
|
||||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
|
||||||
int parent_index = g->parent_regions.size();
|
|
||||||
g->parent_regions.push_back(parent_reg);
|
|
||||||
for (i = 0; i < (int)positions.size(); i++) {
|
|
||||||
int cell_id = positions[i].second.x +
|
|
||||||
grid_size * positions[i].second.y;
|
|
||||||
flecs::entity region_e =
|
|
||||||
grid_e.world().entity(positions[i].first);
|
|
||||||
assert(region_e.is_valid());
|
|
||||||
Rect2i check;
|
|
||||||
check.position = positions[i].second;
|
|
||||||
check.size = Vector2i(1, 1);
|
|
||||||
// flecs::log::dbg("%s ->region: %s cell_id %d",
|
|
||||||
// grid_floor_e.path().c_str(),
|
|
||||||
// region_e.path().c_str(), cell_id);
|
|
||||||
assert(g->check_region(-1, check));
|
|
||||||
flecs::entity cell_e =
|
|
||||||
g->create_cell(grid_floor_e, region_e, cell_id);
|
|
||||||
assert(cell_e.is_valid());
|
|
||||||
flecs::log::warn("grid cell: %s", cell_e.path().c_str());
|
|
||||||
float area = get_entity_area(region_e);
|
|
||||||
// flecs::log::dbg("region: %s: parent: %s",
|
|
||||||
// region_e.path().c_str(),
|
|
||||||
// region_e.parent().path().c_str());
|
|
||||||
g->create_region(grid_floor_e, cell_e, region_e.parent(),
|
|
||||||
region_e, positions[i].second, area,
|
|
||||||
parent_index);
|
|
||||||
flecs::log::warn("grid cell: %s", cell_e.path().c_str());
|
|
||||||
}
|
|
||||||
// flecs::log::dbg("###=== %s done", grid_floor_e.path().c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
void grid_misc::place_regions_common(flecs::entity parent_e,
|
void grid_misc::place_regions_common(flecs::entity parent_e,
|
||||||
@@ -396,36 +346,6 @@ void grid_misc::filter_candidates(flecs::entity ce, float area,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
void grid_misc::place_region_cells(
|
|
||||||
flecs::entity grid_floor_e,
|
|
||||||
const WorldEditor::components::buildings_layout_grid_floor &fl,
|
|
||||||
growth_regions &g)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < g.regions.size(); i++) {
|
|
||||||
int x, y;
|
|
||||||
RegionRect2i rect = g.regions[i].rect;
|
|
||||||
for (x = rect.position.x; x <= rect.position.x + rect.size.x;
|
|
||||||
x++)
|
|
||||||
for (y = rect.position.y;
|
|
||||||
y <= rect.position.y + rect.size.y; y++) {
|
|
||||||
int id = x + fl.grid_size * y;
|
|
||||||
if (!fl.cells.has(id)) {
|
|
||||||
flecs::entity seed_e =
|
|
||||||
grid_floor_e.world().entity(
|
|
||||||
g.regions[i].seed_et);
|
|
||||||
assert(seed_e.is_valid());
|
|
||||||
assert(seed_e.parent().is_valid());
|
|
||||||
assert(seed_e.parent().id() ==
|
|
||||||
grid_floor_e.id());
|
|
||||||
queue_grow_cell(seed_e, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void grid_misc::queue_grow_cell(flecs::entity seed_e, int id)
|
void grid_misc::queue_grow_cell(flecs::entity seed_e, int id)
|
||||||
{
|
{
|
||||||
assert(seed_e.is_valid());
|
assert(seed_e.is_valid());
|
||||||
@@ -455,220 +375,6 @@ void grid_misc::queue_grow_cell(flecs::entity seed_e, int id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void grid_misc::print_can_grow(int state, growth_regions &g, int index,
|
|
||||||
const char *what)
|
|
||||||
{
|
|
||||||
const growth_regions::region ®ion = g.regions[index];
|
|
||||||
bool can = false;
|
|
||||||
if (!strcmp(what, "square"))
|
|
||||||
can = region.can_grow_square;
|
|
||||||
else if (!strcmp(what, "rect"))
|
|
||||||
can = region.can_grow;
|
|
||||||
|
|
||||||
if (can)
|
|
||||||
flecs::log::dbg(
|
|
||||||
"state: %d: index %d: region can still grow %s %d",
|
|
||||||
state, index, what, region.remains_area);
|
|
||||||
else
|
|
||||||
flecs::log::dbg("state: %d: index %d: region can't grow %s %d",
|
|
||||||
state, index, what, region.remains_area);
|
|
||||||
if (region.can_grow_region())
|
|
||||||
flecs::log::dbg("state %d: index %d: region can still continue",
|
|
||||||
state, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool grid_misc::grow_state0(growth_regions &g, int index,
|
|
||||||
const RegionRect2i &clip)
|
|
||||||
{
|
|
||||||
bool ok = true, ret = false;
|
|
||||||
RegionRect2i mrect;
|
|
||||||
growth_regions::region ®ion = g.regions.write[index];
|
|
||||||
mrect = region.rect;
|
|
||||||
assert(g.check_region(index, mrect));
|
|
||||||
|
|
||||||
mrect = mrect.grow(1);
|
|
||||||
ok = clip.encloses(mrect);
|
|
||||||
// if (!ok)
|
|
||||||
// flecs::log::dbg("state: %d: index %d: out of clip area",
|
|
||||||
// 0, index);
|
|
||||||
if (ok) {
|
|
||||||
ok = g.check_region(index, mrect);
|
|
||||||
// if (!ok)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state: %d: index %d: check_region failed",
|
|
||||||
// 0, index);
|
|
||||||
}
|
|
||||||
if (ok) {
|
|
||||||
ret = region.update_region_size(mrect);
|
|
||||||
// if (!ret)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state: %d: index %d: update_region_size failed",
|
|
||||||
// 0, index);
|
|
||||||
}
|
|
||||||
print_can_grow(0, g, index, "square");
|
|
||||||
// if (!ret)
|
|
||||||
// flecs::log::dbg("state %d could not grow region %d: %d",
|
|
||||||
// 0, index, region.remains_area);
|
|
||||||
// else
|
|
||||||
// flecs::log::dbg("state %d could grow region %d: %d", 0,
|
|
||||||
// index, region.remains_area);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
bool grid_misc::grow_state1(growth_regions &g, int index,
|
|
||||||
const RegionRect2i &clip)
|
|
||||||
{
|
|
||||||
int d;
|
|
||||||
bool ret = false;
|
|
||||||
RegionRect2i mrect;
|
|
||||||
growth_regions::region ®ion = g.regions.write[index];
|
|
||||||
int count = 0;
|
|
||||||
for (d = 0; d < 4; d++) {
|
|
||||||
bool ok;
|
|
||||||
mrect = region.rect;
|
|
||||||
assert(g.check_region(index, mrect));
|
|
||||||
switch (d) {
|
|
||||||
case 0:
|
|
||||||
mrect.position.y -= 1;
|
|
||||||
mrect.size.y += 1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mrect.size.y += 1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mrect.position.x -= 1;
|
|
||||||
mrect.size.x += 1;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mrect.size.x += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ok = g.parent_regions[region.parent_region].rect.encloses(
|
|
||||||
mrect);
|
|
||||||
if (ok)
|
|
||||||
ok = clip.encloses(mrect);
|
|
||||||
if (ok) {
|
|
||||||
ok = false;
|
|
||||||
if (mrect.size.y > 0 && mrect.size.x > 0) {
|
|
||||||
float aspect = (float)mrect.size.x /
|
|
||||||
(float)mrect.size.y;
|
|
||||||
ok = (aspect > 0.2f && aspect < 5.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ok)
|
|
||||||
ok = g.check_region(index, mrect);
|
|
||||||
if (ok) {
|
|
||||||
bool result = region.update_region_size(mrect);
|
|
||||||
if (result)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
ret = true;
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state %d could grow region %d: %d - %d out of %d times",
|
|
||||||
// 0, index, region.remains_area, count, 4);
|
|
||||||
}
|
|
||||||
print_can_grow(1, g, index, "rect");
|
|
||||||
// if (!ret)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state %d could not grow region rect %d: %d", 0,
|
|
||||||
// index, region.remains_area);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void grid_misc::grow_region_rects(
|
|
||||||
flecs::entity floor_e,
|
|
||||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
|
||||||
growth_regions &g)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool grown = true;
|
|
||||||
int state = 0;
|
|
||||||
if (g.complete)
|
|
||||||
return;
|
|
||||||
Rect2i clip(0, 0, fl.grid_size, fl.grid_size);
|
|
||||||
state = 0;
|
|
||||||
// flecs::log::dbg("growing square");
|
|
||||||
while (grown) {
|
|
||||||
grown = false;
|
|
||||||
int count = 0;
|
|
||||||
for (i = 0; i < g.regions.size(); i++) {
|
|
||||||
growth_regions::region ®ion = g.regions.write[i];
|
|
||||||
RegionRect2i mrect = region.rect;
|
|
||||||
// flecs::log::dbg("grow_region_rects: region %d",
|
|
||||||
// i);
|
|
||||||
if (!region.can_grow_region()) {
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "grow_region_rects: skip %d",
|
|
||||||
// i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mrect = region.rect;
|
|
||||||
bool result = false;
|
|
||||||
result = grow_state0(g, i, clip);
|
|
||||||
if (result)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
grown = true;
|
|
||||||
// flecs::log::dbg("grown squares %d times of %d",
|
|
||||||
// count, g.regions.size());
|
|
||||||
}
|
|
||||||
// if (!grown)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "grow_region_rects: could not grow more squares");
|
|
||||||
}
|
|
||||||
state = 1;
|
|
||||||
grown = true;
|
|
||||||
// flecs::log::dbg("growing rect");
|
|
||||||
while (grown) {
|
|
||||||
grown = false;
|
|
||||||
int count = 0;
|
|
||||||
for (i = 0; i < g.regions.size(); i++) {
|
|
||||||
growth_regions::region ®ion = g.regions.write[i];
|
|
||||||
RegionRect2i mrect = region.rect;
|
|
||||||
// flecs::log::dbg("grow_region_rects: region %d",
|
|
||||||
// i);
|
|
||||||
if (!region.can_grow_region()) {
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "grow_region_rects: skip %d",
|
|
||||||
// i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mrect = region.rect;
|
|
||||||
bool result = false;
|
|
||||||
result = grow_state1(g, i, clip);
|
|
||||||
if (result)
|
|
||||||
count++;
|
|
||||||
// if (!result)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state %d could not grow region %d",
|
|
||||||
// state, i);
|
|
||||||
// else
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state %d could grow region %d: %d",
|
|
||||||
// state, i, region.remains_area);
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
grown = true;
|
|
||||||
// flecs::log::dbg("grown rects %d times of %d",
|
|
||||||
// count, g.regions.size());
|
|
||||||
}
|
|
||||||
// if (!grown)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "grow_region_rects: could not grow any more rects");
|
|
||||||
}
|
|
||||||
flecs::log::dbg("grow_region_rects: complete");
|
|
||||||
g.complete = true;
|
|
||||||
flecs::log::dbg("grow_region_rects: %s: done", floor_e.path().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void grid_misc::subregions_init(flecs::world w)
|
void grid_misc::subregions_init(flecs::world w)
|
||||||
{
|
{
|
||||||
flecs::query<const WorldEditor::components::buildings_layout_area> qprep =
|
flecs::query<const WorldEditor::components::buildings_layout_area> qprep =
|
||||||
|
|||||||
@@ -177,16 +177,6 @@ struct grid_misc {
|
|||||||
const WorldEditor::components::buildings_layout_grid_floor &fl,
|
const WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||||
growth_regions &g);
|
growth_regions &g);
|
||||||
void queue_grow_cell(flecs::entity seed_e, int id);
|
void queue_grow_cell(flecs::entity seed_e, int id);
|
||||||
void print_can_grow(int state, growth_regions &g, int index,
|
|
||||||
const char *what);
|
|
||||||
bool grow_state0(growth_regions &g, int index,
|
|
||||||
const RegionRect2i &clip);
|
|
||||||
bool grow_state1(growth_regions &g, int index,
|
|
||||||
const RegionRect2i &clip);
|
|
||||||
void grow_region_rects(
|
|
||||||
flecs::entity floor_e,
|
|
||||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
|
||||||
growth_regions &g);
|
|
||||||
Vector<Pair<flecs::entity, flecs::entity_t> > all_items;
|
Vector<Pair<flecs::entity, flecs::entity_t> > all_items;
|
||||||
void subregions_init(flecs::world w);
|
void subregions_init(flecs::world w);
|
||||||
void get_subregions(flecs::entity parent,
|
void get_subregions(flecs::entity parent,
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ grow_job_queue::grow_job_queue(
|
|||||||
/* Unlimited growth for squares */
|
/* Unlimited growth for squares */
|
||||||
void grow_job_queue::job_initial(struct grow_job *job)
|
void grow_job_queue::job_initial(struct grow_job *job)
|
||||||
{
|
{
|
||||||
int i, j;
|
|
||||||
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
||||||
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
||||||
flecs::log::dbg("create: base_floor: %s", base_floor_e.path().c_str());
|
flecs::log::dbg("create: base_floor: %s", base_floor_e.path().c_str());
|
||||||
@@ -118,10 +117,15 @@ void grow_job_queue::job_initial(struct grow_job *job)
|
|||||||
grid_floor_e.set<region_tree>(
|
grid_floor_e.set<region_tree>(
|
||||||
{ { job->base_floor_id, job->base_floor_id, job->base_floor_id,
|
{ { job->base_floor_id, job->base_floor_id, job->base_floor_id,
|
||||||
clip_rect.grow(-1), grid_size * grid_size, false, false,
|
clip_rect.grow(-1), grid_size * grid_size, false, false,
|
||||||
true },
|
false, true },
|
||||||
Vector<struct region_tree *>(),
|
Vector<struct region_tree *>(),
|
||||||
nullptr });
|
nullptr });
|
||||||
struct region_tree *rtree = grid_floor_e.get_mut<region_tree>();
|
struct region_tree *rtree = grid_floor_e.get_mut<region_tree>();
|
||||||
|
flecs::log::dbg("region rect: %s",
|
||||||
|
(rtree->region.rect.operator String()).ascii().ptr());
|
||||||
|
assert(!rtree->region.can_grow);
|
||||||
|
assert(rtree->region.rect.size.x > 1 || rtree->region.rect.size.y > 1);
|
||||||
|
assert(rtree->region.rect.get_area() > subregions.size());
|
||||||
create_region_list(rtree, subregions, initial_regions);
|
create_region_list(rtree, subregions, initial_regions);
|
||||||
grid_floor_e.modified<region_tree>();
|
grid_floor_e.modified<region_tree>();
|
||||||
grid_floor_e.get_mut<region_tree>()->split(grid_floor_e,
|
grid_floor_e.get_mut<region_tree>()->split(grid_floor_e,
|
||||||
@@ -164,7 +168,6 @@ void grow_job_queue::job_initial(struct grow_job *job)
|
|||||||
}
|
}
|
||||||
void grow_job_queue::job_common(struct grow_job *job)
|
void grow_job_queue::job_common(struct grow_job *job)
|
||||||
{
|
{
|
||||||
int i, j;
|
|
||||||
make_random r(172);
|
make_random r(172);
|
||||||
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
||||||
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
||||||
@@ -173,8 +176,6 @@ void grow_job_queue::job_common(struct grow_job *job)
|
|||||||
flecs::entity parent_e = grid_e.world().entity(job->parent_id);
|
flecs::entity parent_e = grid_e.world().entity(job->parent_id);
|
||||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||||
const List<Pair<flecs::entity, float> > &subregions = job->subregions;
|
const List<Pair<flecs::entity, float> > &subregions = job->subregions;
|
||||||
const List<Pair<flecs::entity, float> >::Element *fe =
|
|
||||||
subregions.front();
|
|
||||||
|
|
||||||
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>(),
|
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>(),
|
||||||
*rtree;
|
*rtree;
|
||||||
@@ -189,8 +190,16 @@ void grow_job_queue::job_common(struct grow_job *job)
|
|||||||
parent_e.path().c_str(), g->job_list.size());
|
parent_e.path().c_str(), g->job_list.size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
flecs::log::dbg("region rect: %s",
|
||||||
|
(rtree->region.rect.operator String()).ascii().ptr());
|
||||||
|
assert(!rtree->region.can_grow);
|
||||||
|
assert(rtree->region.rect.size.x > 1 || rtree->region.rect.size.y > 1);
|
||||||
|
assert(rtree->region.rect.get_area() > subregions.size());
|
||||||
create_region_list(rtree, subregions, region_list);
|
create_region_list(rtree, subregions, region_list);
|
||||||
assert(base_rtree->check(grid_floor_e));
|
assert(base_rtree->check(grid_floor_e));
|
||||||
|
flecs::log::dbg(
|
||||||
|
"splitting region: %s",
|
||||||
|
grid_e.world().entity(rtree->region.region_et).path().c_str());
|
||||||
rtree->split(grid_floor_e, region_list);
|
rtree->split(grid_floor_e, region_list);
|
||||||
assert(base_rtree->check(grid_floor_e));
|
assert(base_rtree->check(grid_floor_e));
|
||||||
grid_floor_e.modified<region_tree>();
|
grid_floor_e.modified<region_tree>();
|
||||||
@@ -198,126 +207,11 @@ void grow_job_queue::job_common(struct grow_job *job)
|
|||||||
assert(base_rtree->check(grid_floor_e));
|
assert(base_rtree->check(grid_floor_e));
|
||||||
rtree->grow(grid_floor_e);
|
rtree->grow(grid_floor_e);
|
||||||
assert(base_rtree->check(grid_floor_e));
|
assert(base_rtree->check(grid_floor_e));
|
||||||
|
rtree->move(grid_floor_e);
|
||||||
|
assert(base_rtree->check(grid_floor_e));
|
||||||
rtree->dump(grid_floor_e);
|
rtree->dump(grid_floor_e);
|
||||||
grid_floor_e.modified<region_tree>();
|
grid_floor_e.modified<region_tree>();
|
||||||
|
|
||||||
#if 0
|
|
||||||
flecs::log::dbg("common: region count: %d", g->regions.size());
|
|
||||||
assert(g->regions.size() > 0);
|
|
||||||
bool restart = false, found = false;
|
|
||||||
RegionRect2i clip_rect(0, 0, grid_size, grid_size);
|
|
||||||
for (i = 0; i < (int)g->regions.size(); i++) {
|
|
||||||
flecs::log::dbg("region %d: %s", i,
|
|
||||||
grid_e.world()
|
|
||||||
.entity(g->regions[i].region_et)
|
|
||||||
.path()
|
|
||||||
.c_str());
|
|
||||||
}
|
|
||||||
int region_index = -1;
|
|
||||||
for (i = 0; i < (int)g->regions.size(); i++) {
|
|
||||||
if (g->regions[i].region_et == job->parent_id) {
|
|
||||||
flecs::log::warn("parent is in regions %d", i);
|
|
||||||
region_index = i;
|
|
||||||
if (!g->regions[i].complete) {
|
|
||||||
g->job_list.push_back(*job);
|
|
||||||
restart = true;
|
|
||||||
flecs::log::err(
|
|
||||||
"parent is in regions %d incomplete",
|
|
||||||
i);
|
|
||||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
|
||||||
grid_e.world()
|
|
||||||
.entity(job->parent_id)
|
|
||||||
.path()
|
|
||||||
.c_str(),
|
|
||||||
g->job_list.size());
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
// no parent region yet
|
|
||||||
g->job_list.push_back(*job);
|
|
||||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
|
||||||
parent_e.path().c_str(), g->job_list.size());
|
|
||||||
restart = true;
|
|
||||||
}
|
|
||||||
if (restart)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < g->regions.size(); i++)
|
|
||||||
flecs::log::warn(
|
|
||||||
"before: region %d: %s", i,
|
|
||||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
|
||||||
// growth_regions::region parent_region = g->regions[region_index];
|
|
||||||
// const List<Pair<flecs::entity, float> >::Element *fe =
|
|
||||||
// subregions.front();
|
|
||||||
List<Pair<flecs::entity, float> > region_list = subregions;
|
|
||||||
g->split_region(grid_floor_e, region_index, region_list);
|
|
||||||
#endif
|
|
||||||
// g->regions.remove(region_index);
|
|
||||||
// clip_rect = parent_region.rect;
|
|
||||||
// int parent_region_index = g->parent_regions.size();
|
|
||||||
// g->parent_regions.push_back(parent_region);
|
|
||||||
/*
|
|
||||||
while (fe) {
|
|
||||||
flecs::entity ce = fe->get().first;
|
|
||||||
float area = fe->get().second;
|
|
||||||
flecs::log::warn("generating positions for: %s",
|
|
||||||
ce.path().c_str());
|
|
||||||
job->grid.filter_candidates(ce, area, clip_rect);
|
|
||||||
fe = fe->next();
|
|
||||||
}
|
|
||||||
job->grid.place_regions_common(parent_e, grid_floor_e,
|
|
||||||
parent_region_index);
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < g->regions.size(); i++)
|
|
||||||
flecs::log::warn(
|
|
||||||
"after: region %d: %s", i,
|
|
||||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
|
||||||
flecs::log::dbg("Running grow...");
|
|
||||||
g->grow_regions(grid_floor_e);
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
// FIXME: fix this
|
|
||||||
queries.get_qr().each(
|
|
||||||
[this, parent_e](
|
|
||||||
flecs::entity grid_floor_e,
|
|
||||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
|
||||||
growth_regions &g) {
|
|
||||||
if (g.complete)
|
|
||||||
return;
|
|
||||||
g.grow_regions(grid_floor_e);
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < g->regions.size(); i++)
|
|
||||||
flecs::log::warn(
|
|
||||||
"after2: region %d: %s", i,
|
|
||||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
queries.get_qr().each(
|
|
||||||
[this, parent_e](
|
|
||||||
flecs::entity grid_floor_e,
|
|
||||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
|
||||||
growth_regions &g) {
|
|
||||||
struct grid_misc grd;
|
|
||||||
// if (g.complete)
|
|
||||||
// return;
|
|
||||||
//grd.grow_region_rects(grid_floor_e, fl, g);
|
|
||||||
grd.update_region_cells(grid_floor_e, parent_e, fl, g);
|
|
||||||
assert(false);
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
update_region_cells(grid_floor_e);
|
|
||||||
for (i = 0; i < (int)g->regions.size(); i++)
|
|
||||||
g->regions.write[i].complete = true;
|
|
||||||
g->complete = true;
|
|
||||||
#endif
|
|
||||||
commit_common_queue();
|
commit_common_queue();
|
||||||
// assert(false);
|
// assert(false);
|
||||||
}
|
}
|
||||||
@@ -396,18 +290,22 @@ void grow_job_queue::create_region_list(
|
|||||||
int i, j;
|
int i, j;
|
||||||
const List<Pair<flecs::entity, float> >::Element *fe =
|
const List<Pair<flecs::entity, float> >::Element *fe =
|
||||||
subregions.front();
|
subregions.front();
|
||||||
bool restart = false, found = false;
|
|
||||||
make_random r(172);
|
make_random r(172);
|
||||||
RegionRect2i clip_rect = rtree->region.rect;
|
RegionRect2i clip_rect = rtree->region.rect;
|
||||||
Vector2i current_position = clip_rect.get_center();
|
Vector2i current_position = clip_rect.get_center();
|
||||||
Vector2i velocity;
|
Vector2i velocity;
|
||||||
|
|
||||||
|
flecs::log::dbg("clip_rect: %s",
|
||||||
|
(clip_rect.operator String()).ascii().ptr());
|
||||||
|
|
||||||
|
assert(clip_rect.size.x > 1 || clip_rect.size.y > 1);
|
||||||
|
assert(clip_rect.get_area() > subregions.size());
|
||||||
|
|
||||||
Vector<flecs::entity> regions;
|
Vector<flecs::entity> regions;
|
||||||
LocalVector<Vector2i> positions;
|
LocalVector<Vector2i> positions;
|
||||||
Vector<int> distances;
|
Vector<int> distances;
|
||||||
LocalVector<float> areas;
|
LocalVector<float> areas;
|
||||||
// Drunk walk implementation
|
// Drunk walk implementation
|
||||||
int speed = MAX(1, grid_size * grid_size / 2 / subregions.size());
|
|
||||||
int bad_count = 0;
|
int bad_count = 0;
|
||||||
while (fe) {
|
while (fe) {
|
||||||
Vector<Vector2i> position_candidates;
|
Vector<Vector2i> position_candidates;
|
||||||
@@ -496,6 +394,12 @@ void grow_job_queue::create_region_list(
|
|||||||
bad_count++;
|
bad_count++;
|
||||||
}
|
}
|
||||||
if (bad_count >= 100) {
|
if (bad_count >= 100) {
|
||||||
|
flecs::log::dbg(
|
||||||
|
"using different algorithm: %s: %s",
|
||||||
|
(clip_rect.operator String()).ascii().ptr(),
|
||||||
|
(current_position.operator String())
|
||||||
|
.ascii()
|
||||||
|
.ptr());
|
||||||
position_candidates.clear();
|
position_candidates.clear();
|
||||||
int x, y;
|
int x, y;
|
||||||
for (x = clip_rect.position.x;
|
for (x = clip_rect.position.x;
|
||||||
@@ -506,6 +410,10 @@ void grow_job_queue::create_region_list(
|
|||||||
y++) {
|
y++) {
|
||||||
position_candidates.push_back(
|
position_candidates.push_back(
|
||||||
Vector2i(x, y));
|
Vector2i(x, y));
|
||||||
|
flecs::log::dbg(
|
||||||
|
"candidate: %d: %d %d",
|
||||||
|
position_candidates.size() - 1,
|
||||||
|
x, y);
|
||||||
}
|
}
|
||||||
bad_count = 0;
|
bad_count = 0;
|
||||||
for (i = 0; i < position_candidates.size(); i++) {
|
for (i = 0; i < position_candidates.size(); i++) {
|
||||||
@@ -547,6 +455,7 @@ void grow_job_queue::create_region_list(
|
|||||||
flecs::log::dbg("position: %d, %d", positions[i].x,
|
flecs::log::dbg("position: %d, %d", positions[i].x,
|
||||||
positions[i].y);
|
positions[i].y);
|
||||||
region.complete = false;
|
region.complete = false;
|
||||||
|
region.can_move = true;
|
||||||
region.can_grow = true;
|
region.can_grow = true;
|
||||||
region.can_grow_square = true;
|
region.can_grow_square = true;
|
||||||
region.parent = rtree->region.region_et;
|
region.parent = rtree->region.region_et;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
#include <core/math/a_star.h>
|
||||||
#include "growth_regions.h"
|
#include "growth_regions.h"
|
||||||
#include "region_tree.h"
|
#include "region_tree.h"
|
||||||
#include "editor_event.h"
|
#include "editor_event.h"
|
||||||
#include "queries.h"
|
#include "queries.h"
|
||||||
|
#include "building_layout_graph.h"
|
||||||
#include "growth_module.h"
|
#include "growth_module.h"
|
||||||
|
|
||||||
growth_module::growth_module(flecs::world &ecs)
|
growth_module::growth_module(flecs::world &ecs)
|
||||||
@@ -9,6 +11,18 @@ growth_module::growth_module(flecs::world &ecs)
|
|||||||
ecs.module<growth_module>();
|
ecs.module<growth_module>();
|
||||||
ecs.component<growth_regions>();
|
ecs.component<growth_regions>();
|
||||||
ecs.component<region_tree>();
|
ecs.component<region_tree>();
|
||||||
|
ecs.component<WorldEditor::components::internal_wall_east>();
|
||||||
|
ecs.component<WorldEditor::components::internal_wall_west>();
|
||||||
|
ecs.component<WorldEditor::components::internal_wall_north>();
|
||||||
|
ecs.component<WorldEditor::components::internal_wall_south>();
|
||||||
|
ecs.component<WorldEditor::components::outside_wall_east>();
|
||||||
|
ecs.component<WorldEditor::components::outside_wall_west>();
|
||||||
|
ecs.component<WorldEditor::components::outside_wall_north>();
|
||||||
|
ecs.component<WorldEditor::components::outside_wall_south>();
|
||||||
|
ecs.component<WorldEditor::components::window_east>();
|
||||||
|
ecs.component<WorldEditor::components::window_west>();
|
||||||
|
ecs.component<WorldEditor::components::window_north>();
|
||||||
|
ecs.component<WorldEditor::components::window_south>();
|
||||||
const String &module_name = "::growth_module";
|
const String &module_name = "::growth_module";
|
||||||
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
||||||
.add(flecs::Phase)
|
.add(flecs::Phase)
|
||||||
@@ -16,11 +30,6 @@ growth_module::growth_module(flecs::world &ecs)
|
|||||||
flecs::entity GraphSolve = ecs.lookup("::graph_module::GraphSolve");
|
flecs::entity GraphSolve = ecs.lookup("::graph_module::GraphSolve");
|
||||||
assert(GraphSolve.is_valid());
|
assert(GraphSolve.is_valid());
|
||||||
GraphFilter.disable();
|
GraphFilter.disable();
|
||||||
#if 0
|
|
||||||
flecs::entity GraphGridPrepare = ecs.entity("GraphGridPrepare")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(GraphSolve);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ecs.system("RunGrow")
|
ecs.system("RunGrow")
|
||||||
.immediate()
|
.immediate()
|
||||||
@@ -76,113 +85,8 @@ growth_module::growth_module(flecs::world &ecs)
|
|||||||
job_queue.iterate();
|
job_queue.iterate();
|
||||||
});
|
});
|
||||||
commit_growth_queue(it.world());
|
commit_growth_queue(it.world());
|
||||||
queries.get_mark_cells().each([](flecs::entity e,
|
mark_cells(it.world());
|
||||||
const WorldEditor::
|
mark_doors(it.world());
|
||||||
components::buildings_layout_grid_cell
|
|
||||||
&cell) {
|
|
||||||
int grid_size =
|
|
||||||
e.parent()
|
|
||||||
.get<WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor>()
|
|
||||||
->grid_size;
|
|
||||||
int i;
|
|
||||||
Vector2i position(cell.index % grid_size,
|
|
||||||
cell.index / grid_size);
|
|
||||||
Vector2 west(position.x - 1, position.y);
|
|
||||||
Vector2 north(position.x, position.y - 1);
|
|
||||||
Vector2 east(position.x + 1, position.y);
|
|
||||||
Vector2 south(position.x, position.y + 1);
|
|
||||||
int west_id = west.x + grid_size * west.y;
|
|
||||||
int north_id = north.x + grid_size * north.y;
|
|
||||||
int east_id = east.x + grid_size * east.y;
|
|
||||||
int south_id = south.x + grid_size * south.y;
|
|
||||||
std::vector<int> neighbors = {
|
|
||||||
west_id, north_id, east_id, south_id
|
|
||||||
};
|
|
||||||
bool outside = false;
|
|
||||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
|
||||||
int id = neighbors[i];
|
|
||||||
print_line("id=" + itos(id));
|
|
||||||
String neighbor_cell =
|
|
||||||
"cell_" + itos(id);
|
|
||||||
flecs::entity neighbor_e =
|
|
||||||
e.parent().lookup(
|
|
||||||
neighbor_cell.ascii()
|
|
||||||
.ptr());
|
|
||||||
if (!neighbor_e.is_valid()) {
|
|
||||||
outside = true;
|
|
||||||
if (id == west_id) {
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
outside_wall_west>();
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_west>();
|
|
||||||
} else if (id == east_id) {
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
outside_wall_east>();
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_east>();
|
|
||||||
} else if (id == north_id) {
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
outside_wall_north>();
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_north>();
|
|
||||||
} else if (id == south_id) {
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
outside_wall_south>();
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_south>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool border = false;
|
|
||||||
flecs::log::dbg("outside: %d", outside);
|
|
||||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
|
||||||
int id = neighbors[i];
|
|
||||||
print_line("id=" + itos(id));
|
|
||||||
String neighbor_name =
|
|
||||||
"cell_" + itos(id);
|
|
||||||
flecs::entity neighbor_e =
|
|
||||||
e.parent().lookup(
|
|
||||||
neighbor_name.ascii()
|
|
||||||
.ptr());
|
|
||||||
if (!neighbor_e.is_valid())
|
|
||||||
continue;
|
|
||||||
const WorldEditor::components::buildings_layout_grid_cell
|
|
||||||
*neighbor_cell = neighbor_e.get<
|
|
||||||
WorldEditor::components::
|
|
||||||
buildings_layout_grid_cell>();
|
|
||||||
if (cell.type != neighbor_cell->type) {
|
|
||||||
border = true;
|
|
||||||
if (id == west_id)
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_west>();
|
|
||||||
else if (id == east_id)
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_east>();
|
|
||||||
else if (id == north_id)
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_north>();
|
|
||||||
else if (id == south_id)
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
internal_wall_south>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (outside) {
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
outside_wall>();
|
|
||||||
flecs::log::dbg("outside wall cell %s",
|
|
||||||
e.path().c_str());
|
|
||||||
} else
|
|
||||||
e.add<WorldEditor::components::
|
|
||||||
final_cell>();
|
|
||||||
if (border)
|
|
||||||
e.add<WorldEditor::components::border>();
|
|
||||||
print_line("outside: " + itos(outside));
|
|
||||||
print_line("position: " +
|
|
||||||
(position.operator String()));
|
|
||||||
print_line("grid size: " + itos(grid_size));
|
|
||||||
print_line("tile index: " + itos(cell.index));
|
|
||||||
});
|
|
||||||
it.world()
|
it.world()
|
||||||
.lookup("::growth_module::GraphFilter")
|
.lookup("::growth_module::GraphFilter")
|
||||||
.disable();
|
.disable();
|
||||||
@@ -261,3 +165,472 @@ void growth_module::commit_growth_queue(flecs::world &&ecs)
|
|||||||
buildings_layout_grid_queue>();
|
buildings_layout_grid_queue>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void growth_module::mark_cells(flecs::world &&ecs_)
|
||||||
|
{
|
||||||
|
struct queries queries(ecs_);
|
||||||
|
queries.get_mark_cells().each([](flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
flecs::entity room_e;
|
||||||
|
int grid_size =
|
||||||
|
e.parent()
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
->grid_size;
|
||||||
|
int i;
|
||||||
|
e.each<WorldEditor::components::belongs_room>(
|
||||||
|
[&room_e](flecs::entity fe) { room_e = fe; });
|
||||||
|
bool window = true;
|
||||||
|
if (room_e.is_valid()) {
|
||||||
|
int room = room_e.get<WorldEditor::components::
|
||||||
|
buildings_layout_room>()
|
||||||
|
->room_type;
|
||||||
|
flecs::log::dbg("room id: %d", room);
|
||||||
|
window = BuildingLayoutGraph::get_singleton()
|
||||||
|
->get_room_type_property(room,
|
||||||
|
"window");
|
||||||
|
flecs::log::dbg("room id: %d: window: %d", room,
|
||||||
|
window);
|
||||||
|
}
|
||||||
|
Vector2i position(cell.index % grid_size,
|
||||||
|
cell.index / grid_size);
|
||||||
|
Vector2 west(position.x - 1, position.y);
|
||||||
|
Vector2 north(position.x, position.y - 1);
|
||||||
|
Vector2 east(position.x + 1, position.y);
|
||||||
|
Vector2 south(position.x, position.y + 1);
|
||||||
|
Vector2 nw(position.x - 1, position.y - 1);
|
||||||
|
Vector2 sw(position.x - 1, position.y + 1);
|
||||||
|
Vector2 ne(position.x + 1, position.y - 1);
|
||||||
|
Vector2 se(position.x + 1, position.y + 1);
|
||||||
|
#define CELL_ID(v) (v.x + grid_size * v.y);
|
||||||
|
int west_id = CELL_ID(west);
|
||||||
|
int north_id = CELL_ID(north);
|
||||||
|
int east_id = CELL_ID(east);
|
||||||
|
int south_id = CELL_ID(south);
|
||||||
|
int nw_id = CELL_ID(nw);
|
||||||
|
int sw_id = CELL_ID(sw);
|
||||||
|
int ne_id = CELL_ID(ne);
|
||||||
|
int se_id = CELL_ID(se);
|
||||||
|
std::vector<int> neighbors = { west_id, north_id, east_id,
|
||||||
|
south_id, nw_id, sw_id,
|
||||||
|
ne_id, se_id };
|
||||||
|
std::vector<int> west_corners = { nw_id, sw_id };
|
||||||
|
std::vector<int> north_corners = { nw_id, ne_id };
|
||||||
|
std::vector<int> south_corners = { sw_id, se_id };
|
||||||
|
std::vector<int> east_corners = { ne_id, se_id };
|
||||||
|
bool outside = false;
|
||||||
|
int neighbor_flags = 0;
|
||||||
|
HashMap<int, flecs::entity> neighbor_data;
|
||||||
|
HashMap<int, bool> neighbor_flags_data;
|
||||||
|
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||||
|
int id = neighbors[i];
|
||||||
|
String neighbor_cell = "cell_" + itos(id);
|
||||||
|
flecs::entity neighbor_e =
|
||||||
|
e.parent().lookup(neighbor_cell.ascii().ptr());
|
||||||
|
neighbor_data[id] = neighbor_e;
|
||||||
|
if (neighbor_e.is_valid()) {
|
||||||
|
neighbor_flags |= (1 << i);
|
||||||
|
neighbor_flags_data[id] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int internal_corner_flags = 0;
|
||||||
|
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||||
|
int id = neighbors[i];
|
||||||
|
if ((neighbor_flags & (1 << i)) == 0) {
|
||||||
|
outside = true;
|
||||||
|
if (id == west_id) {
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
outside_wall_west>();
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_west>();
|
||||||
|
if (window)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
window_west>();
|
||||||
|
if (neighbor_flags_data.has(nw_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
NW;
|
||||||
|
if (neighbor_flags_data.has(sw_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
SW;
|
||||||
|
} else if (id == east_id) {
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
outside_wall_east>();
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_east>();
|
||||||
|
if (window)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
window_east>();
|
||||||
|
if (neighbor_flags_data.has(ne_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
NE;
|
||||||
|
if (neighbor_flags_data.has(se_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
SE;
|
||||||
|
} else if (id == north_id) {
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
outside_wall_north>();
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_north>();
|
||||||
|
if (window)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
window_north>();
|
||||||
|
if (neighbor_flags_data.has(nw_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
NW;
|
||||||
|
if (neighbor_flags_data.has(ne_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
NE;
|
||||||
|
} else if (id == south_id) {
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
outside_wall_south>();
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_south>();
|
||||||
|
if (window)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
window_south>();
|
||||||
|
if (neighbor_flags_data.has(sw_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
SW;
|
||||||
|
if (neighbor_flags_data.has(se_id))
|
||||||
|
internal_corner_flags |=
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_corner::
|
||||||
|
SE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (internal_corner_flags > 0)
|
||||||
|
e.set<WorldEditor::components::internal_corner>(
|
||||||
|
{ internal_corner_flags });
|
||||||
|
bool border = false;
|
||||||
|
flecs::log::dbg("outside: %d", outside);
|
||||||
|
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||||
|
int id = neighbors[i];
|
||||||
|
print_line("id=" + itos(id));
|
||||||
|
String neighbor_name = "cell_" + itos(id);
|
||||||
|
flecs::entity neighbor_e =
|
||||||
|
e.parent().lookup(neighbor_name.ascii().ptr());
|
||||||
|
if (!neighbor_e.is_valid())
|
||||||
|
continue;
|
||||||
|
const WorldEditor::components::buildings_layout_grid_cell
|
||||||
|
*neighbor_cell = neighbor_e.get<
|
||||||
|
WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>();
|
||||||
|
if (cell.type != neighbor_cell->type) {
|
||||||
|
border = true;
|
||||||
|
if (id == west_id)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_west>();
|
||||||
|
else if (id == east_id)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_east>();
|
||||||
|
else if (id == north_id)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_north>();
|
||||||
|
else if (id == south_id)
|
||||||
|
e.add<WorldEditor::components::
|
||||||
|
internal_wall_south>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (outside) {
|
||||||
|
e.add<WorldEditor::components::outside_wall>();
|
||||||
|
flecs::log::dbg("outside wall cell %s",
|
||||||
|
e.path().c_str());
|
||||||
|
} else
|
||||||
|
e.add<WorldEditor::components::final_cell>();
|
||||||
|
if (border)
|
||||||
|
e.add<WorldEditor::components::border>();
|
||||||
|
print_line("outside: " + itos(outside));
|
||||||
|
print_line("position: " + (position.operator String()));
|
||||||
|
print_line("grid size: " + itos(grid_size));
|
||||||
|
print_line("tile index: " + itos(cell.index));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static float get_cell_cost(flecs::entity room_e, flecs::entity cell_e)
|
||||||
|
{
|
||||||
|
float cost = 1.0f;
|
||||||
|
if (!room_e.is_valid())
|
||||||
|
return cost;
|
||||||
|
int room = room_e.get<WorldEditor::components::buildings_layout_room>()
|
||||||
|
->room_type;
|
||||||
|
flecs::log::dbg("room id: %d", room);
|
||||||
|
bool priv =
|
||||||
|
BuildingLayoutGraph::get_singleton()->get_room_type_property(
|
||||||
|
room, "private");
|
||||||
|
flecs::log::dbg("room id: %d: private: %d", room, priv);
|
||||||
|
if (priv)
|
||||||
|
cost += 10000.0f;
|
||||||
|
if (cell_e.has<WorldEditor::components::border>())
|
||||||
|
cost += 500.0f;
|
||||||
|
if (cell_e.has<WorldEditor::components::outside_wall>())
|
||||||
|
cost += 500.0f;
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_astar_id(Ref<AStar> &astar, int grid_size, int cell_id,
|
||||||
|
float cost)
|
||||||
|
{
|
||||||
|
int astar_id = -1;
|
||||||
|
|
||||||
|
Vector2i position(cell_id % grid_size, cell_id / grid_size);
|
||||||
|
Vector3 pos3(position.x, 0, position.y);
|
||||||
|
astar_id = astar->get_closest_point(pos3, true);
|
||||||
|
if (astar_id >= 0 &&
|
||||||
|
astar->get_point_position(astar_id).distance_squared_to(pos3) <
|
||||||
|
1.0f)
|
||||||
|
return astar_id;
|
||||||
|
astar_id = astar->get_available_point_id();
|
||||||
|
astar->add_point(astar_id, pos3, cost);
|
||||||
|
return astar_id;
|
||||||
|
}
|
||||||
|
void growth_module::mark_doors(flecs::world &&ecs_)
|
||||||
|
{
|
||||||
|
struct queries queries(ecs_);
|
||||||
|
struct mark_doors_data {
|
||||||
|
Ref<AStar> astar;
|
||||||
|
List<const struct region_tree *> regions;
|
||||||
|
Vector<Vector3> room_points;
|
||||||
|
HashMap<int, int> id2cell;
|
||||||
|
HashMap<int, flecs::entity> id2entity;
|
||||||
|
};
|
||||||
|
HashMap<flecs::entity_t, struct mark_doors_data> data;
|
||||||
|
queries.get_mark_cells().each([&data](flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
flecs::entity room_e;
|
||||||
|
int i;
|
||||||
|
int grid_size =
|
||||||
|
e.parent()
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
->grid_size;
|
||||||
|
if (!data.has(e.parent().id())) {
|
||||||
|
struct mark_doors_data mdata;
|
||||||
|
mdata.astar.instance();
|
||||||
|
const struct region_tree *rtree =
|
||||||
|
e.parent().get<region_tree>();
|
||||||
|
rtree->get_leaf_nodes(&mdata.regions);
|
||||||
|
List<const struct region_tree *>::Element *reg_E =
|
||||||
|
mdata.regions.front();
|
||||||
|
while (reg_E) {
|
||||||
|
const struct region_tree *rt = reg_E->get();
|
||||||
|
Vector2i center = rt->region.rect.get_center();
|
||||||
|
Vector3 center3(center.x, 0, center.y);
|
||||||
|
mdata.room_points.push_back(center3);
|
||||||
|
flecs::log::dbg("room_point: %s",
|
||||||
|
(center3.operator String())
|
||||||
|
.ascii()
|
||||||
|
.ptr());
|
||||||
|
reg_E = reg_E->next();
|
||||||
|
}
|
||||||
|
data[e.parent().id()] = mdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.each<WorldEditor::components::belongs_room>(
|
||||||
|
[&room_e](flecs::entity fe) { room_e = fe; });
|
||||||
|
Vector2i position(cell.index % grid_size,
|
||||||
|
cell.index / grid_size);
|
||||||
|
Vector2 west(position.x - 1, position.y);
|
||||||
|
Vector2 north(position.x, position.y - 1);
|
||||||
|
Vector2 east(position.x + 1, position.y);
|
||||||
|
Vector2 south(position.x, position.y + 1);
|
||||||
|
int p0 = get_astar_id(data[e.parent().id()].astar, grid_size,
|
||||||
|
cell.index, get_cell_cost(room_e, e));
|
||||||
|
data[e.parent().id()].id2cell[p0] = cell.index;
|
||||||
|
data[e.parent().id()].id2entity[p0] = e;
|
||||||
|
#define CELL_ID(v) (v.x + grid_size * v.y);
|
||||||
|
int west_id = CELL_ID(west);
|
||||||
|
int north_id = CELL_ID(north);
|
||||||
|
int east_id = CELL_ID(east);
|
||||||
|
int south_id = CELL_ID(south);
|
||||||
|
std::vector<int> neighbors = { west_id, north_id, east_id,
|
||||||
|
south_id };
|
||||||
|
bool outside = false;
|
||||||
|
HashMap<int, flecs::entity> neighbor_data;
|
||||||
|
HashMap<int, bool> neighbor_flags_data;
|
||||||
|
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||||
|
int id = neighbors[i];
|
||||||
|
String neighbor_cell = "cell_" + itos(id);
|
||||||
|
flecs::entity neighbor_e =
|
||||||
|
e.parent().lookup(neighbor_cell.ascii().ptr());
|
||||||
|
|
||||||
|
if (neighbor_e.is_valid()) {
|
||||||
|
flecs::entity neighbor_room_e;
|
||||||
|
neighbor_e.each<
|
||||||
|
WorldEditor::components::belongs_room>(
|
||||||
|
[&neighbor_room_e](flecs::entity fe) {
|
||||||
|
neighbor_room_e = fe;
|
||||||
|
});
|
||||||
|
neighbor_flags_data[id] = true;
|
||||||
|
int p1 = get_astar_id(
|
||||||
|
data[e.parent().id()].astar, grid_size,
|
||||||
|
id,
|
||||||
|
get_cell_cost(neighbor_room_e,
|
||||||
|
neighbor_e));
|
||||||
|
assert(p1 >= 0 && p0 >= 0);
|
||||||
|
data[e.parent().id()].astar->connect_points(
|
||||||
|
p0, p1, true);
|
||||||
|
data[e.parent().id()].id2cell[p1] = id;
|
||||||
|
data[e.parent().id()].id2entity[p1] =
|
||||||
|
neighbor_e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<flecs::entity_t> key_list;
|
||||||
|
data.get_key_list(&key_list);
|
||||||
|
List<flecs::entity_t>::Element *ke = key_list.front();
|
||||||
|
while (ke) {
|
||||||
|
int j, k;
|
||||||
|
int grid_size =
|
||||||
|
ecs_.entity(ke->get())
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
->grid_size;
|
||||||
|
HashMap<flecs::entity_t, List<flecs::entity_t> > exits;
|
||||||
|
Set<flecs::entity_t> corridoor_exits;
|
||||||
|
Vector3 xdata(grid_size / 2, 0, grid_size + 1);
|
||||||
|
int p0 = data[ke->get()].astar->get_closest_point(xdata);
|
||||||
|
for (j = 0; j < data[ke->get()].room_points.size(); j++) {
|
||||||
|
int p1 = data[ke->get()].astar->get_closest_point(
|
||||||
|
data[ke->get()].room_points[j]);
|
||||||
|
PoolVector<int> path =
|
||||||
|
data[ke->get()].astar->get_id_path(p0, p1);
|
||||||
|
PoolVector<int> cell_path;
|
||||||
|
cell_path.resize(path.size());
|
||||||
|
String elements;
|
||||||
|
for (k = 0; k < path.size(); k++)
|
||||||
|
cell_path.write()[k] =
|
||||||
|
data[ke->get()].id2cell[path[k]];
|
||||||
|
for (k = 0; k < cell_path.size(); k++) {
|
||||||
|
elements += itos(cell_path[k]);
|
||||||
|
if (k < cell_path.size() - 1)
|
||||||
|
elements += ", ";
|
||||||
|
}
|
||||||
|
for (k = 0; k < cell_path.size() - 1; k++) {
|
||||||
|
int px = cell_path[k] % grid_size;
|
||||||
|
int py = cell_path[k] / grid_size;
|
||||||
|
int next_px = cell_path[k + 1] % grid_size;
|
||||||
|
int next_py = cell_path[k + 1] / grid_size;
|
||||||
|
int tx = next_px - px;
|
||||||
|
int ty = next_py - py;
|
||||||
|
Vector3 position(px, 0, py),
|
||||||
|
next_position(next_px, 0, next_py);
|
||||||
|
int point = data[ke->get()]
|
||||||
|
.astar->get_closest_point(
|
||||||
|
position, true),
|
||||||
|
point_next =
|
||||||
|
data[ke->get()]
|
||||||
|
.astar->get_closest_point(
|
||||||
|
next_position,
|
||||||
|
true);
|
||||||
|
data[ke->get()].astar->set_point_weight_scale(
|
||||||
|
point, 0.5f);
|
||||||
|
data[ke->get()].astar->set_point_weight_scale(
|
||||||
|
point_next, 0.5f);
|
||||||
|
|
||||||
|
flecs::entity room_e, next_room_e;
|
||||||
|
flecs::entity cell_e =
|
||||||
|
data[ke->get()].id2entity[path[k]];
|
||||||
|
cell_e.each<
|
||||||
|
WorldEditor::components::belongs_room>(
|
||||||
|
[&room_e](flecs::entity re) {
|
||||||
|
room_e = re;
|
||||||
|
});
|
||||||
|
flecs::entity next_cell_e =
|
||||||
|
data[ke->get()].id2entity[path[k + 1]];
|
||||||
|
next_cell_e.each<
|
||||||
|
WorldEditor::components::belongs_room>(
|
||||||
|
[&next_room_e](flecs::entity re) {
|
||||||
|
next_room_e = re;
|
||||||
|
});
|
||||||
|
if (room_e.is_valid() &&
|
||||||
|
next_room_e.is_valid()) {
|
||||||
|
if (exits.has(room_e.id()) &&
|
||||||
|
exits[room_e.id()].find(
|
||||||
|
next_room_e.id()) !=
|
||||||
|
nullptr)
|
||||||
|
continue;
|
||||||
|
if (exits.has(next_room_e.id()) &&
|
||||||
|
exits[next_room_e.id()].find(
|
||||||
|
room_e.id()) != nullptr)
|
||||||
|
continue;
|
||||||
|
exits[room_e.id()].push_back(
|
||||||
|
next_room_e.id());
|
||||||
|
exits[next_room_e.id()].push_back(
|
||||||
|
room_e.id());
|
||||||
|
} else if (room_e.is_valid()) {
|
||||||
|
if (corridoor_exits.has(room_e.id()))
|
||||||
|
continue;
|
||||||
|
corridoor_exits.insert(room_e.id());
|
||||||
|
} else if (next_room_e.is_valid()) {
|
||||||
|
if (corridoor_exits.has(
|
||||||
|
next_room_e.id()))
|
||||||
|
continue;
|
||||||
|
corridoor_exits.insert(
|
||||||
|
next_room_e.id());
|
||||||
|
}
|
||||||
|
flecs::log::dbg("path point %d: %d %d", k, tx,
|
||||||
|
ty);
|
||||||
|
assert((tx == 0 || ty == 0) &&
|
||||||
|
(tx != 0 || ty != 0));
|
||||||
|
|
||||||
|
if (tx < 0 &&
|
||||||
|
cell_e.has<WorldEditor::components::
|
||||||
|
internal_wall_west>()) {
|
||||||
|
cell_e.add<WorldEditor::components::
|
||||||
|
internal_door_west>();
|
||||||
|
next_cell_e.add<
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_door_east>();
|
||||||
|
}
|
||||||
|
if (tx > 0 &&
|
||||||
|
cell_e.has<WorldEditor::components::
|
||||||
|
internal_wall_east>()) {
|
||||||
|
cell_e.add<WorldEditor::components::
|
||||||
|
internal_door_east>();
|
||||||
|
next_cell_e.add<
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_door_west>();
|
||||||
|
}
|
||||||
|
if (ty < 0 &&
|
||||||
|
cell_e.has<WorldEditor::components::
|
||||||
|
internal_wall_north>()) {
|
||||||
|
cell_e.add<WorldEditor::components::
|
||||||
|
internal_door_north>();
|
||||||
|
next_cell_e.add<
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_door_south>();
|
||||||
|
}
|
||||||
|
if (ty > 0 &&
|
||||||
|
cell_e.has<WorldEditor::components::
|
||||||
|
internal_wall_south>()) {
|
||||||
|
cell_e.add<WorldEditor::components::
|
||||||
|
internal_door_south>();
|
||||||
|
next_cell_e.add<
|
||||||
|
WorldEditor::components::
|
||||||
|
internal_door_north>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flecs::log::dbg("path: %s", elements.ascii().ptr());
|
||||||
|
}
|
||||||
|
ke = ke->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
struct growth_module {
|
struct growth_module {
|
||||||
void grow_cell(flecs::entity seed_e, int id);
|
void grow_cell(flecs::entity seed_e, int id);
|
||||||
void commit_growth_queue(flecs::world &&world);
|
void commit_growth_queue(flecs::world &&world);
|
||||||
|
void mark_cells(flecs::world &&ecs_);
|
||||||
|
void mark_doors(flecs::world &&ecs_);
|
||||||
growth_module(flecs::world &ecs);
|
growth_module(flecs::world &ecs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,213 +1 @@
|
|||||||
#include "growth_regions.h"
|
#include "growth_regions.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static void print_can_grow(int state, growth_regions &g, int index,
|
|
||||||
const char *what)
|
|
||||||
{
|
|
||||||
const growth_regions::region ®ion = g.regions[index];
|
|
||||||
bool can = false;
|
|
||||||
if (!strcmp(what, "square"))
|
|
||||||
can = region.can_grow_square;
|
|
||||||
else if (!strcmp(what, "rect"))
|
|
||||||
can = region.can_grow;
|
|
||||||
|
|
||||||
if (can)
|
|
||||||
flecs::log::dbg(
|
|
||||||
"state: %d: index %d: region can still grow %s %d",
|
|
||||||
state, index, what, region.remains_area);
|
|
||||||
else
|
|
||||||
flecs::log::dbg("state: %d: index %d: region can't grow %s %d",
|
|
||||||
state, index, what, region.remains_area);
|
|
||||||
if (region.can_grow_region())
|
|
||||||
flecs::log::dbg("state %d: index %d: region can still continue",
|
|
||||||
state, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool growth_regions::grow_state0(int index, const RegionRect2i &clip)
|
|
||||||
{
|
|
||||||
bool ok = true, ret = false;
|
|
||||||
RegionRect2i mrect;
|
|
||||||
growth_regions::region ®ion = regions.write[index];
|
|
||||||
mrect = region.rect;
|
|
||||||
assert(check_region(index, mrect));
|
|
||||||
|
|
||||||
mrect = mrect.grow(1);
|
|
||||||
ok = clip.encloses(mrect);
|
|
||||||
// if (!ok)
|
|
||||||
// flecs::log::dbg("state: %d: index %d: out of clip area",
|
|
||||||
// 0, index);
|
|
||||||
if (ok) {
|
|
||||||
ok = check_region(index, mrect);
|
|
||||||
// if (!ok)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state: %d: index %d: check_region failed",
|
|
||||||
// 0, index);
|
|
||||||
}
|
|
||||||
if (ok) {
|
|
||||||
ret = region.update_region_size(mrect);
|
|
||||||
// if (!ret)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state: %d: index %d: update_region_size failed",
|
|
||||||
// 0, index);
|
|
||||||
}
|
|
||||||
print_can_grow(0, *this, index, "square");
|
|
||||||
// if (!ret)
|
|
||||||
// flecs::log::dbg("state %d could not grow region %d: %d",
|
|
||||||
// 0, index, region.remains_area);
|
|
||||||
// else
|
|
||||||
// flecs::log::dbg("state %d could grow region %d: %d", 0,
|
|
||||||
// index, region.remains_area);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
bool growth_regions::grow_state1(int index, const RegionRect2i &clip)
|
|
||||||
{
|
|
||||||
int d;
|
|
||||||
bool ret = false;
|
|
||||||
RegionRect2i mrect;
|
|
||||||
growth_regions::region ®ion = regions.write[index];
|
|
||||||
int count = 0;
|
|
||||||
for (d = 0; d < 4; d++) {
|
|
||||||
bool ok;
|
|
||||||
mrect = region.rect;
|
|
||||||
assert(check_region(index, mrect));
|
|
||||||
switch (d) {
|
|
||||||
case 0:
|
|
||||||
mrect.position.y -= 1;
|
|
||||||
mrect.size.y += 1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mrect.size.y += 1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mrect.position.x -= 1;
|
|
||||||
mrect.size.x += 1;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mrect.size.x += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ok = parent_regions[region.parent_region].rect.encloses(mrect);
|
|
||||||
if (ok)
|
|
||||||
ok = clip.encloses(mrect);
|
|
||||||
if (ok) {
|
|
||||||
ok = false;
|
|
||||||
if (mrect.size.y > 0 && mrect.size.x > 0) {
|
|
||||||
float aspect = (float)mrect.size.x /
|
|
||||||
(float)mrect.size.y;
|
|
||||||
ok = (aspect > 0.2f && aspect < 5.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ok)
|
|
||||||
ok = check_region(index, mrect);
|
|
||||||
if (ok) {
|
|
||||||
bool result = region.update_region_size(mrect);
|
|
||||||
if (result)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
ret = true;
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state %d could grow region %d: %d - %d out of %d times",
|
|
||||||
// 0, index, region.remains_area, count, 4);
|
|
||||||
}
|
|
||||||
print_can_grow(1, *this, index, "rect");
|
|
||||||
// if (!ret)
|
|
||||||
// flecs::log::dbg(
|
|
||||||
// "state %d could not grow region rect %d: %d", 0,
|
|
||||||
// index, region.remains_area);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
void growth_regions::grow_regions(flecs::entity grid_floor_e)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool grown = true;
|
|
||||||
int state = 0;
|
|
||||||
if (complete)
|
|
||||||
return;
|
|
||||||
#if 0
|
|
||||||
int grid_size = grid_floor_e
|
|
||||||
.get<WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor>()
|
|
||||||
->grid_size;
|
|
||||||
#endif
|
|
||||||
state = 0;
|
|
||||||
flecs::log::dbg("growing square");
|
|
||||||
while (grown) {
|
|
||||||
grown = false;
|
|
||||||
int count = 0;
|
|
||||||
for (i = 0; i < regions.size(); i++) {
|
|
||||||
growth_regions::region ®ion = regions.write[i];
|
|
||||||
const RegionRect2i &clip =
|
|
||||||
parent_regions[region.parent_region].rect;
|
|
||||||
RegionRect2i mrect = region.rect;
|
|
||||||
flecs::log::dbg("grow_region_rects: region %d", i);
|
|
||||||
if (!region.can_grow_region()) {
|
|
||||||
flecs::log::dbg("grow_region_rects: skip %d",
|
|
||||||
i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mrect = region.rect;
|
|
||||||
bool result = false;
|
|
||||||
result = grow_state0(i, clip);
|
|
||||||
if (result)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
grown = true;
|
|
||||||
flecs::log::dbg("grown squares %d times of %d", count,
|
|
||||||
regions.size());
|
|
||||||
}
|
|
||||||
if (!grown)
|
|
||||||
flecs::log::dbg(
|
|
||||||
"grow_region_rects: could not grow more squares");
|
|
||||||
}
|
|
||||||
state = 1;
|
|
||||||
grown = true;
|
|
||||||
flecs::log::dbg("growing rect");
|
|
||||||
while (grown) {
|
|
||||||
grown = false;
|
|
||||||
int count = 0;
|
|
||||||
for (i = 0; i < regions.size(); i++) {
|
|
||||||
growth_regions::region ®ion = regions.write[i];
|
|
||||||
const RegionRect2i &clip =
|
|
||||||
parent_regions[region.parent_region].rect;
|
|
||||||
RegionRect2i mrect = region.rect;
|
|
||||||
flecs::log::dbg("grow_region_rects: region %d", i);
|
|
||||||
if (!region.can_grow_region()) {
|
|
||||||
flecs::log::dbg("grow_region_rects: skip %d",
|
|
||||||
i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mrect = region.rect;
|
|
||||||
bool result = false;
|
|
||||||
result = grow_state1(i, clip);
|
|
||||||
if (result)
|
|
||||||
count++;
|
|
||||||
if (!result)
|
|
||||||
flecs::log::dbg(
|
|
||||||
"state %d could not grow region %d",
|
|
||||||
state, i);
|
|
||||||
else
|
|
||||||
flecs::log::dbg(
|
|
||||||
"state %d could grow region %d: %d",
|
|
||||||
state, i, region.remains_area);
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
grown = true;
|
|
||||||
flecs::log::dbg("grown rects %d times of %d", count,
|
|
||||||
regions.size());
|
|
||||||
}
|
|
||||||
if (!grown)
|
|
||||||
flecs::log::dbg(
|
|
||||||
"grow_region_rects: could not grow any more rects");
|
|
||||||
}
|
|
||||||
flecs::log::dbg("grow_region_rects: complete");
|
|
||||||
complete = true;
|
|
||||||
flecs::log::dbg("grow_region_rects: %s: done",
|
|
||||||
grid_floor_e.path().c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -14,6 +14,7 @@ struct region {
|
|||||||
RegionRect2i rect;
|
RegionRect2i rect;
|
||||||
int remains_area;
|
int remains_area;
|
||||||
bool can_grow_square;
|
bool can_grow_square;
|
||||||
|
bool can_move;
|
||||||
bool can_grow;
|
bool can_grow;
|
||||||
bool complete;
|
bool complete;
|
||||||
bool can_grow_region() const
|
bool can_grow_region() const
|
||||||
@@ -45,55 +46,6 @@ struct region {
|
|||||||
struct growth_regions {
|
struct growth_regions {
|
||||||
List<struct grow_job> job_list;
|
List<struct grow_job> job_list;
|
||||||
bool complete;
|
bool complete;
|
||||||
bool check_region(int index, const RegionRect2i &rect) const;
|
|
||||||
#if 0
|
|
||||||
bool check_region(int index, const RegionRect2i &rect) const
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool ret = true;
|
|
||||||
for (i = 0; i < regions.size(); i++) {
|
|
||||||
if (i == index)
|
|
||||||
continue;
|
|
||||||
if (rect.intersects(regions[i].rect)) {
|
|
||||||
ret = false;
|
|
||||||
flecs::log::dbg(
|
|
||||||
"%d: %s intersects %s", i,
|
|
||||||
(rect.operator String()).ascii().ptr(),
|
|
||||||
(regions[i].rect.operator String())
|
|
||||||
.ascii()
|
|
||||||
.ptr());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flecs::log::dbg("check_region: %d -> %d", index, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bool update_region_size(int index, RegionRect2i &mrect);
|
|
||||||
#if 0
|
|
||||||
bool update_region_size(int index, RegionRect2i &mrect)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
bool ok = check_region(index, mrect);
|
|
||||||
if (ok)
|
|
||||||
ret = regions.write[index].update_region_size(mrect);
|
|
||||||
flecs::log::dbg("update_region_size %d -> %d", index, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void create_region(flecs::entity floor_e, flecs::entity seed_e,
|
|
||||||
flecs::entity parent_e, flecs::entity region_e,
|
|
||||||
const Vector2i &position, float area,
|
|
||||||
int parent_index);
|
|
||||||
flecs::entity create_cell(flecs::entity floor_e, flecs::entity region_e,
|
|
||||||
int id);
|
|
||||||
flecs::entity update_cell(flecs::entity floor_e, flecs::entity parent_e,
|
|
||||||
flecs::entity region_e, int id);
|
|
||||||
void split_region(flecs::entity grid_floor_e, int region_index,
|
|
||||||
const List<Pair<flecs::entity, float> > ®ion_list);
|
|
||||||
void grow_regions(flecs::entity grid_floor_e);
|
|
||||||
bool grow_state0(int index, const RegionRect2i &clip);
|
|
||||||
bool grow_state1(int index, const RegionRect2i &clip);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
void region_tree::split(flecs::entity grid_floor_e,
|
void region_tree::split(flecs::entity grid_floor_e,
|
||||||
const List<struct region> ®ions)
|
const List<struct region> ®ions)
|
||||||
{
|
{
|
||||||
|
assert((region.rect.size.x > 1 || region.rect.size.y > 1) &&
|
||||||
|
region.rect.get_area() > regions.size());
|
||||||
assert(children.size() == 0);
|
assert(children.size() == 0);
|
||||||
const region_tree *base_rtree = grid_floor_e.get<region_tree>();
|
const region_tree *base_rtree = grid_floor_e.get<region_tree>();
|
||||||
const List<struct region>::Element *e = regions.front();
|
const List<struct region>::Element *e = regions.front();
|
||||||
@@ -461,6 +463,70 @@ void region_tree::place(flecs::entity grid_floor_e) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void region_tree::move(flecs::entity grid_floor_e)
|
||||||
|
{
|
||||||
|
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>();
|
||||||
|
assert(base_rtree);
|
||||||
|
List<struct region_tree *> queue;
|
||||||
|
List<struct region_tree *> movables;
|
||||||
|
int count = 0;
|
||||||
|
Vector2i center;
|
||||||
|
queue.push_back(base_rtree);
|
||||||
|
while (!queue.empty()) {
|
||||||
|
int i;
|
||||||
|
struct region_tree *item = queue.front()->get();
|
||||||
|
if (item->is_a_room(grid_floor_e) && !item->region.can_grow &&
|
||||||
|
item->region.can_move) {
|
||||||
|
movables.push_back(item);
|
||||||
|
count++;
|
||||||
|
center += item->region.rect.get_center();
|
||||||
|
}
|
||||||
|
queue.pop_front();
|
||||||
|
for (i = 0; i < item->children.size(); i++)
|
||||||
|
queue.push_back(item->children[i]);
|
||||||
|
}
|
||||||
|
if (count == 0)
|
||||||
|
return;
|
||||||
|
assert(count > 0);
|
||||||
|
center /= count;
|
||||||
|
flecs::log::dbg("center: %d %d", center.x, center.y);
|
||||||
|
while (!movables.empty()) {
|
||||||
|
struct region_tree *item = movables.front()->get();
|
||||||
|
movables.pop_front();
|
||||||
|
if (!item->region.can_move)
|
||||||
|
continue;
|
||||||
|
Vector2i dir = item->region.rect.get_center() - center, dir1,
|
||||||
|
dir2;
|
||||||
|
if (dir.x * dir.x > dir.y * dir.y) {
|
||||||
|
dir1.x = CLAMP(dir.x, -1, 1);
|
||||||
|
dir1.y = 0;
|
||||||
|
} else if (dir.x * dir.x < dir.y * dir.y) {
|
||||||
|
dir1.x = 0;
|
||||||
|
dir1.y = CLAMP(dir.y, -1, 1);
|
||||||
|
}
|
||||||
|
dir2.x = CLAMP(dir.x, -1, 1);
|
||||||
|
dir2.y = CLAMP(dir.y, -1, 1);
|
||||||
|
flecs::log::dbg("direction: %d %d", dir.x, dir.y);
|
||||||
|
RegionRect2i backup = item->region.rect;
|
||||||
|
item->region.rect.position += dir1;
|
||||||
|
if (base_rtree->check(grid_floor_e)) {
|
||||||
|
queue.push_back(item);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
item->region.rect = backup;
|
||||||
|
item->region.rect.position += dir2;
|
||||||
|
if (base_rtree->check(grid_floor_e)) {
|
||||||
|
queue.push_back(item);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
item->region.rect = backup;
|
||||||
|
item->region.can_move = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grid_floor_e.modified<region_tree>();
|
||||||
|
}
|
||||||
|
|
||||||
void region_tree::get_rects(List<RegionRect2i> *rect_list) const
|
void region_tree::get_rects(List<RegionRect2i> *rect_list) const
|
||||||
{
|
{
|
||||||
List<const struct region_tree *> queue;
|
List<const struct region_tree *> queue;
|
||||||
@@ -481,6 +547,46 @@ void region_tree::get_rects(List<RegionRect2i> *rect_list) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void region_tree::get_leaf_nodes(
|
||||||
|
List<const struct region_tree *> *node_list) const
|
||||||
|
{
|
||||||
|
List<const struct region_tree *> queue;
|
||||||
|
queue.push_back(this);
|
||||||
|
while (!queue.empty()) {
|
||||||
|
int i;
|
||||||
|
const struct region_tree *item = queue.front()->get();
|
||||||
|
queue.pop_front();
|
||||||
|
if (item->is_leaf()) {
|
||||||
|
node_list->push_back(item);
|
||||||
|
}
|
||||||
|
for (i = 0; i < (int)item->children.size(); i++)
|
||||||
|
queue.push_back(item->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void region_tree::get_leaf_nodes(List<struct region_tree *> *node_list)
|
||||||
|
{
|
||||||
|
List<struct region_tree *> queue;
|
||||||
|
queue.push_back(this);
|
||||||
|
while (!queue.empty()) {
|
||||||
|
int i;
|
||||||
|
struct region_tree *item = queue.front()->get();
|
||||||
|
queue.pop_front();
|
||||||
|
if (item->is_leaf()) {
|
||||||
|
node_list->push_back(item);
|
||||||
|
}
|
||||||
|
for (i = 0; i < (int)item->children.size(); i++)
|
||||||
|
queue.push_back(item->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 region_tree::check_candidate(int i, const RegionRect2i &candidate) const
|
bool region_tree::check_candidate(int i, const RegionRect2i &candidate) const
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ struct region_tree {
|
|||||||
void grow(flecs::entity grid_floor_e, bool limited = true);
|
void grow(flecs::entity grid_floor_e, bool limited = true);
|
||||||
bool check(flecs::entity grid_floor_e) const;
|
bool check(flecs::entity grid_floor_e) const;
|
||||||
void place(flecs::entity grid_floor_e) const;
|
void place(flecs::entity grid_floor_e) const;
|
||||||
|
void move(flecs::entity grid_floor_e);
|
||||||
void get_rects(List<RegionRect2i> *rect_list) const;
|
void get_rects(List<RegionRect2i> *rect_list) const;
|
||||||
|
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;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool check_candidate(int i, const RegionRect2i &candidate) const;
|
bool check_candidate(int i, const RegionRect2i &candidate) const;
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ protected:
|
|||||||
display_mi[i] = memnew(MeshInstance);
|
display_mi[i] = memnew(MeshInstance);
|
||||||
view->call_deferred("add_child", display_mi[i]);
|
view->call_deferred("add_child", display_mi[i]);
|
||||||
}
|
}
|
||||||
|
ColorRect *nav = memnew(ColorRect);
|
||||||
|
view->call_deferred("add_child", nav);
|
||||||
|
nav->set_size(Vector2(100, 100));
|
||||||
}
|
}
|
||||||
void build_mesh_data()
|
void build_mesh_data()
|
||||||
{
|
{
|
||||||
@@ -127,6 +130,7 @@ protected:
|
|||||||
Vector3(x * 4, 0, z * 4));
|
Vector3(x * 4, 0, z * 4));
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
struct pmatch {
|
struct pmatch {
|
||||||
|
int check;
|
||||||
int mask;
|
int mask;
|
||||||
String item;
|
String item;
|
||||||
Basis basis;
|
Basis basis;
|
||||||
@@ -134,43 +138,107 @@ protected:
|
|||||||
bool exterior;
|
bool exterior;
|
||||||
};
|
};
|
||||||
struct pmatch match_data[] = {
|
struct pmatch match_data[] = {
|
||||||
{ 1, "outside-wall", Basis(), Vector3(0, 0, -2),
|
{ 1, 1 | 256, "outside-wall", Basis(),
|
||||||
true },
|
Vector3(0, 0, -2), true },
|
||||||
{ 2, "outside-wall",
|
{ 2, 2 | 512, "outside-wall",
|
||||||
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
Vector3(0, 0, 2), true },
|
Vector3(0, 0, 2), true },
|
||||||
{ 4, "outside-wall",
|
{ 4, 4 | 1024, "outside-wall",
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
Math_PI / 2),
|
Math_PI / 2),
|
||||||
Vector3(-2, 0, 0), true },
|
Vector3(-2, 0, 0), true },
|
||||||
{ 8, "outside-wall",
|
{ 8, 8 | 2048, "outside-wall",
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
-Math_PI / 2),
|
-Math_PI / 2),
|
||||||
Vector3(2, 0, 0), true },
|
Vector3(2, 0, 0), true },
|
||||||
{ 2 | 8, "outside-wall-corner",
|
{ 2 | 8, 2 | 8, "outside-wall-corner",
|
||||||
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
Vector3(2, 0, 2), true },
|
Vector3(2, 0, 2), true },
|
||||||
{ 1 | 4, "outside-wall-corner",
|
{ 1 | 4, 1 | 4, "outside-wall-corner",
|
||||||
Basis().rotated(Vector3(0, 1, 0), 0),
|
Basis().rotated(Vector3(0, 1, 0), 0),
|
||||||
Vector3(-2, 0, -2), true },
|
Vector3(-2, 0, -2), true },
|
||||||
{ 1 | 8, "outside-wall-corner",
|
{ 1 | 8, 1 | 8, "outside-wall-corner",
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
-Math_PI / 2),
|
-Math_PI / 2),
|
||||||
Vector3(2, 0, -2), true },
|
Vector3(2, 0, -2), true },
|
||||||
{ 2 | 4, "outside-wall-corner",
|
{ 2 | 4, 2 | 4, "outside-wall-corner",
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
Math_PI / 2),
|
Math_PI / 2),
|
||||||
Vector3(-2, 0, 2), true },
|
Vector3(-2, 0, 2), true },
|
||||||
{ 16, "internal-wall", Basis(),
|
{ 16, 16 | 256 | 4096, "internal-wall", Basis(),
|
||||||
Vector3(0, 0, -2), false },
|
Vector3(0, 0, -2), false },
|
||||||
{ 32, "internal-wall",
|
{ 32, 32 | 512 | 8192, "internal-wall",
|
||||||
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
Vector3(0, 0, 2), false },
|
Vector3(0, 0, 2), false },
|
||||||
{ 64, "internal-wall",
|
{ 64, 64 | 1024 | 16384, "internal-wall",
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
Math_PI / 2),
|
Math_PI / 2),
|
||||||
Vector3(-2, 0, 0), false },
|
Vector3(-2, 0, 0), false },
|
||||||
{ 128, "internal-wall",
|
{ 128, 128 | 2048 | 32768, "internal-wall",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
-Math_PI / 2),
|
||||||
|
Vector3(2, 0, 0), false },
|
||||||
|
{ 16, 16 | 256, "internal-wall-skirting",
|
||||||
|
Basis(), Vector3(0, 0, -2), false },
|
||||||
|
{ 32, 32 | 512, "internal-wall-skirting",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
|
Vector3(0, 0, 2), false },
|
||||||
|
{ 64, 64 | 1024, "internal-wall-skirting",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
Math_PI / 2),
|
||||||
|
Vector3(-2, 0, 0), false },
|
||||||
|
{ 128, 128 | 2048, "internal-wall-skirting",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
-Math_PI / 2),
|
||||||
|
Vector3(2, 0, 0), false },
|
||||||
|
{ 16 | 4096, 16 | 256 | 4096, "internal-door",
|
||||||
|
Basis(), Vector3(0, 0, -2), false },
|
||||||
|
{ 32 | 8192, 32 | 512 | 8192, "internal-door",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
|
Vector3(0, 0, 2), false },
|
||||||
|
{ 64 | 16384, 64 | 1024 | 16384,
|
||||||
|
"internal-door",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
Math_PI / 2),
|
||||||
|
Vector3(-2, 0, 0), false },
|
||||||
|
{ 128 | 32768, 128 | 2048 | 32768,
|
||||||
|
"internal-door",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
-Math_PI / 2),
|
||||||
|
Vector3(2, 0, 0), false },
|
||||||
|
#if 0
|
||||||
|
{ 1 | 256, 1 | 256, "external-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
-Math_PI / 2),
|
||||||
|
Vector3(2, 0, 0), false },
|
||||||
|
{ 16 | 256, 16 | 256, "internal-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
-Math_PI / 2),
|
||||||
|
Vector3(2, 0, 0), false }
|
||||||
|
#endif
|
||||||
|
{ 1 | 256, 1 | 256, "outside-window", Basis(),
|
||||||
|
Vector3(0, 0, -2), true },
|
||||||
|
{ 2 | 512, 2 | 512, "outside-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
|
Vector3(0, 0, 2), true },
|
||||||
|
{ 4 | 1024, 4 | 1024, "outside-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
Math_PI / 2),
|
||||||
|
Vector3(-2, 0, 0), true },
|
||||||
|
{ 8 | 2048, 8 | 2048, "outside-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
-Math_PI / 2),
|
||||||
|
Vector3(2, 0, 0), true },
|
||||||
|
{ 16 | 256, 16 | 256, "internal-window",
|
||||||
|
Basis(), Vector3(0, 0, -2), false },
|
||||||
|
{ 32 | 512, 32 | 512, "internal-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0), Math_PI),
|
||||||
|
Vector3(0, 0, 2), false },
|
||||||
|
{ 64 | 1024, 64 | 1024, "internal-window",
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
Math_PI / 2),
|
||||||
|
Vector3(-2, 0, 0), false },
|
||||||
|
{ 128 | 2048, 128 | 2048, "internal-window",
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
-Math_PI / 2),
|
-Math_PI / 2),
|
||||||
Vector3(2, 0, 0), false },
|
Vector3(2, 0, 0), false },
|
||||||
@@ -191,13 +259,30 @@ protected:
|
|||||||
matches |= 64;
|
matches |= 64;
|
||||||
if (e.has<WorldEditor::components::internal_wall_east>())
|
if (e.has<WorldEditor::components::internal_wall_east>())
|
||||||
matches |= 128;
|
matches |= 128;
|
||||||
|
if (e.has<WorldEditor::components::window_north>())
|
||||||
|
matches |= 256;
|
||||||
|
if (e.has<WorldEditor::components::window_south>())
|
||||||
|
matches |= 512;
|
||||||
|
if (e.has<WorldEditor::components::window_west>())
|
||||||
|
matches |= 1024;
|
||||||
|
if (e.has<WorldEditor::components::window_east>())
|
||||||
|
matches |= 2048;
|
||||||
|
if (e.has<WorldEditor::components::internal_door_north>())
|
||||||
|
matches |= 4096;
|
||||||
|
if (e.has<WorldEditor::components::internal_door_south>())
|
||||||
|
matches |= 8192;
|
||||||
|
if (e.has<WorldEditor::components::internal_door_west>())
|
||||||
|
matches |= 16384;
|
||||||
|
if (e.has<WorldEditor::components::internal_door_east>())
|
||||||
|
matches |= 32768;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
item_data[i].items.clear();
|
item_data[i].items.clear();
|
||||||
for (i = 0; i < (int)sizeof(match_data) /
|
for (i = 0; i < (int)sizeof(match_data) /
|
||||||
(int)sizeof(match_data[0]);
|
(int)sizeof(match_data[0]);
|
||||||
i++) {
|
i++) {
|
||||||
|
int check = match_data[i].check;
|
||||||
int mask = match_data[i].mask;
|
int mask = match_data[i].mask;
|
||||||
if ((matches & mask) == mask) {
|
if ((matches & mask) == check) {
|
||||||
int id =
|
int id =
|
||||||
layout_parts->find_item_by_name(
|
layout_parts->find_item_by_name(
|
||||||
match_data[i].item);
|
match_data[i].item);
|
||||||
|
|||||||
@@ -127,10 +127,27 @@ public:
|
|||||||
struct outside_wall_west {};
|
struct outside_wall_west {};
|
||||||
struct outside_wall_north {};
|
struct outside_wall_north {};
|
||||||
struct outside_wall_south {};
|
struct outside_wall_south {};
|
||||||
|
struct window_east {};
|
||||||
|
struct window_west {};
|
||||||
|
struct window_north {};
|
||||||
|
struct window_south {};
|
||||||
|
struct internal_door_east {};
|
||||||
|
struct internal_door_west {};
|
||||||
|
struct internal_door_north {};
|
||||||
|
struct internal_door_south {};
|
||||||
struct internal_wall_east {};
|
struct internal_wall_east {};
|
||||||
struct internal_wall_west {};
|
struct internal_wall_west {};
|
||||||
struct internal_wall_north {};
|
struct internal_wall_north {};
|
||||||
struct internal_wall_south {};
|
struct internal_wall_south {};
|
||||||
|
struct internal_corner {
|
||||||
|
enum {
|
||||||
|
NW = (1 << 0),
|
||||||
|
NE = (1 << 1),
|
||||||
|
SE = (1 << 2),
|
||||||
|
SW = (1 << 3),
|
||||||
|
};
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
struct corridoor {};
|
struct corridoor {};
|
||||||
struct buildings_layout_grid_floor {
|
struct buildings_layout_grid_floor {
|
||||||
Set<int> cells;
|
Set<int> cells;
|
||||||
|
|||||||
Reference in New Issue
Block a user