#include "package.hpp" #include #include #include namespace silly::editor { TileSet &LevelPackage::get_tileset() { return this->tileset; } void LevelPackage::add_level(TileLevel level) { this->levels.push_back(level); } TileLevel &LevelPackage::get_current_level() { return this->levels.at(this->currentLevelIndex); } void LevelPackage::move_to_level_index(int index) { this->currentLevelIndex = std::min(index, (int)this->levels.size() - 1); } const int LevelPackage::get_current_level_index() const { return this->currentLevelIndex; } const std::vector &LevelPackage::get_levels() const { return this->levels; } const std::string &LevelPackage::get_name() const { return this->name; } void LevelPackage::set_name(const std::string &name) { this->name = name; } void LevelPackage::clear() { this->name = ""; this->currentLevelIndex = 0; this->levels.clear(); this->tileset.clear(); } std::string LevelPackage::export_to_string() const { std::ostringstream oss; // package data oss << "[package]\n" << "# name;version\n" << name << ";" << "0\n"; // tileset data oss << this->tileset.export_to_string() << "\n"; // level data for (auto it = this->levels.begin(); it != this->levels.end(); ++it) { oss << it->export_to_string() << "\n"; } return oss.str(); } void LevelPackage::save(LevelPackageFormat format, std::string &file_path) const { if (format != PACKAGE_TXT) { return; } // writing package file std::stringstream pkg_file_path; pkg_file_path << file_path << "/" << this->name << ".txt"; std::string package = this->export_to_string(); std::ofstream ifs(pkg_file_path.str()); ifs << package; ifs.close(); // copying resource files for (auto it = this->tileset.get_entries().begin(); it != this->tileset.get_entries().end(); ++it) { TilesetTile *t = it->get(); std::string old_path = t->path; std::string new_path = file_path + "/" + t->name + "." + t->extension; std::filesystem::copy_file(old_path, new_path); } } void LevelPackage::load(LevelPackageFormat format, std::string &file_path) { if (format != PACKAGE_TXT) { return; } std::string folder_path; #ifdef WIN32 char delim = '\\'; #else char delim = '/'; #endif { auto parts = utils::split_text(file_path, delim); auto name = parts[parts.size() - 1]; folder_path = file_path.substr(0, file_path.size() - name.size() - 1); } this->clear(); std::ifstream ifs(file_path); int sector = 0; std::string line; while (std::getline(ifs, line)) { // skip comments if (line[0] == '#' || line.empty()) continue; // changing sector if (line == "[package]") { sector = 0; continue; } else if (line == "[tileset]") { sector = 1; continue; } else if (line == "[level]") { sector = 2; continue; } else if (line == "[[floor]]") { sector = 3; continue; } else if (line == "[[[tiles]]]") { sector = 4; continue; } auto parts = utils::split_text(line, ';'); switch (sector) { // package case 0: { std::string name = parts.at(0); // TODO: do something with version int version = std::stoi(parts.at(1)); this->set_name(name); break; } // tileset case 1: { int id = std::stoi(parts.at(0)); int type = std::stoi(parts.at(1)); std::string file_name = parts.at(2); this->tileset.add_entry(id, folder_path + delim + file_name, (TilesetTileType)type); break; } // level case 2: { std::string name = parts.at(0); TileLevel level(name); this->add_level(level); this->move_to_level_index(this->levels.size() - 1); break; } // floor case 3: { int width = std::stoi(parts.at(0)); int height = std::stoi(parts.at(1)); TileFloor floor(width, height); this->get_current_level().add_floor(floor); break; } // tiles case 4: { int tile_id = std::stoi(parts.at(0)); int x = std::stoi(parts.at(1)); int y = std::stoi(parts.at(2)); float rotation = std::stof(parts.at(3)); auto tile = std::find_if(this->tileset.get_entries().begin(), this->tileset.get_entries().end(), [&tile_id](const std::shared_ptr &t) { return t->id == tile_id; }); if (tile == this->tileset.get_entries().end()) { break; } this->get_current_level().get_current_floor().place_tile( *tile, {x, y}, rotation); break; } default: break; } } ifs.close(); } }