You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.0 KiB
C++

#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> &hero, std::unique_ptr<Level> &level)
{
UNUSED(hero), UNUSED(level);
// Hero just moves on.
return true;
}
std::unique_ptr<Cell> PassableCell::clone() const
{
return std::make_unique<PassableCell>();
}
///////////////////////////////////////
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> &hero, std::unique_ptr<Level> &level)
{
// Try to use one charge to place a bridge
if (hero->useCharge())
level->placeBridge(entity_row, entity_col);
return false;
}
std::unique_ptr<Cell> WaterCell::clone() const
{
return std::make_unique<WaterCell>();
}
///////////////////////////////////////
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> &hero, std::unique_ptr<Level> &level)
{
UNUSED(hero), UNUSED(level);
// Hero never passes this cell.
return false;
}
std::unique_ptr<Cell> WallCell::clone() const
{
return std::make_unique<WallCell>();
}
///////////////////////////////////////
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> &hero, std::unique_ptr<Level> &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<Cell> ChargeCell::clone() const
{
return std::make_unique<ChargeCell>();
}
///////////////////////////////////////
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> &hero, std::unique_ptr<Level> &level)
{
UNUSED(level);
// Level is over.
hero->reachExit();
return true;
}
std::unique_ptr<Cell> ExitCell::clone() const
{
return std::make_unique<ExitCell>();
}
///////////////////////////////////////
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> &hero, std::unique_ptr<Level> &level)
{
UNUSED(level);
// Hero jumps into teleport!
hero->setPosition(new_row, new_col);
return true;
}
std::unique_ptr<Cell> TeleportCell::clone() const
{
return std::make_unique<TeleportCell>();
}
///////////////////////////////////////
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> &&cell)
{
vector_cells.emplace_back(std::move(cell));
}
bool TriggerCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
UNUSED(hero);
// We replace needed cells with the ones that the trigger provides.
for (std::unique_ptr<Cell> &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<Cell> TriggerCell::clone() const
{
return std::make_unique<TriggerCell>();
}