2020-02-19 12:50:09 -05:00
|
|
|
#include "level.h"
|
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
#include <sstream>
|
2020-03-15 17:57:39 -04:00
|
|
|
#include <fstream>
|
2020-03-19 10:24:18 -04:00
|
|
|
#include <algorithm>
|
2020-03-15 17:57:39 -04:00
|
|
|
|
2020-03-16 10:30:30 -04:00
|
|
|
template<typename D, typename B> // [D]erived - [B]ase
|
2020-03-19 10:24:18 -04:00
|
|
|
std::unique_ptr<D> static_unique_pointer_cast(std::unique_ptr<B>&& old)
|
2020-03-16 10:30:30 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
return std::unique_ptr<D>{static_cast<D *>(old.release())};
|
2020-03-16 10:30:30 -04:00
|
|
|
}
|
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
void Level::Map::init(const std::string &map_file_name)
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
prepareDefaultCells();
|
2020-03-15 17:57:39 -04:00
|
|
|
|
|
|
|
std::ifstream file;
|
2020-03-19 10:24:18 -04:00
|
|
|
file.open(map_file_name);
|
2020-03-15 17:57:39 -04:00
|
|
|
|
|
|
|
std::string cur_line;
|
2020-03-19 10:24:18 -04:00
|
|
|
std::istringstream sstr;
|
|
|
|
SECTION cur_section = SECTION::NONE;
|
2020-03-15 17:57:39 -04:00
|
|
|
while (getline(file, cur_line))
|
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
if (map_section.find(cur_line) != map_section.end())
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
cur_section = map_section[cur_line];
|
|
|
|
continue;
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
2020-03-19 10:24:18 -04:00
|
|
|
|
|
|
|
sstr.str(cur_line);
|
|
|
|
switch (cur_section)
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
case SECTION::SIZE:
|
|
|
|
readMapSize(sstr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SECTION::MAP:
|
|
|
|
readMapRow(sstr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SECTION::TELEPORT:
|
|
|
|
readTeleport(sstr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SECTION::TRIGGER:
|
|
|
|
readTrigger(sstr);
|
|
|
|
break;
|
2020-03-15 17:57:39 -04:00
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
default:
|
|
|
|
break;
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
|
|
|
}
|
2020-03-19 10:24:18 -04:00
|
|
|
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Level::Map::prepareDefaultCells()
|
|
|
|
{
|
|
|
|
default_cells[PASSABLE_CELL] = std::make_unique<PassableCell>();
|
|
|
|
default_cells[WATER_CELL] = std::make_unique<WaterCell>();
|
|
|
|
default_cells[WALL_CELL] = std::make_unique<WallCell>();
|
|
|
|
default_cells[CHARGE_CELL] = std::make_unique<ChargeCell>();
|
|
|
|
default_cells[EXIT_CELL] = std::make_unique<ExitCell>();
|
|
|
|
default_cells[TELEPORT_CELL] = std::make_unique<TeleportCell>();
|
|
|
|
default_cells[TRIGGER_CELL] = std::make_unique<TriggerCell>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Level::Map::readMapSize(std::istringstream &sstr)
|
|
|
|
{
|
|
|
|
sstr >> rows >> cols;
|
|
|
|
data.reserve(rows * cols);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Level::Map::readMapRow(std::istringstream &sstr)
|
|
|
|
{
|
|
|
|
data.push_back(Row());
|
|
|
|
for (int cell_type; sstr >> cell_type;)
|
|
|
|
{
|
|
|
|
data.back().push_back(default_cells[cell_type]->clone());
|
|
|
|
data.back().back()->setPosition(data.size()-1, data.back().size()-1);
|
|
|
|
}
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
void Level::Map::readTeleport(std::istringstream &sstr)
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
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<TeleportCell>(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<TriggerCell>(std::move(data[src_row][src_col]));
|
|
|
|
trigger_cell->addTarget(default_cells[cell_type]->clone());
|
|
|
|
data[src_row][src_col] = std::move(trigger_cell);
|
|
|
|
}
|
|
|
|
|
|
|
|
Level::Level(const std::string &map_file_name)
|
|
|
|
{
|
|
|
|
map.init(map_file_name);
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
|
|
|
|
2020-03-17 00:27:30 -04:00
|
|
|
size_t Level::rows() const
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
return map.rows;
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
|
|
|
|
2020-03-17 00:27:30 -04:00
|
|
|
size_t Level::cols() const
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
return map.cols;
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
CellPtr &Level::getCellAt(coordinate row, coordinate col)
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
return map.data[row][col];
|
2020-03-15 17:57:39 -04:00
|
|
|
}
|
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
void Level::placeBridge(coordinate row, coordinate col)
|
2020-03-15 17:57:39 -04:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
map.data[row][col] = std::make_unique<PassableCell>(row, col, palette::Black);
|
2020-02-19 12:50:09 -05:00
|
|
|
}
|
2020-02-21 16:55:13 -05:00
|
|
|
|
2020-03-19 10:24:18 -04:00
|
|
|
void Level::removeCharge(coordinate row, coordinate col)
|
2020-02-21 16:55:13 -05:00
|
|
|
{
|
2020-03-19 10:24:18 -04:00
|
|
|
map.data[row][col] = std::make_unique<PassableCell>(row, col, color_ground);
|
2020-02-21 16:55:13 -05:00
|
|
|
}
|
2020-03-15 11:02:37 -04:00
|
|
|
|
|
|
|
sf::Color Level::defaultGroundColor()
|
|
|
|
{
|
|
|
|
return color_ground;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Level::setDefaultGroundColor(const sf::Color &color)
|
|
|
|
{
|
|
|
|
color_ground = color;
|
|
|
|
}
|