#pragma once #include "global-coords.hpp" #include "object-id.hpp" #include "rotation.hpp" #include "world.hpp" #include "compat/function2.fwd.hpp" #include "path-search-astar.hpp" #include "path-search-result.hpp" #include #include #include #include namespace Corrade::Containers { template class Optional; template class Pair; } // namespace Corrade::Containers namespace floormat { struct world; struct object; struct chunk; struct path_search_result; class path_search; struct astar_edge; struct astar_hash; struct astar; enum class path_search_continue : bool { pass = false, blocked = true }; class path_search final { friend struct path_search_result; // todo bucketize by array length struct astar astar; public: static constexpr int subdivide_factor = 4; static constexpr auto div_size = iTILE_SIZE2 / subdivide_factor; static constexpr auto min_size = div_size / 2; struct neighbors final { auto begin() const { return data.data(); } auto end() const { return data.data() + size; } std::array data; uint8_t size = 0; operator ArrayView() const; }; #if 0 struct chunk_tiles_cache { std::bitset can_go_north{true}, can_go_west{true}; }; struct chunk_cache { Array array; Vector2i start, size; // in chunks }; #endif struct obj_position { Vector2 center, size; }; template struct bbox { VectorTypeFor<2, T> min, max; }; #if 0 chunk_cache cache; #endif using pred = fu2::function_view; static const pred& never_continue() noexcept; static const pred& always_continue() noexcept; // todo add simple bresenham short-circuit path_search_result Dijkstra(world& w, Vector2ub own_size, object_id own_id, global_coords from, Vector2b from_offset, global_coords to, Vector2b to_offset, const pred& p = never_continue()); path_search_result Dijkstra(world& w, const object& obj, global_coords to, Vector2b to_offset, const pred& p = never_continue()); static bool is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue()); static bool is_passable_(chunk* c0, const std::array& neighbors, Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue()); static bool is_passable(world& w, chunk_coords_ ch0, Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue()); static bool is_passable(world& w, global_coords coord, Vector2b offset, Vector2ub size, object_id own_id, const pred& p = never_continue()); static bool is_passable(world& w, chunk_coords_ ch0, const bbox& bb, object_id own_id, const pred& p = never_continue()); static bbox neighbor_tile_bbox(Vector2i coord, Vector2ub own_size, Vector2ub div, rotation r); template requires std::is_arithmetic_v static bbox bbox_union(bbox bb, Vector2i coord, Vector2b offset, Vector2ub size); static bbox bbox_union(bbox bb1, bbox bb2); static neighbors neighbor_tiles(world& w, global_coords coord, Vector2ub size, object_id own_id, const pred& p = never_continue()); }; } // namespace floormat