diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2014-09-26 04:12:27 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2014-09-26 04:14:11 +0200 |
commit | 144d6201929ebd84f48f6ab5b056b3cf1d2dc5af (patch) | |
tree | 0767c694c060aaf54903034fcd993dee652e6727 /src | |
parent | 124116a8bf56ccc742e6efcb3b9e83abe97bf143 (diff) | |
download | rpgedit-144d6201929ebd84f48f6ab5b056b3cf1d2dc5af.tar rpgedit-144d6201929ebd84f48f6ab5b056b3cf1d2dc5af.zip |
Implement a very simple map file format for further testing
Diffstat (limited to 'src')
-rw-r--r-- | src/model/Map.cpp | 86 |
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; } |