summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-03-15 15:43:59 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-03-15 15:43:59 +0100
commit23eae734c5e8a49c02e48fe0b401d610abfee9c8 (patch)
tree02311af36b8c2a10f8b69543b7b38e498bd42bd8
parent2e0c0009806860e4e8ac24663afdc5d926d1213f (diff)
a
-rw-r--r--editor/imgui.cpp7
-rw-r--r--editor/inspect-types.cpp2
-rw-r--r--editor/update.cpp6
-rw-r--r--src/character.cpp6
-rw-r--r--src/character.hpp2
-rw-r--r--src/chunk-collision.cpp1
-rw-r--r--src/chunk-render.cpp2
-rw-r--r--src/chunk.cpp4
-rw-r--r--src/chunk.hpp2
-rw-r--r--src/chunk.inl4
-rw-r--r--src/entity-type.hpp10
-rw-r--r--src/entity.cpp35
-rw-r--r--src/entity.hpp19
-rw-r--r--src/scenery.cpp6
-rw-r--r--src/scenery.hpp6
-rw-r--r--src/world.hpp1
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>