From 144d6201929ebd84f48f6ab5b056b3cf1d2dc5af Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Sep 2014 04:12:27 +0200 Subject: Implement a very simple map file format for further testing --- src/model/Map.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 20 deletions(-) (limited to 'src/model') 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 +#include +#include + namespace RPGEdit { @@ -85,32 +89,74 @@ void Map::finishEntityTransition(Entity *entity) { } std::unique_ptr Map::load(__attribute__((unused)) const std::string &name) { - std::unique_ptr 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{i, j}, 1); - map->setCollisionAt(Position{i, j}, CollisionType::EMPTY); - } - else { - map->setTileAt(0, Position{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{i, j}, 3); - else if (4 <= i && i < 12 && j == 8) - map->setTileAt(1, Position{i, j}, 2); - else - map->setTileAt(1, Position{i, j}, 0); + std::unique_ptr 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 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{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(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(j), int(i)}, it->second); + } + } + } return map; } -- cgit v1.2.3