diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-02 10:20:40 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-02 10:20:40 +0100 |
commit | 9ff017f1d4c1502fca9797aa4b38351c97e57982 (patch) | |
tree | 5b122d52ddec31c988e23a70531a968466e73bf6 /src | |
parent | 58d95d559276b556f584411d5c3ea0a986f3fbc4 (diff) |
a
Diffstat (limited to 'src')
-rw-r--r-- | src/critter.cpp | 2 | ||||
-rw-r--r-- | src/critter.hpp | 2 | ||||
-rw-r--r-- | src/object.hpp | 2 | ||||
-rw-r--r-- | src/world.cpp | 68 | ||||
-rw-r--r-- | src/world.hpp | 12 |
5 files changed, 80 insertions, 6 deletions
diff --git a/src/critter.cpp b/src/critter.cpp index f018f274..b187c33a 100644 --- a/src/critter.cpp +++ b/src/critter.cpp @@ -212,7 +212,7 @@ critter::operator critter_proto() const return ret; } -critter::critter(object_id id, class chunk& c, const critter_proto& proto) : +critter::critter(object_id id, class chunk& c, critter_proto proto) : // todo! check if it gets move-constructed object{id, c, proto}, name{proto.name}, speed{proto.speed}, diff --git a/src/critter.hpp b/src/critter.hpp index 01159710..fc3e8f17 100644 --- a/src/critter.hpp +++ b/src/critter.hpp @@ -41,7 +41,7 @@ struct critter final : object private: friend class world; - critter(object_id id, class chunk& c, const critter_proto& proto); + critter(object_id id, class chunk& c, critter_proto proto); }; template<> struct object_type_<struct critter> : std::integral_constant<object_type, object_type::critter> {}; diff --git a/src/object.hpp b/src/object.hpp index f15699bb..49d861aa 100644 --- a/src/object.hpp +++ b/src/object.hpp @@ -48,7 +48,7 @@ struct object const Vector2b offset, bbox_offset; const Vector2ub bbox_size; uint16_t delta = 0, frame = 0; - const rotation r = rotation::N; + const rotation r = rotation::N; // todo remove bitfield? const pass_mode pass = pass_mode::see_through; bool ephemeral : 1 = false; //char _pad[4]; // got 4 bytes left diff --git a/src/world.cpp b/src/world.cpp index ef0de7ae..650f1494 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,6 +1,8 @@ #include "world.hpp" #include "chunk.hpp" #include "object.hpp" +#include "critter.hpp" +#include "compat/shared-ptr-wrapper.hpp" #include "compat/int-hash.hpp" #include "compat/exception.hpp" #include <cr/GrowableArray.h> @@ -95,7 +97,7 @@ chunk& world::operator[](chunk_coords_ coord) noexcept return *c; } -auto world::operator[](global_coords pt) noexcept -> pair +auto world::operator[](global_coords pt) noexcept -> pair_chunk_tile { auto& c = operator[](pt.chunk3()); return { c, c[pt.local()] }; @@ -196,4 +198,68 @@ auto world::neighbors(chunk_coords_ coord) -> std::array<chunk*, 8> return ret; } +const critter_proto& world::make_player_proto() +{ + static const critter_proto p = [] + { + critter_proto cproto; + cproto.name = "Player"_s; + cproto.speed = 10; + cproto.playable = true; + return cproto; + }(); + return p; +} + +shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id) +{ + return ensure_player_character(id, make_player_proto()); +} + +shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id_, critter_proto p) +{ + if (id_) + { + std::shared_ptr<critter> tmp; + if (auto C = find_object(id_); C && C->type() == object_type::critter) + { + auto ptr = std::static_pointer_cast<critter>(C); + return {ptr}; + } + } + id_ = 0; + + auto id = (object_id)-1; + + shared_ptr_wrapper<critter> ret; + + for (const auto& [coord, c] : chunks()) // todo use world::_objects + { + for (const auto& e_ : c.objects()) + { + const auto& e = *e_; + if (e.type() == object_type::critter) + { + const auto& C = static_cast<const critter&>(e); + if (C.playable) + { + id = std::min(id, C.id); + ret.ptr = std::static_pointer_cast<critter>(e_); + } + } + } + } + + if (id != (object_id)-1) + id_ = id; + else + { + p.playable = true; + ret.ptr = make_object<critter>(make_id(), global_coords{}, p); + id_ = ret.ptr->id; + } + fm_debug_assert(ret.ptr); + return ret; +} + } // namespace floormat diff --git a/src/world.hpp b/src/world.hpp index 19a31a46..c6846750 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -10,7 +10,10 @@ namespace floormat { struct object; +struct critter; +struct critter_proto; template<typename T> struct object_type_; +template<typename T> struct shared_ptr_wrapper; class world final { @@ -43,6 +46,7 @@ private: void do_kill_object(object_id id); std::shared_ptr<object> find_object_(object_id id); + [[noreturn]] static void throw_on_wrong_object_type(object_id id, object_type actual, object_type expected); friend struct object; @@ -52,10 +56,10 @@ public: ~world() noexcept; explicit world(std::unordered_map<chunk_coords_, chunk>&& chunks); - struct pair final { chunk& c; tile_ref t; }; // NOLINT + struct pair_chunk_tile final { chunk& c; tile_ref t; }; // NOLINT chunk& operator[](chunk_coords_ c) noexcept; - pair operator[](global_coords pt) noexcept; // todo maybe remove this overload? + pair_chunk_tile operator[](global_coords pt) noexcept; // todo maybe remove this overload? chunk* at(chunk_coords_ c) noexcept; bool contains(chunk_coords_ c) const noexcept; void clear(); @@ -90,6 +94,10 @@ public: template<typename T = object> std::shared_ptr<T> find_object(object_id id); + shared_ptr_wrapper<critter> ensure_player_character(object_id& id, critter_proto p); + shared_ptr_wrapper<critter> ensure_player_character(object_id& id); + static const critter_proto& make_player_proto(); + bool is_teardown() const { return _teardown; } object_id object_counter() const { return _object_counter; } [[nodiscard]] object_id make_id() { return ++_object_counter; } |