summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/object.cpp42
-rw-r--r--src/object.hpp6
-rw-r--r--src/timer-ns.cpp16
-rw-r--r--src/timer.hpp15
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;