summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/astar.hpp4
-rw-r--r--src/chunk-region.cpp37
-rw-r--r--src/chunk.hpp6
-rw-r--r--src/path-search-pred.hpp18
-rw-r--r--src/path-search.cpp24
-rw-r--r--src/path-search.hpp22
6 files changed, 76 insertions, 35 deletions
diff --git a/src/astar.hpp b/src/astar.hpp
index bc2ecd6f..0a46ec6d 100644
--- a/src/astar.hpp
+++ b/src/astar.hpp
@@ -46,7 +46,7 @@ public:
point pt;
};
- using pred = path_search::pred;
+ using pred = detail_astar::pred;
fm_DECLARE_DELETED_COPY_ASSIGNMENT(astar);
@@ -57,7 +57,7 @@ public:
// todo add simple bresenham short-circuit
path_search_result Dijkstra(world& w, point from, point to,
object_id own_id, uint32_t max_dist, Vector2ub own_size,
- int debug = 0, const pred& p = path_search::never_continue());
+ int debug = 0, const pred& p = detail_astar::never_continue());
private:
static constexpr auto initial_capacity = TILE_COUNT * 16 * detail_astar::div_factor*detail_astar::div_factor;
diff --git a/src/chunk-region.cpp b/src/chunk-region.cpp
index 253c1d4f..67c474bc 100644
--- a/src/chunk-region.cpp
+++ b/src/chunk-region.cpp
@@ -1,6 +1,10 @@
#include "chunk-region.hpp"
#include "path-search-bbox.hpp"
#include "world.hpp"
+#include "collision.hpp"
+#include "object.hpp"
+#include "compat/function2.hpp"
+#include <bit>
#include <array>
#include <Corrade/Containers/GrowableArray.h>
#include <Magnum/Math/Functions.h>
@@ -13,6 +17,7 @@ using detail_astar::bbox;
using detail_astar::div_factor;
using detail_astar::div_size;
using detail_astar::div_count;
+using detail_astar::pred;
static_assert(div_count.x() == div_count.y());
static_assert((iTILE_SIZE2 % div_size).isZero());
@@ -44,11 +49,11 @@ constexpr bbox<Int> make_pos(Vector2i ij, Vector2i from)
return bbox_from_pos2(pos, pos0);
}
-bool check_pos(chunk& c, const std::array<chunk*, 8>& nbs, Vector2i ij, Vector2i from)
+bool check_pos(chunk& c, const std::array<chunk*, 8>& nbs, Vector2i ij, Vector2i from, const pred& p)
{
auto pos = make_pos(ij, from);
- bool ret = path_search::is_passable_(&c, nbs, Vector2(pos.min), Vector2(pos.max), 0);
- //if (ret) Debug{} << "check" << ij << ij/div_factor << ij % div_factor << pos.min << pos.max << ret;
+ bool ret = path_search::is_passable_(&c, nbs, Vector2(pos.min), Vector2(pos.max), 0, p);
+ //if (ret) Debug{} << "check" << ij << pos.min << pos.max << ret;
//Debug{} << "check" << ij << pos.min << pos.max << ret;
return ret;
}
@@ -117,6 +122,22 @@ void chunk::delete_pass_region(pass_region*& ptr)
}
}
+pred chunk::default_region_predicate() noexcept
+{
+ return [this](collision_data data) {
+ auto x = std::bit_cast<collision_data>(data);
+ // XXX 'scenery' is used for all object types
+ if (x.tag == (uint64_t)collision_type::scenery)
+ {
+ auto& w = _world;
+ auto obj = w->find_object(x.data);
+ if (obj->type() == object_type::critter)
+ return path_search_continue::pass;
+ }
+ return path_search_continue::blocked;
+ };
+}
+
auto chunk::get_pass_region() -> const pass_region*
{
if (!_region_modified)
@@ -140,6 +161,12 @@ void chunk::mark_region_modified() noexcept { _region_modified = true; }
void chunk::make_pass_region(pass_region& ret)
{
+ return make_pass_region(ret, default_region_predicate());
+}
+
+void chunk::make_pass_region(pass_region& ret, const pred& f)
+{
+ ret = {};
auto& tmp = get_tmp();
const auto nbs = _world->neighbors(_coord);
@@ -161,7 +188,7 @@ void chunk::make_pass_region(pass_region& ret)
{
auto positions = get_positions(i);
for (auto i = 0u; i < 4; i++)
- if (check_pos(*this, nbs, positions[i], fours[i]))
+ if (check_pos(*this, nbs, positions[i], fours[i], f))
tmp.append(ret.bits, positions[i]);
}
@@ -174,7 +201,7 @@ void chunk::make_pass_region(pass_region& ret)
Vector2i from = fours[i], pos{p - from};
if ((uint32_t)pos.x() >= div_count.x() || (uint32_t)pos.y() >= div_count.y()) [[unlikely]]
continue;
- if (tmp.check_visited(ret.bits, pos, i) && check_pos(*this, nbs, pos, from))
+ if (tmp.check_visited(ret.bits, pos, i) && check_pos(*this, nbs, pos, from, f))
tmp.append(ret.bits, pos);
}
}
diff --git a/src/chunk.hpp b/src/chunk.hpp
index 5404d25b..0efe9847 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -5,7 +5,7 @@
#include "src/RTree-fwd.h"
#include "global-coords.hpp"
#include "wall-defs.hpp"
-#include "collision.hpp"
+#include "path-search-pred.hpp"
#include <type_traits>
#include <array>
#include <Corrade/Containers/Array.h>
@@ -119,8 +119,10 @@ public:
static constexpr size_t max_wall_quad_count =
TILE_COUNT*Wall::Direction_COUNT*(Wall::Group_COUNT+4);
+ detail_astar::pred default_region_predicate() noexcept;
const pass_region* get_pass_region();
void make_pass_region(pass_region& ret);
+ void make_pass_region(pass_region& ret, const detail_astar::pred& f);
private:
struct ground_stuff
@@ -162,7 +164,7 @@ private:
struct bbox final // NOLINT(cppcoreguidelines-pro-type-member-init)
{
- object_id id;
+ object_id id; // todo change to collision_data
Vector2i start, end;
bool operator==(const bbox& other) const noexcept;
diff --git a/src/path-search-pred.hpp b/src/path-search-pred.hpp
new file mode 100644
index 00000000..f0f99c3e
--- /dev/null
+++ b/src/path-search-pred.hpp
@@ -0,0 +1,18 @@
+#pragma once
+#include "compat/function2.fwd.hpp"
+#include "collision.hpp"
+
+namespace floormat {
+
+enum class path_search_continue : bool { pass = false, blocked = true };
+
+} // namespace floormat
+
+namespace floormat::detail_astar {
+
+using pred = fu2::function_view<path_search_continue(collision_data) const>;
+
+const pred& never_continue() noexcept;
+const pred& always_continue() noexcept;
+
+} // namespace floormat::detail_astar
diff --git a/src/path-search.cpp b/src/path-search.cpp
index 769bc4b9..a41c2820 100644
--- a/src/path-search.cpp
+++ b/src/path-search.cpp
@@ -8,24 +8,24 @@
#include "compat/function2.hpp"
#include <bit>
-namespace floormat {
-
-using namespace detail_astar;
+namespace floormat::detail_astar {
namespace {
-
-constexpr int div_BITS = 2;
-static_assert(1 << div_BITS == div_factor);
-
constexpr auto never_continue_1 = [](collision_data) constexpr { return path_search_continue::blocked; };
-constexpr auto never_continue_ = path_search::pred{never_continue_1};
+constexpr auto never_continue_ = pred{never_continue_1};
constexpr auto always_continue_1 = [](collision_data) constexpr { return path_search_continue::pass; };
-constexpr auto always_continue_ = path_search::pred{always_continue_1};
-
+constexpr auto always_continue_ = pred{always_continue_1};
} // namespace
-auto path_search::never_continue() noexcept -> const pred& { return never_continue_; }
-auto path_search::always_continue() noexcept -> const pred& { return always_continue_; }
+const pred& never_continue() noexcept { return never_continue_; }
+const pred& always_continue() noexcept { return always_continue_; }
+//static_assert(1 << 2 == div_factor);
+
+} // namespace floormat::detail_astar
+
+namespace floormat {
+
+using namespace detail_astar;
bool path_search::is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p)
{
diff --git a/src/path-search.hpp b/src/path-search.hpp
index daf3379d..05516676 100644
--- a/src/path-search.hpp
+++ b/src/path-search.hpp
@@ -2,9 +2,8 @@
#include "tile-constants.hpp"
#include "global-coords.hpp"
#include "object-id.hpp"
-#include "collision.hpp"
-#include "compat/function2.fwd.hpp"
#include "path-search-result.hpp"
+#include "path-search-pred.hpp"
#include <array>
namespace floormat {
@@ -30,26 +29,21 @@ constexpr inline auto div_count = iTILE_SIZE2 * TILE_MAX_DIM / detail_astar::div
namespace floormat {
struct path_search_result;
-enum class path_search_continue : bool { pass = false, blocked = true };
class path_search final
{
friend struct path_search_result;
template<typename T> using bbox = detail_astar::bbox<T>;
+ using pred = detail_astar::pred;
public:
- using pred = fu2::function_view<path_search_continue(collision_data) const>;
-
- static const pred& never_continue() noexcept;
- static const pred& always_continue() noexcept;
-
- static bool is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue());
+ static bool is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p = detail_astar::never_continue());
static bool is_passable_(chunk* c0, const std::array<chunk*, 8>& neighbors,
- Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue());
- static bool is_passable(world& w, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = never_continue());
- static bool is_passable(world& w, struct detail_astar::cache& cache, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = never_continue());
- static bool is_passable(world& w, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = never_continue());
- static bool is_passable(world& w, struct detail_astar::cache& cache, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = never_continue());
+ Vector2 min, Vector2 max, object_id own_id, const pred& p = detail_astar::never_continue());
+ static bool is_passable(world& w, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = detail_astar::never_continue());
+ static bool is_passable(world& w, struct detail_astar::cache& cache, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = detail_astar::never_continue());
+ static bool is_passable(world& w, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = detail_astar::never_continue());
+ static bool is_passable(world& w, struct detail_astar::cache& cache, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = detail_astar::never_continue());
};
} // namespace floormat