diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/object.cpp | 42 | ||||
-rw-r--r-- | src/object.hpp | 6 | ||||
-rw-r--r-- | src/timer-ns.cpp | 16 | ||||
-rw-r--r-- | src/timer.hpp | 15 |
4 files changed, 59 insertions, 20 deletions
diff --git a/src/object.cpp b/src/object.cpp index 041a6d48..208f4fe2 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -213,18 +213,25 @@ bool object::can_move_to(Vector2i delta) return can_move_to(delta, coord, offset, bbox_offset, bbox_size); } -void object::move_to(size_t& i, Vector2i delta, rotation new_r) +void object::teleport_to(size_t& i, point pt, rotation new_r) { - if (!can_rotate(new_r)) - return; + return teleport_to(i, pt.coord(), pt.offset(), new_r); +} - auto& es = c->_objects; - fm_debug_assert(i < es.size()); - auto e_ = es[i]; +void object::teleport_to(size_t& i, global_coords coord_, Vector2b offset_, rotation new_r) +{ + if (new_r == rotation_COUNT) + new_r = r; + else if (!atlas->check_rotation(new_r) || true) + { + const auto& info = atlas->info(); + const auto *obj = info.object_name.data(), *anim = info.anim_name.data(); + fm_abort("wrong rotation %d for %s/%s!", (int)new_r, obj, anim); + } + fm_assert(i < c->_objects.size()); + const auto e_ = c->_objects[i]; fm_assert(&*e_ == this); - auto& w = *c->_world; - const auto [coord_, offset_] = normalize_coords(coord, offset, delta); if (coord_ == coord && offset_ == offset) return; @@ -247,26 +254,37 @@ void object::move_to(size_t& i, Vector2i delta, rotation new_r) } else { + auto& w = *c->_world; + auto& c2 = w[coord_.chunk3()]; if (!is_dynamic()) c2.mark_scenery_modified(); c2._add_bbox(bb1); c->remove_object(i); auto& es = c2._objects; - auto it = std::lower_bound(es.cbegin(), es.cend(), e_, object_id_lessp); const_cast<global_coords&>(coord) = coord_; set_bbox_(offset_, bb_offset, bb_size, pass); const_cast<rotation&>(r) = new_r; const_cast<class chunk*&>(c) = &c2; - i = (size_t)std::distance(es.cbegin(), it); + i = (size_t)std::distance(es.cbegin(), std::lower_bound(es.cbegin(), es.cend(), e_, object_id_lessp)); arrayInsert(es, i, move(e_)); } } -void object::move_to(Magnum::Vector2i delta) + +bool object::move_to(size_t& i, Vector2i delta, rotation new_r) +{ + if (!can_rotate(new_r)) + return false; + const auto [coord_, offset_] = normalize_coords(coord, offset, delta); + teleport_to(i, coord_, offset_, new_r); + return true; +} + +bool object::move_to(Magnum::Vector2i delta) { auto i = index(); - move_to(i, delta, r); + return move_to(i, delta, r); } uint32_t object::allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float speed) diff --git a/src/object.hpp b/src/object.hpp index 49d861aa..9f029efa 100644 --- a/src/object.hpp +++ b/src/object.hpp @@ -82,8 +82,10 @@ struct object virtual bool is_dynamic() const; bool can_rotate(rotation new_r); bool can_move_to(Vector2i delta); - void move_to(size_t& i, Vector2i delta, rotation new_r); - void move_to(Vector2i delta); + bool move_to(size_t& i, Vector2i delta, rotation new_r); + bool move_to(Vector2i delta); + void teleport_to(size_t& i, global_coords coord, Vector2b offset, rotation new_r); + void teleport_to(size_t& i, point pt, rotation new_r); static uint32_t allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float speed); uint32_t allocate_frame_time(Ns dt, float speed); diff --git a/src/timer-ns.cpp b/src/timer-ns.cpp index a6d1a073..45d0411c 100644 --- a/src/timer-ns.cpp +++ b/src/timer-ns.cpp @@ -56,6 +56,14 @@ Ns operator*(uint64_t a, const Ns& rhs) return Ns{a} * b; } +Ns operator*(const Ns& lhs, float b_) +{ + long double a(lhs.stamp), b(b_); + auto x = a * b; + fm_assert(x <= 1 << 24 && x >= 0); + return Ns{uint64_t(x)}; +} + uint64_t operator/(const Ns& lhs, const Ns& rhs) { auto a = lhs.stamp, b = rhs.stamp; @@ -96,6 +104,14 @@ std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs) return a <=> b; } +Ns Ns::from_millis(uint64_t a) +{ + constexpr auto b = uint64_t(1e6); + const auto x = a * b; + fm_assert(a == 0 || x / a == b); + return Ns{x}; +}; + Ns::operator uint64_t() const { return stamp; } Ns::operator float() const { return float(stamp); } uint64_t Ns::operator*() const { return stamp; } diff --git a/src/timer.hpp b/src/timer.hpp index 8eef447e..a05cc507 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -5,13 +5,9 @@ namespace floormat { struct Ns { - static constexpr uint64_t Min = 0, Max = (uint64_t)-1; - static constexpr uint64_t Second = 1000000000, Millisecond = 1000000; - - uint64_t stamp; - explicit constexpr Ns(): stamp{0} {} explicit constexpr Ns(uint64_t x) : stamp{x} {} + static Ns from_millis(uint64_t x); explicit operator uint64_t() const; explicit operator float() const; @@ -21,6 +17,8 @@ struct Ns friend Ns operator-(const Ns& lhs, const Ns& rhs); friend Ns operator*(const Ns& lhs, uint64_t rhs); friend Ns operator*(uint64_t lhs, const Ns& rhs); + friend Ns operator*(const Ns& lhs, float rhs); + friend Ns operator*(float lhs, const Ns& rhs); friend uint64_t operator/(const Ns& lhs, const Ns& rhs); friend Ns operator/(const Ns& lhs, uint64_t rhs); @@ -29,10 +27,15 @@ struct Ns friend bool operator==(const Ns& lhs, const Ns& rhs); friend std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs); - friend Debug& operator<<(Debug& dbg, const Ns& box); + + uint64_t stamp; + + static constexpr uint64_t Min = 0, Max = (uint64_t)-1; }; +constexpr inline Ns Second{1000000000}, Millisecond{1000000}; + struct Time final { static Time now() noexcept; |