summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/character.cpp2
-rw-r--r--src/character.hpp3
-rw-r--r--src/chunk.cpp5
-rw-r--r--src/chunk.hpp5
-rw-r--r--src/entity.cpp31
-rw-r--r--src/entity.hpp7
-rw-r--r--src/scenery.cpp4
-rw-r--r--src/scenery.hpp2
-rw-r--r--src/world.cpp8
-rw-r--r--src/world.hpp8
10 files changed, 40 insertions, 35 deletions
diff --git a/src/character.cpp b/src/character.cpp
index a0bfbbd6..7293fddc 100644
--- a/src/character.cpp
+++ b/src/character.cpp
@@ -51,7 +51,7 @@ constexpr auto arrows_to_dir(bool L, bool R, bool U, bool D)
} // namespace
-character::character(std::uint64_t id, struct world& w, entity_type type) : entity{id, w, type}
+character::character(std::uint64_t id, struct chunk& c, entity_type type) : entity{id, c, type}
{
atlas = loader.anim_atlas("npc-walk", loader.ANIM_PATH);
bbox_size = {12, 12};
diff --git a/src/character.hpp b/src/character.hpp
index d69b98dc..1733c2dd 100644
--- a/src/character.hpp
+++ b/src/character.hpp
@@ -18,12 +18,11 @@ struct character final : entity
private:
int allocate_frame_time(float dt);
static Vector2 move_vec(int left_right, int top_bottom);
- character(std::uint64_t id, struct world& w, entity_type type);
friend struct world;
+ character(std::uint64_t id, struct chunk& c, entity_type type);
Vector2s offset_frac;
-
bool b_L : 1 = false, b_R : 1 = false, b_U : 1 = false, b_D : 1 = false;
};
diff --git a/src/chunk.cpp b/src/chunk.cpp
index 6edced05..7f8623dc 100644
--- a/src/chunk.cpp
+++ b/src/chunk.cpp
@@ -89,7 +89,10 @@ void chunk::mark_modified() noexcept
mark_scenery_modified();
}
-chunk::chunk() noexcept = default;
+chunk::chunk(struct world& w) noexcept : _world{&w}
+{
+}
+
chunk::~chunk() noexcept
{
_teardown = true;
diff --git a/src/chunk.hpp b/src/chunk.hpp
index 9f4e2ebd..83764d87 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -50,7 +50,7 @@ struct chunk final
bool empty(bool force = false) const noexcept;
- chunk() noexcept;
+ chunk(struct world& w) noexcept;
~chunk() noexcept;
chunk(const chunk&) = delete;
chunk& operator=(const chunk&) = delete;
@@ -102,6 +102,8 @@ struct chunk final
const RTree* rtree() const noexcept;
RTree* rtree() noexcept;
+ struct world& world() noexcept { return *_world; }
+
template<typename F>
requires requires(F fun) { fun(); }
void with_scenery_update(entity& e, F&& fun);
@@ -129,6 +131,7 @@ private:
std::vector<std::array<UnsignedShort, 6>> scenery_indexes;
std::vector<std::array<vertex, 4>> scenery_vertexes;
+ struct world* _world;
GL::Mesh ground_mesh{NoCreate}, wall_mesh{NoCreate}, scenery_mesh{NoCreate};
RTree _rtree;
diff --git a/src/entity.cpp b/src/entity.cpp
index 3cfea061..9f70a5b3 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -13,13 +13,13 @@ entity_proto::~entity_proto() noexcept = default;
entity_proto::entity_proto() = default;
entity_proto::entity_proto(const entity_proto&) = default;
-entity::entity(std::uint64_t id, struct world& w, entity_type type) noexcept :
- id{id}, w{w}, type{type}
+entity::entity(std::uint64_t id, struct chunk& c, entity_type type) noexcept :
+ id{id}, c{c}, type{type}
{
}
-entity::entity(std::uint64_t id, struct world& w, entity_type type, const entity_proto& proto) noexcept :
- id{id}, w{w}, atlas{proto.atlas},
+entity::entity(std::uint64_t id, struct chunk& c, entity_type type, const entity_proto& proto) noexcept :
+ id{id}, c{c}, atlas{proto.atlas},
offset{proto.offset}, bbox_offset{proto.bbox_offset},
bbox_size{proto.bbox_size}, delta{proto.delta},
frame{proto.frame}, type{type}, r{proto.r}, pass{proto.pass}
@@ -30,17 +30,14 @@ entity::entity(std::uint64_t id, struct world& w, entity_type type, const entity
entity::~entity() noexcept
{
fm_debug_assert(id);
- if (w.is_teardown()) [[unlikely]]
+ if (c._teardown || c._world->_teardown) [[unlikely]]
return;
- auto& c = chunk();
- if (!c._teardown) [[likely]]
- {
- if (chunk::bbox bb; c._bbox_for_scenery(*this, bb))
- c._remove_bbox(bb);
- auto it = std::find_if(c._entities.cbegin(), c._entities.cend(), [id = id](const auto& x) { return x->id == id; });
- fm_debug_assert(it != c._entities.cend());
- c._entities.erase(it);
- }
+ auto& w = *c._world;
+ if (chunk::bbox bb; c._bbox_for_scenery(*this, bb))
+ c._remove_bbox(bb);
+ auto it = std::find_if(c._entities.cbegin(), c._entities.cend(), [id = id](const auto& x) { return x->id == id; });
+ fm_debug_assert(it != c._entities.cend());
+ c._entities.erase(it);
w.do_kill_entity(id);
}
@@ -63,7 +60,7 @@ std::uint32_t entity::ordinal(local_coords xy, Vector2b offset)
struct chunk& entity::chunk() const
{
- return w[coord.chunk()];
+ return c;
}
auto entity::iter() const -> It
@@ -84,6 +81,7 @@ bool entity::operator==(const entity_proto& o) const
void entity::rotate(It, struct chunk&, rotation new_r)
{
+ auto& w = *c._world;
w[coord.chunk()].with_scenery_update(*this, [&]() {
bbox_offset = rotate_point(bbox_offset, r, new_r);
bbox_size = rotate_size(bbox_size, r, new_r);
@@ -116,6 +114,7 @@ Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vect
bool entity::can_move_to(Vector2i delta, struct chunk& c)
{
auto [coord_, offset_] = normalize_coords(coord, offset, delta);
+ auto& w = *c._world;
auto& c_ = coord.chunk() == coord_.chunk() ? c : w[coord_.chunk()];
const auto center = Vector2(coord_.local())*TILE_SIZE2 + Vector2(offset_) + Vector2(bbox_offset),
@@ -137,7 +136,7 @@ void entity::move(It it, Vector2i delta, struct chunk& c)
{
auto e_ = *it;
auto& e = *e_;
- auto& w = e.w;
+ auto& w = *c._world;
auto& coord = e.coord;
auto& offset = e.offset;
auto& es = c._entities;
diff --git a/src/entity.hpp b/src/entity.hpp
index 18c588bd..34aec0af 100644
--- a/src/entity.hpp
+++ b/src/entity.hpp
@@ -11,6 +11,7 @@ namespace floormat {
template<typename T> struct entity_type_;
struct anim_atlas;
struct world;
+struct chunk;
enum class entity_type : std::uint8_t {
none, character, scenery,
@@ -41,7 +42,7 @@ struct entity
using It = typename std::vector<std::shared_ptr<entity>>::const_iterator;
const std::uint64_t id = 0;
- world& w;
+ struct chunk& c;
std::shared_ptr<anim_atlas> atlas;
global_coords coord;
Vector2b offset, bbox_offset;
@@ -73,8 +74,8 @@ struct entity
friend struct world;
protected:
- entity(std::uint64_t id, struct world& w, entity_type type) noexcept;
- entity(std::uint64_t id, struct world& w, entity_type type, const entity_proto& proto) noexcept;
+ entity(std::uint64_t id, struct chunk& c, entity_type type) noexcept;
+ entity(std::uint64_t id, struct chunk& c, entity_type type, const entity_proto& proto) noexcept;
};
} // namespace floormat
diff --git a/src/scenery.cpp b/src/scenery.cpp
index cf58a8de..8808d7ed 100644
--- a/src/scenery.cpp
+++ b/src/scenery.cpp
@@ -92,8 +92,8 @@ bool scenery::operator==(const entity_proto& e0) const
closing == s0.closing && interactive == s0.interactive;
}
-scenery::scenery(std::uint64_t id, struct world& w, entity_type type, const scenery_proto& proto) :
- entity{id, w, type}, sc_type{proto.sc_type}, active{proto.active},
+scenery::scenery(std::uint64_t id, struct chunk& c, entity_type type, const scenery_proto& proto) :
+ entity{id, c, type}, sc_type{proto.sc_type}, active{proto.active},
closing{proto.closing}, interactive{proto.interactive}
{
fm_assert(type == proto.type);
diff --git a/src/scenery.hpp b/src/scenery.hpp
index 6f8afadd..dfc0e416 100644
--- a/src/scenery.hpp
+++ b/src/scenery.hpp
@@ -47,7 +47,7 @@ struct scenery final : entity
private:
friend struct world;
- scenery(std::uint64_t id, struct world& w, entity_type type, const scenery_proto& proto);
+ scenery(std::uint64_t id, struct chunk& c, entity_type type, const scenery_proto& proto);
};
template<> struct entity_type_<scenery> : std::integral_constant<entity_type, entity_type::scenery> {};
diff --git a/src/world.cpp b/src/world.cpp
index f50853cf..37b78616 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -32,7 +32,7 @@ chunk& world::operator[](chunk_coords coord) noexcept
{
auto& [c, coord2] = _last_chunk;
if (coord != coord2)
- c = &_chunks.try_emplace(coord).first->second;
+ c = &_chunks.try_emplace(coord, *this).first->second;
coord2 = coord;
return *c;
}
@@ -88,14 +88,14 @@ void world::collect(bool force)
static constexpr std::uint64_t min_id = 1u << 16;
std::uint64_t world::entity_counter = min_id;
-void world::do_make_entity(const std::shared_ptr<entity>& e, global_coords pos)
+void world::do_make_entity(const std::shared_ptr<entity>& e, chunk& c, global_coords pos)
{
- fm_debug_assert(e->id > min_id && &e->w == this);
+ fm_debug_assert(e->id > min_id && &c.world() == this);
fm_assert(Vector2ui(e->bbox_size).product() > 0);
fm_assert(e->type != entity_type::none);
e->coord = pos;
_entities[e->id] = e;
- operator[](pos.chunk()).add_entity(e);
+ c.add_entity(e);
}
void world::do_kill_entity(std::uint64_t id)
diff --git a/src/world.hpp b/src/world.hpp
index 6781ee3c..5da700e3 100644
--- a/src/world.hpp
+++ b/src/world.hpp
@@ -37,7 +37,7 @@ private:
explicit world(std::size_t capacity);
- void do_make_entity(const std::shared_ptr<entity>& e, global_coords pos);
+ void do_make_entity(const std::shared_ptr<entity>& e, chunk& c, global_coords pos);
void do_kill_entity(std::uint64_t id);
friend struct entity;
@@ -67,12 +67,12 @@ public:
std::size_t collect_threshold() const noexcept { return _collect_every; }
template<typename T, typename... Xs>
- requires requires { T{std::uint64_t(), std::declval<world&>(), entity_type(), std::declval<Xs>()...}; }
+ requires requires(chunk& c) { T{std::uint64_t(), c, entity_type(), std::declval<Xs>()...}; }
std::shared_ptr<T> make_entity(global_coords pos, Xs&&... xs)
{
static_assert(std::is_base_of_v<entity, T>);
- auto ret = std::shared_ptr<T>(new T{++entity_counter, *this, entity_type_<T>::value, std::forward<Xs>(xs)...});
- do_make_entity(std::static_pointer_cast<entity>(ret), pos);
+ auto ret = std::shared_ptr<T>(new T{++entity_counter, operator[](pos.chunk()), entity_type_<T>::value, std::forward<Xs>(xs)...});
+ do_make_entity(std::static_pointer_cast<entity>(ret), ret->c, pos);
return ret;
}