diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-21 12:01:48 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-21 12:28:53 +0100 |
commit | 9b063b749faedd17fd8f6d76a25d84f066a92814 (patch) | |
tree | 4bf4b7106ade3cd762281204bc1e72344bc12739 /src/scenery.cpp | |
parent | 3ed15b56aded3a6f58ef98d0cbe17012e28e9430 (diff) |
scenery work
Diffstat (limited to 'src/scenery.cpp')
-rw-r--r-- | src/scenery.cpp | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/src/scenery.cpp b/src/scenery.cpp index 620fb51e..e103d679 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -1,7 +1,26 @@ #include "scenery.hpp" +#include "anim-atlas.hpp" +#include "compat/assert.hpp" +#include <algorithm> namespace floormat { +scenery_proto::scenery_proto() noexcept : scenery_proto{scenery::none} {} +scenery_proto::scenery_proto(scenery::none_tag_t) noexcept : frame{scenery::none} {} +scenery_proto::scenery_proto(const std::shared_ptr<anim_atlas>& atlas, const scenery& frame) : + atlas{atlas}, frame{frame} +{} + +scenery_proto::scenery_proto(scenery::generic_tag_t, rotation r, const std::shared_ptr<anim_atlas>& atlas, scenery::frame_t frame) : + atlas{atlas}, frame{scenery::generic, r, *atlas, frame} +{} + +scenery_proto::scenery_proto(scenery::door_tag_t, rotation r, const std::shared_ptr<anim_atlas>& atlas, bool is_open) : + atlas{atlas}, frame{scenery::door, r, *atlas, is_open} +{} + +scenery_proto& scenery_proto::operator=(const scenery_proto&) noexcept = default; + scenery_proto::operator bool() const noexcept { return atlas != nullptr; } scenery_ref::scenery_ref(std::shared_ptr<anim_atlas>& atlas, scenery& frame) noexcept : atlas{atlas}, frame{frame} {} @@ -16,6 +35,65 @@ scenery_ref& scenery_ref::operator=(const scenery_proto& proto) noexcept } scenery_ref::operator scenery_proto() const noexcept { return { atlas, frame }; } -scenery_ref::operator bool() const noexcept { return atlas != nullptr; }; +scenery_ref::operator bool() const noexcept { return atlas != nullptr; } + +scenery::scenery() noexcept : scenery{none_tag_t{}} {} +scenery::scenery(none_tag_t) noexcept : passable{true} {} +scenery::scenery(generic_tag_t, rotation r, const anim_atlas& atlas, frame_t frame) : + frame{frame}, r{r}, type{scenery_type::generic} +{ + fm_assert(frame < atlas.group(r).frames.size()); +} + +scenery::scenery(door_tag_t, rotation r, const anim_atlas& atlas, bool is_open) : + frame{frame_t(is_open ? 0 : atlas.group(r).frames.size()-1)}, + r{r}, passable{is_open}, type{scenery_type::door} +{} + +scenery::scenery(float dt, frame_t frame, rotation r, bool passable, scenery_type type) : + delta{dt}, frame{frame}, r{r}, passable{passable}, type{type} +{} + +void scenery::update(float dt, const anim_atlas& anim) +{ + switch (type) + { + default: + case scenery_type::none: + case scenery_type::generic: + break; + case scenery_type::door: + if (active) + { + const auto hz = std::uint8_t(anim.info().fps); + const auto nframes = (int)anim.info().nframes; + fm_debug_assert(anim.info().fps > 0 && anim.info().fps <= 0xff); + + delta += dt; + const float frame_time = 1000.f/hz; + const auto n = int(delta / frame_time); + delta -= frame_time * n; + fm_debug_assert(delta >= 0); + const std::int8_t dir = passable ? 1 : -1; + const int fr = frame + dir*n; + active = fr > 0 && fr < nframes-1; + passable = fr <= 0; + frame = (frame_t)std::clamp(fr, 0, nframes-1); + if (!active) + delta = 0; + } + break; + } +} + +bool scenery::activate(const anim_atlas& atlas) +{ + if (!active) { + fm_assert(frame == 0 || frame == atlas.info().nframes-1); + active = true; + return true; + } else + return false; +} } // namespace floormat |