diff options
Diffstat (limited to 'src/model/Map.hpp')
-rw-r--r-- | src/model/Map.hpp | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/src/model/Map.hpp b/src/model/Map.hpp index abbf2f1..c7b9783 100644 --- a/src/model/Map.hpp +++ b/src/model/Map.hpp @@ -27,11 +27,12 @@ #pragma once #include <cstdint> -#include <deque> #include <memory> #include <stdexcept> +#include <unordered_map> #include <vector> +#include "CollisionType.hpp" #include "Entity.hpp" @@ -39,29 +40,77 @@ namespace RPGEdit { namespace Model { -class Map { -public: - enum CollisionType { - BLOCKED = 0, - EMPTY, - }; - -private: +class _Map { +protected: std::vector<std::string> tileset; size_t width, height; std::vector<CollisionType> collision; std::vector<std::vector<uint32_t>> tiles; - std::deque<Entity> entities; - - Map(size_t width0, size_t height0, size_t layers) + _Map(size_t width0, size_t height0, size_t layers) : width(width0), height(height0), collision(width*height) { for (size_t i = 0; i < layers; i++) tiles.emplace_back(width*height); } +}; + +class Map : private _Map { +private: + struct EntityState { + Position position; + + Direction direction; + uint64_t transitionStart = 0; + uint64_t transitionEnd = 0; + + EntityState(const Position &position0) : position(position0) {} + }; + + std::vector<std::unique_ptr<Entity>> entities; + std::unordered_map<const Entity *, EntityState> entityStates; + + + void pushEntity(Entity *entity, EntityState &&state) { + entities.push_back(std::unique_ptr<Entity>(entity)); + entityStates.emplace(entity, state); + } + + void copyEntities(const Map &other) { + for (auto &e : other.entities) + pushEntity(new Entity(*e), EntityState(other.entityStates.at(e.get()))); + } + + + Map(size_t width0, size_t height0, size_t layers) : _Map(width0, height0, layers) { + } public: + Map & operator=(const Map &other) { + static_cast<_Map>(*this) = other; + copyEntities(other); + + return *this; + } + + Map(const Map &other) : _Map(other) { + copyEntities(other); + } + + Map & operator=(Map &&other) { + static_cast<_Map>(*this) = std::move(other); + + entities = std::move(other.entities); + entityStates = std::move(other.entityStates); + + return *this; + } + + Map(Map &&other) : _Map(std::move(other)) { + entities = std::move(other.entities); + entityStates = std::move(other.entityStates); + } + std::vector<std::string> & getTileset() { return tileset; } @@ -70,12 +119,15 @@ public: return tileset; } - std::deque<Entity> & getEntities() { + const std::vector<std::unique_ptr<Entity>> & getEntities() const { return entities; } - const std::deque<Entity> & getEntities() const { - return entities; + Entity * addEntity(const std::string &name, const Position &pos) { + Entity *e = new Entity(name); + pushEntity(e, EntityState(pos)); + setCollisionAt(pos.x, pos.y, BLOCKED); + return e; } size_t getWidth() const { @@ -92,7 +144,7 @@ public: void setCollisionAt(size_t x, size_t y, CollisionType value) { if (x >= width || y >= height) - throw std::range_error("Map::setTileAt: bad coordinates"); + throw std::range_error("Map::setCollisionAt: bad coordinates"); collision[y*width + x] = value; } @@ -119,6 +171,11 @@ public: return tiles[layer][y*width + x]; } + Position getEntityPosition(const Entity *entity, uint64_t time) const; + bool moveEntity(Entity *entity, Direction dir, uint64_t start, uint64_t end); + void moveEntityTo(Entity *entity, Position pos); + void finishEntityTransition(Entity *entity); + static std::unique_ptr<Map> load(const std::string &name); }; |