#include "level.h" #include #include #include #include template // [D]erived - [B]ase std::unique_ptr static_unique_pointer_cast(std::unique_ptr&& old) { return std::unique_ptr{static_cast(old.release())}; } void Level::Map::init(const std::string &path) { prepareDefaultCells(); std::ifstream file; file.open(path); std::string cur_line; std::istringstream sstr; SECTION cur_section = SECTION::NONE; while (getline(file, cur_line)) { if (map_section.find(cur_line) != map_section.end()) { cur_section = map_section[cur_line]; continue; } sstr.clear(); sstr.str(cur_line); switch (cur_section) { case SECTION::SIZE: readMapSize(sstr); break; case SECTION::MAP: readMapRow(sstr); break; case SECTION::TELEPORT: readTeleport(sstr); break; case SECTION::TRIGGER: readTrigger(sstr); break; default: break; } } file.close(); } void Level::Map::prepareDefaultCells() { default_cells[PASSABLE_CELL] = std::make_unique(); default_cells[WATER_CELL] = std::make_unique(); default_cells[WALL_CELL] = std::make_unique(); default_cells[CHARGE_CELL] = std::make_unique(); default_cells[EXIT_CELL] = std::make_unique(); default_cells[TELEPORT_CELL] = std::make_unique(); default_cells[TRIGGER_CELL] = std::make_unique(); } void Level::Map::readMapSize(std::istringstream &sstr) { sstr >> rows >> cols; data.reserve(rows * cols); } void Level::Map::readMapRow(std::istringstream &sstr) { data.emplace_back(Row()); int cell_type; while (sstr >> cell_type) { data.back().emplace_back(default_cells[cell_type]->clone()); data.back().back()->setPosition(data.size()-1, data.back().size()-1); } } void Level::Map::readTeleport(std::istringstream &sstr) { coordinate src_row, src_col; coordinate dest_row, dest_col; sstr >> src_row >> src_col >> dest_row >> dest_col; auto teleport_cell = static_unique_pointer_cast(std::move(data[src_row][src_col])); teleport_cell->setDestination(dest_row, dest_col); data[src_row][src_col] = std::move(teleport_cell); } void Level::Map::readTrigger(std::istringstream &sstr) { coordinate src_row, src_col; coordinate dest_row, dest_col; int cell_type; sstr >> src_row >> src_col >> dest_row >> dest_col >> cell_type; if (std::find(TriggerCell::cells_to_cast.begin(), TriggerCell::cells_to_cast.end(), cell_type) == TriggerCell::cells_to_cast.end()) return ; auto trigger_cell = static_unique_pointer_cast(std::move(data[src_row][src_col])); auto dest_cell = default_cells[cell_type]->clone(); dest_cell->setPosition(dest_row, dest_col); trigger_cell->addTarget(std::move(dest_cell)); data[src_row][src_col] = std::move(trigger_cell); } Level::Level(const std::string &path) { map.init(path); } size_t Level::rows() const { return map.rows; } size_t Level::cols() const { return map.cols; } CellPtr &Level::getCellAt(coordinate row, coordinate col) { return map.data[row][col]; } void Level::placeBridge(coordinate row, coordinate col) { map.data[row][col] = std::make_unique(row, col, palette::Black); } void Level::removeCharge(coordinate row, coordinate col) { map.data[row][col] = std::make_unique(row, col, color_ground); } sf::Color Level::defaultGroundColor() { return color_ground; } void Level::setDefaultGroundColor(const sf::Color &color) { color_ground = color; }