diff options
-rw-r--r-- | editor/imgui.cpp | 7 | ||||
-rw-r--r-- | editor/inspect-types.cpp | 2 | ||||
-rw-r--r-- | editor/update.cpp | 6 | ||||
-rw-r--r-- | src/character.cpp | 6 | ||||
-rw-r--r-- | src/character.hpp | 2 | ||||
-rw-r--r-- | src/chunk-collision.cpp | 1 | ||||
-rw-r--r-- | src/chunk-render.cpp | 2 | ||||
-rw-r--r-- | src/chunk.cpp | 4 | ||||
-rw-r--r-- | src/chunk.hpp | 2 | ||||
-rw-r--r-- | src/chunk.inl | 4 | ||||
-rw-r--r-- | src/entity-type.hpp | 10 | ||||
-rw-r--r-- | src/entity.cpp | 35 | ||||
-rw-r--r-- | src/entity.hpp | 19 | ||||
-rw-r--r-- | src/scenery.cpp | 6 | ||||
-rw-r--r-- | src/scenery.hpp | 6 | ||||
-rw-r--r-- | src/world.hpp | 1 |
16 files changed, 67 insertions, 46 deletions
diff --git a/editor/imgui.cpp b/editor/imgui.cpp index 4ce19403..05396414 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -154,12 +154,11 @@ void app::do_popup_menu() if (auto b1 = begin_popup(SCENERY_POPUP_NAME)) { auto iter = sc->iter(); - auto& c = sc->chunk(); - if (ImGui::MenuItem("Activate", nullptr, false, sc->can_activate(iter, c))) - sc->activate(iter, c); + if (ImGui::MenuItem("Activate", nullptr, false, sc->can_activate(iter))) + sc->activate(iter); if (auto next_rot = sc->atlas->next_rotation_from(sc->r); ImGui::MenuItem("Rotate", nullptr, false, next_rot != sc->r)) - sc->rotate(iter, c, next_rot); + sc->rotate(iter, next_rot); ImGui::Separator(); diff --git a/editor/inspect-types.cpp b/editor/inspect-types.cpp index 9b14c132..ead95c08 100644 --- a/editor/inspect-types.cpp +++ b/editor/inspect-types.cpp @@ -32,7 +32,7 @@ struct entity_accessors<scenery> { }, entity::type<rotation>::field{"rotation"_s, [](const scenery& x) { return x.r; }, - [](scenery& x, rotation r) { x.rotate(x.iter(), x.chunk(), r); }, + [](scenery& x, rotation r) { x.rotate(x.iter(), r); }, }, entity::type<std::uint16_t>::field{"frame"_s, [](const scenery& x) { return x.frame; }, diff --git a/editor/update.cpp b/editor/update.cpp index 24fd3086..dd985b88 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -69,7 +69,7 @@ void app::do_mouse_up_down(std::uint8_t button, bool is_down, int mods) if (button == mouse_button_left) { if (auto* cl = find_clickable_scenery(*cursor.pixel)) - return (void)cl->e->activate(cl->e->iter(), cl->e->chunk()); + return (void)cl->e->activate(cl->e->iter()); } // TODO it should open on mouseup if still on the same item as on mousedown else if (button == mouse_button_right) @@ -110,7 +110,7 @@ void app::do_rotate(bool backward) auto r = backward ? e.atlas->prev_rotation_from(e.r) : e.atlas->next_rotation_from(e.r); if (r != e.r) { - e.rotate(e.iter(), e.chunk(), r); + e.rotate(e.iter(), r); e.chunk().mark_scenery_modified(); } } @@ -192,7 +192,7 @@ void app::update_world(float dt) { auto iter = es.cbegin() + std::ptrdiff_t(i); auto& e = *es[i]; - c.with_scenery_update(e, [&] { return e.update(iter, c, dt); }); + c.with_scenery_update(e, [&] { return e.update(iter, dt); }); } } } diff --git a/src/character.cpp b/src/character.cpp index 7293fddc..80bfaf8b 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -83,7 +83,7 @@ void character::set_keys(bool L, bool R, bool U, bool D) b_D = D; } -bool character::update(It it, struct chunk& c, float dt) +bool character::update(It it, float dt) { auto [lr, ud, rot] = arrows_to_dir(b_L, b_R, b_U, b_D); @@ -109,8 +109,8 @@ bool character::update(It it, struct chunk& c, float dt) auto offset_ = vec + Vector2(offset_frac) * inv_frac; offset_frac = Vector2s(Vector2(std::fmod(offset_[0], 1.f), std::fmod(offset_[1], 1.f)) * frac); auto off_i = Vector2i(offset_); - if (can_move_to(off_i, c)) - entity::move(it, off_i, c); + if (can_move_to(off_i)) + entity::move(it, off_i); ++frame %= atlas->info().nframes; } //Debug{} << "pos" << Vector2i(pos.local()); diff --git a/src/character.hpp b/src/character.hpp index 1733c2dd..4c02a764 100644 --- a/src/character.hpp +++ b/src/character.hpp @@ -13,7 +13,7 @@ struct character final : entity { ~character() override; void set_keys(bool L, bool R, bool U, bool D); - bool update(It it, struct chunk& c, float dt) override; + bool update(It it, float dt) override; private: int allocate_frame_time(float dt); diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp index 032c9d7d..d05a3a71 100644 --- a/src/chunk-collision.cpp +++ b/src/chunk-collision.cpp @@ -1,6 +1,7 @@ #include "chunk.hpp" #include "RTree.hpp" #include "tile-atlas.hpp" +#include "entity.hpp" #include <bit> #include <Corrade/Containers/PairStl.h> diff --git a/src/chunk-render.cpp b/src/chunk-render.cpp index 28a8d7bc..823e72ab 100644 --- a/src/chunk-render.cpp +++ b/src/chunk-render.cpp @@ -112,7 +112,7 @@ auto chunk::ensure_scenery_mesh() noexcept -> scenery_mesh_tuple const auto count = fm_begin( std::size_t ret = 0; for (const auto& e : _entities) - ret += e->atlas->info().fps == 0; + ret += !e->is_dynamic(); return ret; ); diff --git a/src/chunk.cpp b/src/chunk.cpp index 7f8623dc..f4ba079d 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -107,7 +107,7 @@ bool chunk::bbox::operator==(const bbox& other) const noexcept = default; void chunk::add_entity_unsorted(const std::shared_ptr<entity>& e) { - if (e->atlas->info().fps == 0) + if (!e->is_dynamic()) mark_scenery_modified(false); if (bbox bb; _bbox_for_scenery(*e, bb)) _add_bbox(bb); @@ -140,7 +140,7 @@ void chunk::add_entity(const std::shared_ptr<entity>& e) void chunk::remove_entity(entity_const_iterator it) { const auto& e = *it; - if (e->atlas->info().fps == 0) + if (!e->is_dynamic()) mark_scenery_modified(false); if (bbox bb; _bbox_for_scenery(*e, bb)) _remove_bbox(bb); diff --git a/src/chunk.hpp b/src/chunk.hpp index 83764d87..dc784685 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -1,7 +1,6 @@ #pragma once #include "tile.hpp" #include "tile-iterator.hpp" -#include "scenery.hpp" #include <type_traits> #include <array> #include <memory> @@ -12,6 +11,7 @@ namespace floormat { struct anim_atlas; struct entity; +struct entity_proto; enum class collision : std::uint8_t { view, shoot, move, diff --git a/src/chunk.inl b/src/chunk.inl index 3d40c30e..bbfec37a 100644 --- a/src/chunk.inl +++ b/src/chunk.inl @@ -1,6 +1,6 @@ #pragma once #include "chunk.hpp" -#include "anim-atlas.hpp" +#include "scenery.hpp" namespace floormat { @@ -30,7 +30,7 @@ void chunk::with_scenery_update(entity& s, F&& fun) if (bbox bb; !is_passability_modified()) if (bool b = _bbox_for_scenery(s, bb); b != b0 || bb != bb0) _replace_bbox(bb0, bb, b0, b); - if (!is_scenery_modified() && s.atlas->info().fps == 0 && s != s0) + if (!is_scenery_modified() && !s.is_dynamic() && s != s0) mark_scenery_modified(false); } diff --git a/src/entity-type.hpp b/src/entity-type.hpp new file mode 100644 index 00000000..079cec77 --- /dev/null +++ b/src/entity-type.hpp @@ -0,0 +1,10 @@ +#pragma once +#include <cstdint> + +namespace floormat { + +enum class entity_type : std::uint8_t { + none, character, scenery, +}; + +} // namespace floormat diff --git a/src/entity.cpp b/src/entity.cpp index 9f70a5b3..23e9887d 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -2,6 +2,7 @@ #include "world.hpp" #include "rotation.inl" #include "chunk.inl" +#include "anim-atlas.hpp" #include "RTree.hpp" #include <algorithm> @@ -35,9 +36,10 @@ entity::~entity() noexcept 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); + auto& es = c._entities; + auto it = std::find_if(es.cbegin(), es.cend(), [id = id](const auto& x) { return x->id == id; }); + fm_debug_assert(it != es.cend()); + es.erase(it); w.do_kill_entity(id); } @@ -66,8 +68,11 @@ struct chunk& entity::chunk() const auto entity::iter() const -> It { auto& c = chunk(); - auto it = std::find_if(c._entities.cbegin(), c._entities.cend(), [id = id](const auto& x) { return x->id == id; }); - fm_assert(it != c._entities.cend()); + auto& es = c._entities; + auto it = std::lower_bound(es.cbegin(), es.cend(), nullptr, [ord = ordinal()](const auto& a, const auto&) { return a->ordinal() < ord; }); + fm_assert(it != es.cend()); + it = std::find_if(it, es.cend(), [id = id](const auto& x) { return x->id == id; }); + fm_assert(it != es.cend()); return it; } @@ -79,7 +84,7 @@ bool entity::operator==(const entity_proto& o) const bbox_size == o.bbox_size && delta == o.delta; } -void entity::rotate(It, struct chunk&, rotation new_r) +void entity::rotate(It, rotation new_r) { auto& w = *c._world; w[coord.chunk()].with_scenery_update(*this, [&]() { @@ -111,7 +116,7 @@ Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vect return { coord, Vector2b(off_new) }; } -bool entity::can_move_to(Vector2i delta, struct chunk& c) +bool entity::can_move_to(Vector2i delta) { auto [coord_, offset_] = normalize_coords(coord, offset, delta); auto& w = *c._world; @@ -132,10 +137,11 @@ bool entity::can_move_to(Vector2i delta, struct chunk& c) return ret; } -void entity::move(It it, Vector2i delta, struct chunk& c) +void entity::move(It it, Vector2i delta) { auto e_ = *it; auto& e = *e_; + auto& c = e.c; auto& w = *c._world; auto& coord = e.coord; auto& offset = e.offset; @@ -145,7 +151,7 @@ void entity::move(It it, Vector2i delta, struct chunk& c) if (coord_ == coord && offset_ == offset) return; - if (e.atlas->info().fps == 0) + if (!e.is_dynamic()) c.mark_scenery_modified(false); bool same_chunk = coord_.chunk() == coord.chunk(); @@ -171,7 +177,7 @@ void entity::move(It it, Vector2i delta, struct chunk& c) else { auto& c2 = w[coord.chunk()]; - if (e.atlas->info().fps == 0) + if (!e.is_dynamic()) c2.mark_scenery_modified(false); c._remove_bbox(bb0); c2._add_bbox(bb1); @@ -197,7 +203,12 @@ entity::operator entity_proto() const return x; } -bool entity::can_activate(It, struct chunk&) const { return false; } -bool entity::activate(It, struct chunk&) { return false; } +bool entity::can_activate(It) const { return false; } +bool entity::activate(It) { return false; } + +bool entity::is_dynamic() const +{ + return atlas->info().fps > 0; +} } // namespace floormat diff --git a/src/entity.hpp b/src/entity.hpp index 34aec0af..6bfad752 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -3,6 +3,7 @@ #include "src/global-coords.hpp" #include "src/rotation.hpp" #include "src/pass-mode.hpp" +#include "src/entity-type.hpp" #include <memory> #include <vector> @@ -13,10 +14,6 @@ struct anim_atlas; struct world; struct chunk; -enum class entity_type : std::uint8_t { - none, character, scenery, -}; - struct entity_proto { std::shared_ptr<anim_atlas> atlas; @@ -62,14 +59,16 @@ struct entity virtual bool operator==(const entity_proto& e0) const; operator entity_proto() const; - virtual bool can_activate(It it, struct chunk& c) const; - virtual bool activate(It it, struct chunk& c); - virtual bool update(It it, struct chunk& c, float dt) = 0; - virtual void rotate(It it, struct chunk& c, rotation r); + virtual bool can_activate(It it) const; + virtual bool activate(It it); + virtual bool update(It it, float dt) = 0; + virtual void rotate(It it, rotation r); static Pair<global_coords, Vector2b> normalize_coords(global_coords coord, Vector2b cur_offset, Vector2i delta); - [[nodiscard]] virtual bool can_move_to(Vector2i delta, struct chunk& c); - static void move(It it, Vector2i delta, struct chunk& c); + [[nodiscard]] virtual bool can_move_to(Vector2i delta); + static void move(It it, Vector2i delta); + void update_bbox(Vector2b bbox_offset, Vector2ub bbox_size); // todo + bool is_dynamic() const; friend struct world; diff --git a/src/scenery.cpp b/src/scenery.cpp index 8808d7ed..a7c21ae2 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -14,12 +14,12 @@ scenery_proto::scenery_proto(const scenery_proto&) = default; scenery_proto::~scenery_proto() noexcept = default; scenery_proto::operator bool() const { return atlas != nullptr; } -bool scenery::can_activate(It, struct chunk&) const +bool scenery::can_activate(It) const { return atlas && interactive; } -bool scenery::update(It, struct chunk&, float dt) +bool scenery::update(It, float dt) { auto& s = *this; if (!s.active) @@ -60,7 +60,7 @@ bool scenery::update(It, struct chunk&, float dt) } } -bool scenery::activate(It, struct chunk&) +bool scenery::activate(It) { auto& s = *this; if (s.active) diff --git a/src/scenery.hpp b/src/scenery.hpp index dfc0e416..8f0d5d27 100644 --- a/src/scenery.hpp +++ b/src/scenery.hpp @@ -40,9 +40,9 @@ struct scenery final : entity std::uint8_t closing : 1 = false; std::uint8_t interactive : 1 = false; - bool can_activate(It it, struct chunk& c) const override; - bool activate(It it, struct chunk& c) override; - bool update(It it, struct chunk& c, float dt) override; + bool can_activate(It it) const override; + bool activate(It it) override; + bool update(It it, float dt) override; bool operator==(const entity_proto& p) const override; private: diff --git a/src/world.hpp b/src/world.hpp index 5da700e3..dfd7a71a 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -3,6 +3,7 @@ #include "compat/defs.hpp" #include "chunk.hpp" #include "global-coords.hpp" +#include "entity-type.hpp" #include <cstddef> #include <unordered_map> #include <memory> |