#include "cell.h" #include "hero.h" #include "level.h" #define UNUSED(expr) (void)(expr) Cell::Cell(coordinate cell_row, coordinate cell_col, const sf::Color &color) : Entity(cell_row, cell_col), cell_color(color), height_shift(0) // ground by default {} Cell::~Cell() {} sf::Color Cell::color() const noexcept { return cell_color; } void Cell::setHeightShift(coordinate shift_by_y) { height_shift = shift_by_y; } coordinate Cell::heightShift() const { return height_shift; } /////////////////////////////////////// PassableCell::PassableCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) : Cell(cell_row, cell_col, color) {} PassableCell::~PassableCell() {} bool PassableCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { UNUSED(hero), UNUSED(level); // Hero just moves on. return true; } std::unique_ptr PassableCell::clone() const { return std::make_unique(); } /////////////////////////////////////// WaterCell::WaterCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) : Cell(cell_row, cell_col, color) {} WaterCell::~WaterCell() {} bool WaterCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { // Try to use one charge to place a bridge if (hero->useCharge()) level->placeBridge(entity_row, entity_col); return false; } std::unique_ptr WaterCell::clone() const { return std::make_unique(); } /////////////////////////////////////// WallCell::WallCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) : Cell(cell_row, cell_col, color) { // walls are a bit higher than ground and water height_shift = 10; } WallCell::~WallCell() {} bool WallCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { UNUSED(hero), UNUSED(level); // Hero never passes this cell. return false; } std::unique_ptr WallCell::clone() const { return std::make_unique(); } /////////////////////////////////////// ChargeCell::ChargeCell(coordinate cell_row, coordinate cell_col, int has_charges, const sf::Color &color) : Cell(cell_row, cell_col, color), cell_charges(has_charges) { height_shift = 5; // charges are a bit higher than ground and water, but lower than walls } ChargeCell::~ChargeCell() {} void ChargeCell::setCharges(const int &num_charges) { cell_charges = num_charges; } bool ChargeCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { // Hero picks up the charge; remove it from the map hero->refillCharges(cell_charges); level->removeCharge(entity_row, entity_col); return true; } std::unique_ptr ChargeCell::clone() const { return std::make_unique(); } /////////////////////////////////////// ExitCell::ExitCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) : Cell(cell_row, cell_col, color) {} ExitCell::~ExitCell() {} bool ExitCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { UNUSED(level); // Level is over. hero->reachExit(); return true; } std::unique_ptr ExitCell::clone() const { return std::make_unique(); } /////////////////////////////////////// TeleportCell::TeleportCell(coordinate cell_row, coordinate cell_col, coordinate new_cell_row, coordinate new_cell_col, const sf::Color &color) : Cell(cell_row, cell_col, color), new_row(new_cell_row), new_col(new_cell_col) {} TeleportCell::~TeleportCell() {} void TeleportCell::setDestination(coordinate new_cell_row, coordinate new_cell_col) { new_row = new_cell_row; new_col = new_cell_col; } bool TeleportCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { UNUSED(level); // Hero jumps into teleport! hero->setPosition(new_row, new_col); return true; } std::unique_ptr TeleportCell::clone() const { return std::make_unique(); } /////////////////////////////////////// TriggerCell::TriggerCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) : Cell(cell_row, cell_col, color) { // triggers are a bit higher than ground and water, but lower than walls height_shift = 5; } TriggerCell::~TriggerCell() {} void TriggerCell::addTarget(std::unique_ptr &&cell) { vector_cells.emplace_back(std::move(cell)); } bool TriggerCell::onMovingTo(std::unique_ptr &hero, std::unique_ptr &level) { UNUSED(hero); // We replace needed cells with the ones that the trigger provides. for (std::unique_ptr &cell : vector_cells) { const coordinate &row = cell->row(); const coordinate &col = cell->col(); level->getCellAt(row, col).release(); level->getCellAt(row, col) = std::move(cell); } vector_cells.clear(); // It's an impassable object, so player can't move to here. return false; } std::unique_ptr TriggerCell::clone() const { return std::make_unique(); }