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.
225 lines
4.7 KiB
C++
225 lines
4.7 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(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
UNUSED(hero), UNUSED(level);
|
|
|
|
// Hero just moves on.
|
|
return true;
|
|
}
|
|
|
|
CellPtr 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(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
// Try to use one charge to place a bridge
|
|
if (hero->useCharge())
|
|
level->placeBridge(entity_row, entity_col);
|
|
|
|
return false;
|
|
}
|
|
|
|
CellPtr 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(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
UNUSED(hero), UNUSED(level);
|
|
|
|
// Hero never passes this cell.
|
|
return false;
|
|
}
|
|
|
|
CellPtr 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()
|
|
{}
|
|
|
|
bool ChargeCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
// Hero picks up the charge; remove it from the map
|
|
hero->refillCharges(cell_charges);
|
|
level->removeCharge(entity_row, entity_col);
|
|
|
|
return true;
|
|
}
|
|
|
|
CellPtr 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(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
UNUSED(level);
|
|
|
|
// Level is over.
|
|
hero->reachExit();
|
|
return true;
|
|
}
|
|
|
|
CellPtr 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()
|
|
{}
|
|
|
|
bool TeleportCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
UNUSED(level);
|
|
|
|
// Hero jumps into teleport!
|
|
hero->setPosition(new_row, new_col);
|
|
return true;
|
|
}
|
|
|
|
void TeleportCell::setDestination(coordinate new_cell_row, coordinate new_cell_col)
|
|
{
|
|
new_row = new_cell_row;
|
|
new_col = new_cell_col;
|
|
}
|
|
|
|
CellPtr TeleportCell::clone() const
|
|
{
|
|
return std::make_unique<TeleportCell>();
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
|
|
const std::vector<CELL_TYPE> TriggerCell::cells_to_cast { PASSABLE_CELL, WATER_CELL, WALL_CELL, EXIT_CELL };
|
|
|
|
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(CellPtr &&cell)
|
|
{
|
|
vector_cells.emplace_back(std::move(cell));
|
|
}
|
|
|
|
bool TriggerCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
|
{
|
|
UNUSED(hero);
|
|
|
|
// We replace needed cells with the ones that the trigger provides.
|
|
for (CellPtr &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;
|
|
}
|
|
|
|
CellPtr TriggerCell::clone() const
|
|
{
|
|
return std::make_unique<TriggerCell>();
|
|
}
|