summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-09-25 06:11:52 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-09-25 06:11:52 +0200
commit18d1db7d8be97fd9aea67c352e78b376d7145f4b (patch)
treeb28d9b272bf1a0e5bf971c4e162e8ef2bf44b037 /src
parent627dc90720e083b2e458ab7efb4dcca739b7a19a (diff)
a
Diffstat (limited to 'src')
-rw-r--r--src/path-search.cpp50
-rw-r--r--src/path-search.hpp9
-rw-r--r--src/world.hpp2
3 files changed, 52 insertions, 9 deletions
diff --git a/src/path-search.cpp b/src/path-search.cpp
index cf7d41d5..47ce6f61 100644
--- a/src/path-search.cpp
+++ b/src/path-search.cpp
@@ -176,10 +176,52 @@ auto path_search::make_neighbor_tile_bbox(Vector2i coord, Vector2ub own_size, ro
return { Vector2(min + shift), Vector2(max + shift) };
}
-Optional<path_search_result>
-path_search::operator()(world& w, object_id own_id,
- global_coords from, Vector2b from_offset, Vector2ub size,
- global_coords to, Vector2b to_offset)
+auto path_search::get_walkable_neighbor_tiles(world& w, global_coords coord, Vector2ub size, object_id own_id) -> neighbors
+{
+ auto ch = chunk_coords_{ coord.chunk(), coord.z() };
+ auto pos = Vector2i(coord.local());
+
+ if (auto [min, max] = make_neighbor_tile_bbox(pos, size, rotation_COUNT);
+ !is_passable(w, ch, min, max, own_id))
+ return {};
+
+ neighbors ns;
+
+ using enum rotation;
+ constexpr struct {
+ Vector2i off;
+ rotation r = {};
+ } nbs[] = {
+ { { 0, -1 }, N },
+ { { 1, 0 }, E },
+ { { 0, 1 }, S },
+ { { -1, 0 }, W },
+ };
+
+ for (auto [off, dir] : nbs)
+ {
+ auto [min, max] = make_neighbor_tile_bbox(pos, size, dir);
+ if (is_passable(w, ch, min, max, own_id))
+ ns.neighbors[ns.size++] = coord + off;
+ }
+
+ return ns;
+}
+
+auto path_search::bbox_union(bbox bb, Vector2i coord, Vector2b offset, Vector2ub size) -> bbox
+{
+ auto center = coord * iTILE_SIZE2 + Vector2i(offset);
+ auto min = center - Vector2i(size / 2u);
+ auto max = center + Vector2i(size);
+ return {
+ .min = Math::min(bb.min, Vector2(min)),
+ .max = Math::max(bb.max, Vector2(max)),
+ };
+}
+
+Optional<path_search_result> path_search::operator()(world& w, object_id own_id,
+ global_coords from, Vector2b from_offset, Vector2ub size,
+ global_coords to, Vector2b to_offset)
{
if (from.z() != to.z()) [[unlikely]]
return {};
diff --git a/src/path-search.hpp b/src/path-search.hpp
index 68cf41a4..4d3c7d23 100644
--- a/src/path-search.hpp
+++ b/src/path-search.hpp
@@ -41,9 +41,9 @@ struct path_search_result final
const global_coords* data() const;
private:
- mutable path_search_result* _next;
+ mutable path_search_result* _next = nullptr;
std::unique_ptr<global_coords[]> _path;
- size_t _size;
+ size_t _size = 0;
};
class path_search final
@@ -54,7 +54,7 @@ class path_search final
auto end() const { return neighbors.data() + size; }
std::array<global_coords, 4> neighbors;
- uint8_t size;
+ uint8_t size = 0;
};
struct chunk_tiles_cache
@@ -91,7 +91,8 @@ public:
static bool is_passable(world& w, global_coords coord, Vector2b offset, Vector2ub size, object_id own_id);
static bbox make_neighbor_tile_bbox(Vector2i coord, Vector2ub own_size, rotation r);
- static neighbors get_walkable_neighbor_tiles(world& w, global_coords pos, Vector2 size, object_id own_id);
+ static bbox bbox_union(bbox bb, Vector2i coord, Vector2b offset, Vector2ub size);
+ static neighbors get_walkable_neighbor_tiles(world& w, global_coords coord, Vector2ub size, object_id own_id);
};
} // namespace floormat
diff --git a/src/world.hpp b/src/world.hpp
index bda8d3a4..9b776c5e 100644
--- a/src/world.hpp
+++ b/src/world.hpp
@@ -98,7 +98,7 @@ public:
[[nodiscard]] object_id make_id() { return ++_object_counter; }
void set_object_counter(object_id value);
- struct neighbor_pair final { chunk* c; chunk_coords_ coord; };
+ struct neighbor_pair final { chunk* c = nullptr; chunk_coords_ coord; };
std::array<neighbor_pair, 8> neighbors(chunk_coords_ coord);