diff options
Diffstat (limited to 'src/scenery.cpp')
-rw-r--r-- | src/scenery.cpp | 134 |
1 files changed, 40 insertions, 94 deletions
diff --git a/src/scenery.cpp b/src/scenery.cpp index e2ebdb49..cf58a8de 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -2,91 +2,30 @@ #include "anim-atlas.hpp" #include "chunk.hpp" #include "compat/assert.hpp" -#include "rotation.inl" -#include "chunk.inl" +#include "world.hpp" #include <algorithm> namespace floormat { -scenery_proto::scenery_proto() noexcept = default; -scenery_proto::scenery_proto(const std::shared_ptr<anim_atlas>& atlas, const scenery& frame) noexcept : - atlas{atlas}, frame{frame} -{} +scenery_proto::scenery_proto() = default; -scenery_proto& scenery_proto::operator=(const scenery_proto&) noexcept = default; -scenery_proto::scenery_proto(const scenery_proto&) noexcept = default; -scenery_proto::operator bool() const noexcept { return atlas != nullptr; } +scenery_proto& scenery_proto::operator=(const scenery_proto&) = default; +scenery_proto::scenery_proto(const scenery_proto&) = default; +scenery_proto::~scenery_proto() noexcept = default; +scenery_proto::operator bool() const { return atlas != nullptr; } -scenery_ref::scenery_ref(struct chunk& c, std::size_t i) noexcept : - atlas{c.scenery_atlas_at(i)}, frame{c.scenery_at(i)}, - c{&c}, idx{std::uint8_t(i)} -{} -scenery_ref::scenery_ref(const scenery_ref&) noexcept = default; -scenery_ref::scenery_ref(scenery_ref&&) noexcept = default; -struct chunk& scenery_ref::chunk() noexcept { return *c; } -std::uint8_t scenery_ref::index() const noexcept { return idx; } - -scenery_ref& scenery_ref::operator=(const scenery_proto& proto) noexcept -{ - atlas = proto.atlas; - frame = proto.frame; - return *this; -} - -scenery_ref::operator scenery_proto() const noexcept { return { atlas, frame }; } -scenery_ref::operator bool() const noexcept { return atlas != nullptr; } - -scenery::scenery(generic_tag_t, const anim_atlas& atlas, rotation r, frame_t frame, - pass_mode passability, bool active, bool interactive, - Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size) : - frame{frame}, - offset{offset}, - bbox_offset{rotate_point(bbox_offset, atlas.first_rotation(), r)}, - bbox_size{rotate_size(bbox_size, atlas.first_rotation(), r)}, - r{r}, type{scenery_type::generic}, - passability{passability}, - active{active}, interactive{interactive} -{ - fm_assert(r < rotation_COUNT); - fm_assert(frame < atlas.group(r).frames.size()); -} - -scenery::scenery(door_tag_t, const anim_atlas& atlas, rotation r, bool is_open, - Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size) : - frame{frame_t(is_open ? 0 : atlas.group(r).frames.size()-1)}, - offset{offset}, - bbox_offset{rotate_point(bbox_offset, atlas.first_rotation(), r)}, - bbox_size{rotate_size(bbox_size, atlas.first_rotation(), r)}, - r{r}, type{scenery_type::door}, - passability{is_open ? pass_mode::pass : pass_mode::blocked}, - interactive{true} -{ - fm_assert(r < rotation_COUNT); - fm_assert(atlas.group(r).frames.size() >= 2); -} - -void scenery_ref::rotate(rotation new_r) -{ - c->with_scenery_update(idx, [&]() { - auto& s = frame; - s.bbox_offset = rotate_point(s.bbox_offset, s.r, new_r); - s.bbox_size = rotate_size(s.bbox_size, s.r, new_r); - s.r = new_r; - }); -} - -bool scenery_ref::can_activate() const noexcept +bool scenery::can_activate(It, struct chunk&) const { - return atlas && frame.interactive; + return atlas && interactive; } -bool scenery_ref::update(float dt) +bool scenery::update(It, struct chunk&, float dt) { - auto& s = frame; + auto& s = *this; if (!s.active) return false; - switch (s.type) + switch (s.sc_type) { default: case scenery_type::none: @@ -109,25 +48,25 @@ bool scenery_ref::update(float dt) const int fr = s.frame + dir*n; s.active = fr > 0 && fr < nframes-1; if (fr <= 0) - s.passability = pass_mode::pass; + s.pass = pass_mode::pass; else if (fr >= nframes-1) - s.passability = pass_mode::blocked; + s.pass = pass_mode::blocked; else - s.passability = pass_mode::see_through; - s.frame = (scenery::frame_t)std::clamp(fr, 0, nframes-1); + s.pass = pass_mode::see_through; + s.frame = (std::uint16_t)std::clamp(fr, 0, nframes-1); if (!s.active) s.delta = s.closing = 0; return true; } } -bool scenery_ref::activate() +bool scenery::activate(It, struct chunk&) { - auto& s = frame; - if (!*this || s.active) + auto& s = *this; + if (s.active) return false; - switch (s.type) + switch (s.sc_type) { default: case scenery_type::none: @@ -143,22 +82,29 @@ bool scenery_ref::activate() return false; } -bool scenery::is_mesh_modified(const scenery& s0, const scenery& s) +bool scenery::operator==(const entity_proto& e0) const { - if (s.interactive != s0.interactive || s.type != s0.type) - return true; - if (!s.interactive) - return s.r != s0.r || s.offset != s0.offset || s0.frame != s.frame || s.type != s0.type; - return false; + if (!entity::operator==(e0)) + return false; + + const auto& s0 = static_cast<const scenery_proto&>(e0); + return sc_type == s0.sc_type && active == s0.active && + closing == s0.closing && interactive == s0.interactive; } -#ifdef __GNUG__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif -bool scenery::operator==(const scenery&) const noexcept = default; -#ifdef __GNUG__ -#pragma GCC diagnostic pop -#endif +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}, + closing{proto.closing}, interactive{proto.interactive} +{ + fm_assert(type == proto.type); + atlas = proto.atlas; + offset = proto.offset; + bbox_offset = proto.bbox_offset; + bbox_size = proto.bbox_size; + delta = proto.delta; + frame = proto.frame; + r = proto.r; + pass = proto.pass; +} } // namespace floormat |