summaryrefslogtreecommitdiffhomepage
path: root/src/entity.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-09-01 22:27:30 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-09-01 22:27:30 +0200
commit31fd5bbc08234686cf798a93a18e0bb73615d1bf (patch)
tree59b964d01885916c5d49fef3c168ff10dcbdd93f /src/entity.cpp
parent053ea3aa1c443c368f8b43591e3e970e12b50c70 (diff)
rename entity -> object
Diffstat (limited to 'src/entity.cpp')
-rw-r--r--src/entity.cpp300
1 files changed, 0 insertions, 300 deletions
diff --git a/src/entity.cpp b/src/entity.cpp
deleted file mode 100644
index 2a8c5aa1..00000000
--- a/src/entity.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-#include "entity.hpp"
-#include "world.hpp"
-#include "rotation.inl"
-#include "anim-atlas.hpp"
-#include "src/RTree-search.hpp"
-#include "compat/exception.hpp"
-#include "shaders/shader.hpp"
-#include <cmath>
-#include <algorithm>
-
-namespace floormat {
-
-namespace {
-
-constexpr auto entity_id_lessp = [](const auto& a, const auto& b) { return a->id < b->id; };
-
-} // namespace
-
-bool entity_proto::operator==(const entity_proto&) const = default;
-entity_proto& entity_proto::operator=(const entity_proto&) = default;
-entity_proto::~entity_proto() noexcept = default;
-entity_proto::entity_proto() = default;
-entity_proto::entity_proto(const entity_proto&) = default;
-entity_type entity_proto::type_of() const noexcept { return type; }
-
-entity::entity(object_id id, struct chunk& c, const entity_proto& proto) :
- id{id}, c{&c}, 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}
-{
- fm_soft_assert(atlas);
- fm_soft_assert(atlas->check_rotation(r));
- fm_soft_assert(frame < atlas->info().nframes);
-}
-
-entity::~entity() noexcept
-{
- fm_debug_assert(id);
- if (c->_teardown || c->_world->_teardown) [[unlikely]]
- return;
- if (chunk::bbox bb; c->_bbox_for_scenery(*this, bb))
- c->_remove_bbox(bb);
- c->_world->do_kill_entity(id);
- const_cast<object_id&>(id) = 0;
-}
-
-float entity::ordinal() const
-{
- return ordinal(coord.local(), offset, atlas->group(r).z_offset);
-}
-
-float entity::ordinal(local_coords xy, Vector2b offset, Vector2s z_offset) const
-{
- constexpr auto inv_tile_size = 1.f/TILE_SIZE2;
- auto offset_ = ordinal_offset(offset);
- auto vec = Vector2(xy) + offset_*inv_tile_size;
- return vec[0] + vec[1] + Vector2(z_offset).sum();
-}
-
-struct chunk& entity::chunk() const
-{
- return *c;
-}
-
-size_t entity::index() const
-{
- auto& c = chunk();
- const auto fn = [id = id](const auto& a, const auto&) { return a->id < id; };
- auto& es = c._entities;
- auto it = std::lower_bound(es.cbegin(), es.cend(), nullptr, fn);
- fm_assert(it != es.cend());
- fm_assert((*it)->id == id);
- return (size_t)std::distance(es.cbegin(), it);
-}
-
-bool entity::is_virtual() const
-{
- return false;
-}
-
-bool entity::can_rotate(global_coords coord, rotation new_r, rotation old_r, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size)
-{
- if (bbox_offset.isZero() && bbox_size[0] == bbox_size[1])
- return true;
- const auto offset_ = rotate_point(offset, old_r, new_r);
- const auto bbox_offset_ = rotate_point(bbox_offset, old_r, new_r);
- const auto bbox_size_ = rotate_size(bbox_size, old_r, new_r);
- return can_move_to({}, coord, offset_, bbox_offset_, bbox_size_);
-}
-
-bool entity::can_rotate(rotation new_r)
-{
- if (new_r == r)
- return true;
-
- return can_rotate(coord, new_r, r, offset, bbox_offset, bbox_size);
-}
-
-void entity::rotate(size_t, rotation new_r)
-{
- fm_assert(atlas->check_rotation(new_r));
- auto offset_ = !is_dynamic() ? rotate_point(offset, r, new_r) : offset;
- auto bbox_offset_ = rotate_point(bbox_offset, r, new_r);
- auto bbox_size_ = rotate_size(bbox_size, r, new_r);
- set_bbox(offset_, bbox_offset_, bbox_size_, pass);
- if (r != new_r && !is_dynamic())
- c->mark_scenery_modified();
-
- const_cast<rotation&>(r) = new_r;
-}
-
-template <typename T> constexpr T sgn(T val) { return T(T(0) < val) - T(val < T(0)); }
-
-Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vector2b cur_offset, Vector2i new_offset)
-{
- auto off_tmp = Vector2i(cur_offset) + new_offset;
- auto off_new = off_tmp % iTILE_SIZE2;
- constexpr auto half_tile = iTILE_SIZE2/2;
- for (auto i = 0uz; i < 2; i++)
- {
- auto sign = sgn(off_new[i]);
- auto absval = std::abs(off_new[i]);
- if (absval > half_tile[i])
- {
- Vector2i v(0);
- v[i] = sign;
- coord += v;
- off_new[i] = (iTILE_SIZE[i] - absval)*-sign;
- }
- }
- return { coord, Vector2b(off_new) };
-}
-
-template<bool neighbor = true>
-static bool do_search(struct chunk* c, chunk_coords_ coord, object_id id, Vector2 min, Vector2 max, Vector2b off = {})
-{
- if constexpr(neighbor)
- {
- const auto ch = chunk_coords{(int16_t)(coord.x + off[0]), (int16_t)(coord.y + off[1])};
- constexpr auto size = TILE_SIZE2 * TILE_MAX_DIM, grace = TILE_SIZE2 * 4;
- const auto off_ = Vector2(off) * size;
- min -= off_;
- max -= off_;
- if (!(min + grace >= Vector2{} && max - grace <= size)) [[likely]]
- return true;
- auto& w = c->world();
- c = w.at({ch, coord.z});
- if (!c) [[unlikely]]
- return true;
- }
- bool ret = true;
- c->rtree()->Search(min.data(), max.data(), [&](object_id data, const auto&) {
- auto x = std::bit_cast<collision_data>(data);
- if (x.data != id && x.pass != (uint64_t)pass_mode::pass)
- return ret = false;
- else
- return true;
- });
- return ret;
-}
-
-bool entity::can_move_to(Vector2i delta, global_coords coord2, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size)
-{
- auto [coord_, offset_] = normalize_coords(coord2, offset, delta);
-
- if (coord_.z() != coord.z()) [[unlikely]]
- return false;
-
- auto& w = *c->_world;
- auto& c_ = coord_.chunk() == coord.chunk() ? *c : w[{coord_.chunk(), coord_.z()}];
-
- const auto center = Vector2(coord_.local())*TILE_SIZE2 + Vector2(offset_) + Vector2(bbox_offset),
- half_bbox = Vector2(bbox_size)*.5f,
- min = center - half_bbox, max = min + Vector2(bbox_size);
- auto ch = chunk_coords_{coord_.chunk(), coord_.z()};
- if (!do_search<false>(&c_, ch, id, min, max))
- return false;
- for (const auto& off : world::neighbor_offsets)
- if (!do_search(&c_, ch, id, min, max, off))
- return false;
- return true;
-}
-
-bool entity::can_move_to(Vector2i delta)
-{
- return can_move_to(delta, coord, offset, bbox_offset, bbox_size);
-}
-
-size_t entity::move_to(size_t& i, Vector2i delta, rotation new_r)
-{
- if (!can_rotate(new_r))
- return i;
-
- auto& es = c->_entities;
- fm_debug_assert(i < es.size());
- auto e_ = es[i];
-
- fm_assert(&*e_ == this);
- auto& w = *c->_world;
- const auto [coord_, offset_] = normalize_coords(coord, offset, delta);
-
- if (coord_ == coord && offset_ == offset)
- return i;
-
- if (!is_dynamic())
- c->mark_scenery_modified();
-
- chunk::bbox bb0, bb1;
- const auto bb_offset = rotate_point(bbox_offset, r, new_r);
- const auto bb_size = rotate_size(bbox_size, r, new_r);
- bool b0 = c->_bbox_for_scenery(*this, bb0),
- b1 = c->_bbox_for_scenery(*this, coord_.local(), offset_, bb_offset, bb_size, bb1);
-
- if (coord_.chunk() == coord.chunk())
- {
- c->_replace_bbox(bb0, bb1, b0, b1);
- const_cast<global_coords&>(coord) = coord_;
- set_bbox_(offset_, bb_offset, bb_size, pass);
- const_cast<rotation&>(r) = new_r;
- //for (auto i = 0uz; const auto& x : es) fm_debug("%zu %s %f", i++, x->atlas->name().data(), x->ordinal());
- //fm_debug("insert (%hd;%hd|%hhd;%hhd) %td -> %zu | %f", coord_.chunk().x, coord_.chunk().y, coord_.local().x, coord_.local().y, pos1, es.size(), e.ordinal());
- }
- else
- {
- //fm_debug("change-chunk (%hd;%hd|%hhd;%hhd)", coord_.chunk().x, coord_.chunk().y, coord_.local().x, coord_.local().y);
- auto& c2 = w[{coord_.chunk(), coord_.z()}];
- if (!is_dynamic())
- c2.mark_scenery_modified();
- c2._add_bbox(bb1);
- c->remove_entity(i);
- auto& es = c2._entities;
- auto it = std::lower_bound(es.cbegin(), es.cend(), e_, entity_id_lessp);
- const_cast<global_coords&>(coord) = coord_;
- set_bbox_(offset_, bb_offset, bb_size, pass);
- const_cast<rotation&>(r) = new_r;
- const_cast<struct chunk*&>(c) = &c2;
- i = (size_t)std::distance(es.cbegin(), it);
- es.insert(it, std::move(e_));
- }
-
- return i;
-}
-
-void entity::move_to(Magnum::Vector2i delta)
-{
- auto i = index();
- (void)move_to(i, delta, r);
-}
-
-void entity::set_bbox_(Vector2b offset_, Vector2b bbox_offset_, Vector2ub bbox_size_, pass_mode pass_)
-{
- const_cast<Vector2b&>(offset) = offset_;
- const_cast<Vector2b&>(bbox_offset) = bbox_offset_;
- const_cast<Vector2ub&>(bbox_size) = bbox_size_;
- const_cast<pass_mode&>(pass) = pass_;
-}
-
-entity::operator entity_proto() const
-{
- entity_proto ret;
- ret.atlas = atlas;
- ret.offset = offset;
- ret.bbox_offset = bbox_offset;
- ret.bbox_size = bbox_size;
- ret.delta = delta;
- ret.frame = frame;
- ret.type = type();
- ret.r = r;
- ret.pass = pass;
- return ret;
-}
-
-void entity::set_bbox(Vector2b offset_, Vector2b bbox_offset_, Vector2ub bbox_size_, pass_mode pass)
-{
- if (offset != offset_)
- if (!is_dynamic())
- c->mark_scenery_modified();
-
- chunk::bbox bb0, bb;
- const bool b0 = c->_bbox_for_scenery(*this, bb0);
- set_bbox_(offset_, bbox_offset_, bbox_size_, pass);
- const bool b = c->_bbox_for_scenery(*this, bb);
- c->_replace_bbox(bb0, bb, b0, b);
-}
-
-bool entity::can_activate(size_t) const { return false; }
-bool entity::activate(size_t) { return false; }
-
-bool entity::is_dynamic() const
-{
- return atlas->info().fps > 0;
-}
-
-entity_type entity::type_of() const noexcept
-{
- return type();
-}
-
-} // namespace floormat