summaryrefslogtreecommitdiffstats
path: root/src/model/Map.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/model/Map.hpp')
-rw-r--r--src/model/Map.hpp89
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);
};