summaryrefslogtreecommitdiffstats
path: root/src/model/Map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/model/Map.cpp')
-rw-r--r--src/model/Map.cpp86
1 files changed, 66 insertions, 20 deletions
diff --git a/src/model/Map.cpp b/src/model/Map.cpp
index cb1cb30..ac0b6ee 100644
--- a/src/model/Map.cpp
+++ b/src/model/Map.cpp
@@ -26,6 +26,10 @@
#include "Map.hpp"
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+
namespace RPGEdit {
@@ -85,32 +89,74 @@ void Map::finishEntityTransition(Entity *entity) {
}
std::unique_ptr<Map> Map::load(__attribute__((unused)) const std::string &name) {
- std::unique_ptr<Map> map(new Map(16, 16, 2));
+ std::string filename = "../resources/map/" + name + ".map";
- map->tileset.emplace_back("dirt", 0);
- map->tileset.emplace_back("horizontal_bar", 0);
- map->tileset.emplace_back("horizontal_bar", 2);
+ std::ifstream file;
- for (int i = 0; i < 16; i++) {
- for (int j = 0; j < 16; j++) {
- if (4 <= i && i < 12 && 4 <= j && j < 12) {
- map->setTileAt(0, Position<int>{i, j}, 1);
- map->setCollisionAt(Position<int>{i, j}, CollisionType::EMPTY);
- }
- else {
- map->setTileAt(0, Position<int>{i, j}, 0);
- }
+ file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ file.open(filename.c_str());
+
+ std::string line;
+
+ std::getline(file, line);
+ size_t w, h, layers;
+ if (std::sscanf(line.c_str(), "%zu %zu %zu", &w, &h, &layers) != 3)
+ throw std::invalid_argument("invalid map file");
- if (4 <= i && i < 12 && j == 7)
- map->setTileAt(1, Position<int>{i, j}, 3);
- else if (4 <= i && i < 12 && j == 8)
- map->setTileAt(1, Position<int>{i, j}, 2);
- else
- map->setTileAt(1, Position<int>{i, j}, 0);
+ std::unique_ptr<Map> map(new Map(w, h, layers));
+
+ std::getline(file, line);
+ if (line.length())
+ throw std::invalid_argument("invalid map file");
+
+ size_t n = 1;
+ std::unordered_map<char, size_t> tileset;
+
+ for (std::getline(file, line); line.length(); std::getline(file, line)) {
+ char c;
+ unsigned rot;
+ char *tile = nullptr;
+
+ if (std::sscanf(line.c_str(), "%c %u %ms", &c, &rot, &tile) != 3) {
+ std::free(tile);
+ throw std::invalid_argument("invalid map file");
}
+
+ tileset.emplace(c, n++);
+ map->tileset.emplace_back(tile, rot);
+ std::free(tile);
}
- map->addEntity("square", Model::Position<int>{6, 6});
+ for (size_t i = 0; i < h; i++) {
+ std::getline(file, line);
+ if (line.length() != w)
+ throw std::invalid_argument("invalid map file");
+
+ for (size_t j = 0; j < w; j++) {
+ if (line[j] == '1')
+ map->setCollisionAt(Position<int>{int(j), int(i)}, CollisionType::EMPTY);
+ else if (line[j] != '0')
+ throw std::invalid_argument("invalid map file");
+ }
+ }
+
+ for (size_t layer = 0; layer < layers; layer++) {
+ std::getline(file, line);
+ if (line.length())
+ throw std::invalid_argument("invalid map file");
+
+ for (size_t i = 0; i < h; i++) {
+ std::getline(file, line);
+ if (line.length() != w)
+ throw std::invalid_argument("invalid map file");
+
+ for (size_t j = 0; j < w; j++) {
+ auto it = tileset.find(line[j]);
+ if (it != tileset.end())
+ map->setTileAt(layer, Position<int>{int(j), int(i)}, it->second);
+ }
+ }
+ }
return map;
}