/*
* Copyright 2010-2016 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenXcom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenXcom. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Tile.h"
#include <algorithm>
#include "../Mod/MapData.h"
#include "../Mod/MapDataSet.h"
#include "../Engine/SurfaceSet.h"
#include "../Engine/Surface.h"
#include "../Engine/RNG.h"
#include "BattleUnit.h"
#include "BattleItem.h"
#include "../Mod/RuleItem.h"
#include "../Mod/Armor.h"
#include "SerializationHelper.h"
#include "../Battlescape/Particle.h"
#include "../fmath.h"
namespace OpenXcom
{
/// How many bytes various fields use in a serialized tile. See header.
Tile::SerializationKey Tile::serializationKey =
{4, // index
2, // _mapDataSetID, four of these
2, // _mapDataID, four of these
1, // _fire
1, // _smoke
1, // one 8-bit bool field
4 + 2*4 + 2*4 + 1 + 1 + 1 // total bytes to save one tile
};
/**
* constructor
* @param pos Position.
*/
Tile::Tile(Position pos): _smoke(0), _fire(0), _explosive(0), _explosiveType(0), _pos(pos), _unit(0), _animationOffset(0), _markerColor(0), _visible(false), _preview(-1), _TUMarker(-1), _overlaps(0), _danger(false), _obstacle(0)
{
for (int i = 0; i < 4; ++i)
{
_objects[i] = 0;
_mapDataID[i] = -1;
_mapDataSetID[i] = -1;
_currentFrame[i] = 0;
}
for (int layer = 0; layer < LIGHTLAYERS; layer++)
{
_light[layer] = 0;
_lastLight[layer] = -1;
}
for (int i = 0; i < 3; ++i)
{
_discovered[i] = false;
}
}
/**
* destructor
*/
Tile::~Tile()
{
_inventory.clear();
for (std::list<Particle*>::iterator i = _particles.begin(); i != _particles.end(); ++i)
{
delete *i;
}
_particles.clear();
}
/**
* Load the tile from a YAML node.
* @param node YAML node.
*/
void Tile::load(const YAML::Node &node)
{
//_position = node["position"].as<Position>(_position);
for (int i = 0; i < 4; i++)
{
_mapDataID[i] = node["mapDataID"][i].as<int>(_mapDataID[i]);
_mapDataSetID[i] = node["mapDataSetID"][i].as<int>(_mapDataSetID[i]);
}
_fire = node["fire"].as<int>(_fire);
_smoke = node["smoke"].as<int>(_smoke);
if (node["discovered"])
{
for (int i = 0; i < 3; i++)
{
_discovered[i] = node["discovered"][i].as<bool>();
}
}
if (node["openDoorWest"])
{
_currentFrame[1] = 7;
}
if (node["openDoorNorth"])
{
_currentFrame[2] = 7;
}
if (_fire || _smoke)
{
_animationOffset = std::rand() % 4;
}
}
/**
* Load the tile from binary.
* @param buffer Pointer to buffer.
* @param serKey Serialization key.
*/
void Tile::loadBinary(Uint8 *buffer, Tile::SerializationKey& serKey)
{
_mapDataID[0] = unserializeInt(&buffer, serKey._mapDataID);
_mapDataID[1] = unserializeInt(&buffer, serKey._mapDataID);
_mapDataID[2] = unserializeInt(&buffer, serKey._mapDataID);
_mapDataID[3] = unserializeInt(&buffer, serKey._mapDataID);
_mapDataSetID[0] = unserializeInt(&buffer, serKey._mapDataSetID);
_mapDataSetID[1] = unserializeInt(&buffer, serKey._mapDataSetID);
_mapDataSetID[2] = unserializeInt(&buffer, serKey._mapDataSetID);
_mapDataSetID[3] = unserializeInt(&buffer, serKey._mapDataSetID);
_smoke = unserializeInt(&buffer, serKey._smoke);
_fire = unserializeInt(&buffer, serKey._fire);
Uint8 boolFields = unserializeInt(&buffer, serKey.boolFields);
_discovered[0] = (boolFields & 1) ? true : false;
_discovered[1] = (boolFields & 2) ? true : false;
_discovered[2] = (boolFields & 4) ? true : false;
_currentFrame[1] = (boolFields & 8) ? 7 : 0;
_currentFrame[2] = (boolFields & 0x10) ? 7 : 0;
if (_fire || _smoke)
{
_animationOffset = std::rand() % 4;
}
}
/**
* Saves the tile to a YAML node.
* @return YAML node.
*/
YAML::Node Tile::save() const
{
YAML::Node node;
node["position"] = _pos;
for (int i = 0; i < 4; i++)
{
node["mapDataID"].push_back(_mapDataID[i]);
node["mapDataSetID"].push_back(_mapDataSetID[i]);
}
if (_smoke)
node["smoke"] = _smoke;
if (_fire)
node["fire"] = _fire;
if (_discovered[O_FLOOR] || _discovered[O_WESTWALL] || _discovered[O_NORTHWALL])
{
for (int i = O_FLOOR; i <= O_NORTHWALL; i++)
{
node["discovered"].push_back(_discovered[i]);
}
}
if (isUfoDoorOpen(O_WESTWALL))
{
node["openDoorWest"] = true;
}
if (isUfoDoorOpen(O_NORTHWALL))
{
node["openDoorNorth"] = true;
}
return node;
}
/**
* Saves the tile to binary.
* @param buffer pointer to buffer.
*/
void Tile::saveBinary(Uint8** buffer) const
{
serializeInt(buffer, serializationKey._mapDataID, _mapDataID[0]);
serializeInt(buffer, serializationKey._mapDataID, _mapDataID[1]);
serializeInt(buffer, serializationKey._mapDataID, _mapDataID[2]);
serializeInt(buffer, serializationKey._mapDataID, _mapDataID[3]);
serializeInt(buffer, serializationKey._mapDataSetID, _mapDataSetID[0]);
serializeInt(buffer, serializationKey._mapDataSetID, _mapDataSetID[1]);
serializeInt(buffer, serializationKey._mapDataSetID, _mapDataSetID[2]);
serializeInt(buffer, serializationKey._mapDataSetID, _mapDataSetID[3]);
serializeInt(buffer, serializationKey._smoke, _smoke);
serializeInt(buffer, serializationKey._fire, _fire);
Uint8 boolFields = (_discovered[0]?1:0) + (_discovered[1]?2:0) + (_discovered[2]?4:0);
boolFields |= isUfoDoorOpen(O_WESTWALL) ? 8 : 0; // west
boolFields |= isUfoDoorOpen(O_NORTHWALL) ? 0x10 : 0; // north?
serializeInt(buffer, serializationKey.boolFields, boolFields);
}
/**
* Set the MapData references of part 0 to 3.
* @param dat pointer to the data object
* @param mapDataID
* @param mapDataSetID
* @param part Part of the tile to set data of
*/
void Tile::setMapData(MapData *dat, int mapDataID, int mapDataSetID, TilePart part)
{
_objects[part] = dat;
_mapDataID[part] = mapDataID;
_mapDataSetID[part] = mapDataSetID;
}
/**
* get the MapData references of part 0 to 3.
* @param mapDataID
* @param mapDataSetID
* @param part is part of the tile to get data from
* @return the object ID
*/
void Tile::getMapData(int *mapDataID, int *mapDataSetID, TilePart part) const
{
*mapDataID = _mapDataID[part];
*mapDataSetID = _mapDataSetID[part];
}
/**
* Gets whether this tile has no objects. Note that we can have a unit or smoke on this tile.
* @return bool True if there is nothing but air on this tile.
*/
bool Tile::isVoid() const
{
return _objects[0] == 0 && _objects[1] == 0 && _objects[2] == 0 && _objects[3] == 0 && _smoke == 0 && _inventory.empty();
}
/**
* Gets the TU cost to walk over a certain part of the tile.
* @param part The part number.
* @param movementType The movement type.
* @return TU cost.
*/
int Tile::getTUCost(int part, MovementType movementType) const
{
if (_objects[part])
{
if (_objects[part]->isUFODoor() && _currentFrame[part] > 1)
return 0;
if (part == O_OBJECT && _objects[part]->getBigWall() >= 4)
return 0;
return _objects[part]->getTUCost(movementType);
}
else
return 0;
}
/**
* Whether this tile has a floor or not. If no object defined as floor, it has no floor.
* @param tileBelow
* @return bool
*/
bool Tile::hasNoFloor(Tile *tileBelow) const
{
if (tileBelow != 0 && tileBelow->getTerrainLevel() == -24)
return false;
if (_objects[O_FLOOR])
return _objects[O_FLOOR]->isNoFloor();
else
return true;
}
/**
* Whether this tile has a big wall.
* @return bool
*/
bool Tile::isBigWall() const
{
if (_objects[O_OBJECT])
return (_objects[O_OBJECT]->getBigWall() != 0);
else
return false;
}
/**
* If an object stand on this tile, this returns how high the unit is it standing.
* @return the level in pixels (so negative values are higher)
*/
int Tile::getTerrainLevel() const
{
int level = 0;
if (_objects[O_FLOOR])
level = _objects[O_FLOOR]->getTerrainLevel();
// whichever's higher, but not the sum.
if (_objects[O_OBJECT])
level = std::min(_objects[O_OBJECT]->getTerrainLevel(), level);
return level;
}
/**
* Gets the tile's footstep sound.
* @param tileBelow
* @return sound ID
*/
int Tile::getFootstepSound(Tile *tileBelow) const
{
int sound = -1;
if (_objects[O_FLOOR])
sound = _objects[O_FLOOR]->getFootstepSound();
if (_objects[O_OBJECT] && _objects[O_OBJECT]->getBigWall() <= 1 && _objects[O_OBJECT]->getFootstepSound() > -1)
sound = _objects[O_OBJECT]->getFootstepSound();
if (!_objects[O_FLOOR] && !_objects[O_OBJECT] && tileBelow != 0 && tileBelow->getTerrainLevel() == -24)
sound = tileBelow->getMapData(O_OBJECT)->getFootstepSound();
return sound;
}
/**
* Open a door on this tile.
* @param part
* @param unit
* @param reserve
* @return a value: 0(normal door), 1(ufo door) or -1 if no door opened or 3 if ufo door(=animated) is still opening 4 if not enough TUs
*/
int Tile::openDoor(TilePart part, BattleUnit *unit, BattleActionType reserve)
{
if (!_objects[part]) return -1;
if (_objects[part]->isDoor())
{
if (unit && unit->getArmor()->getSize() > 1) // don't allow double-wide units to open swinging doors due to engine limitations
return -1;
if (unit && unit->getTimeUnits() < _objects[part]->getTUCost(unit->getMovementType()) + unit->getActionTUs(reserve, unit->getMainHandWeapon(false)))
return 4;
if (_unit && _unit != unit && _unit->getPosition() != getPosition())
return -1;
setMapData(_objects[part]->getDataset()->getObject(_objects[part]->getAltMCD()), _objects[part]->getAltMCD(), _mapDataSetID[part],
_objects[part]->getDataset()->getObject(_objects[part]->getAltMCD())->getObjectType());
setMapData(0, -1, -1, part);
return 0;
}
if (_objects[part]->isUFODoor() && _currentFrame[part] == 0) // ufo door part 0 - door is closed
{
if (unit && unit->getTimeUnits() < _objects[part]->getTUCost(unit->getMovementType()) + unit->getActionTUs(reserve, unit->getMainHandWeapon(false)))
return 4;
_currentFrame[part] = 1; // start opening door
return 1;
}
if (_objects[part]->isUFODoor() && _currentFrame[part] != 7) // ufo door != part 7 - door is still opening
{
return 3;
}
return -1;
}
int Tile::closeUfoDoor()
{
int retval = 0;
for (int part = O_FLOOR; part <= O_NORTHWALL; ++part)
{
if (isUfoDoorOpen((TilePart)part))
{
_currentFrame[part] = 0;
retval = 1;
}
}
return retval;
}
/**
* Sets the tile's cache flag. - TODO: set this for each object separately?
* @param flag true/false
* @param part 0-2 westwall/northwall/content+floor
*/
void Tile::setDiscovered(bool flag, int part)
{
if (_discovered[part] != flag)
{
_discovered[part] = flag;
if (part == 2 && flag == true)
{
_discovered[0] = true;
_discovered[1] = true;
}
// if light on tile changes, units and objects on it change light too
if (_unit != 0)
{
_unit->setCache(0);
}
}
}
/**
* Get the black fog of war state of this tile.
* @param part 0-2 westwall/northwall/content+floor
* @return bool True = discovered the tile.
*/
bool Tile::isDiscovered(int part) const
{
return _discovered[part];
}
/**
* Reset the light amount on the tile. This is done before a light level recalculation.
* @param layer Light is separated in 3 layers: Ambient, Static and Dynamic.
*/
void Tile::resetLight(int layer)
{
_light[layer] = 0;
_lastLight[layer] = _light[layer];
}
/**
* Add the light amount on the tile. Only add light if the current light is lower.
* @param light Amount of light to add.
* @param layer Light is separated in 3 layers: Ambient, Static and Dynamic.
*/
void Tile::addLight(int light, int layer)
{
if (_light[layer] < light)
_light[layer] = light;
}
/**
* Gets the tile's shade amount 0-15. It returns the brightest of all light layers.
* Shade level is the inverse of light level. So a maximum amount of light (15) returns shade level 0.
* @return shade
*/
int Tile::getShade() const
{
int light = 0;
for (int layer = 0; layer < LIGHTLAYERS; layer++)
{
if (_light[layer] > light)
light = _light[layer];
}
return std::max(0, 15 - light);
}
/**
* Destroy a part on this tile. We first remove the old object, then replace it with the destroyed one.
* This is because the object type of the old and new one are not necessarily the same.
* If the destroyed part is an explosive, set the tile's explosive value, which will trigger a chained explosion.
* @param part the part to destroy.
* @param type the objective type for this mission we are checking against.
* @return bool Return true objective was destroyed.
*/
bool Tile::destroy(TilePart part, SpecialTileType type)
{
bool _objective = false;
if (_objects[part])
{
if (_objects[part]->isGravLift())
return false;
_objective = _objects[part]->getSpecialType() == type;
MapData *originalPart = _objects[part];
int originalMapDataSetID = _mapDataSetID[part];
setMapData(0, -1, -1, part);
if (originalPart->getDieMCD())
{
MapData *dead = originalPart->getDataset()->getObject(originalPart->getDieMCD());
setMapData(dead, originalPart->getDieMCD(), originalMapDataSetID, dead->getObjectType());
}
if (originalPart->getExplosive())
{
setExplosive(originalPart->getExplosive(), originalPart->getExplosiveType());
}
}
/* check if the floor on the lowest level is gone */
if (part == O_FLOOR && getPosition().z == 0 && _objects[O_FLOOR] == 0)
{
/* replace with scorched earth */
setMapData(MapDataSet::getScorchedEarthTile(), 1, 0, O_FLOOR);
}
return _objective;
}
/**
* damage terrain - check against armor
* @param part Part to check.
* @param power Power of the damage.
* @param type the objective type for this mission we are checking against.
* @return bool Return true objective was destroyed
*/
bool Tile::damage(TilePart part, int power, SpecialTileType type)
{
bool objective = false;
if (power >= _objects[part]->getArmor())
objective = destroy(part, type);
return objective;
}
/**
* Set a "virtual" explosive on this tile. We mark a tile this way to detonate it later.
* We do it this way, because the same tile can be visited multiple times by an "explosion ray".
* The explosive power on the tile is some kind of moving MAXIMUM of the explosive rays that passes it.
* @param power Power of the damage.
* @param damageType the damage type of the explosion (not the same as item damage types)
* @param force Force damage.
*/
void Tile::setExplosive(int power, int damageType, bool force)
{
if (force || _explosive < power)
{
_explosive = power;
_explosiveType = damageType;
}
}
/**
* Get explosive on this tile.
* @return explosive
*/
int Tile::getExplosive() const
{
return _explosive;
}
/**
* Get explosive on this tile.
* @return explosive
*/
int Tile::getExplosiveType() const
{
return _explosiveType;
}
/*
* Flammability of a tile is the lowest flammability of it's objects.
* @return Flammability : the lower the value, the higher the chance the tile/object catches fire.
*/
int Tile::getFlammability() const
{
int flam = 255;
for (int i=0; i<4; ++i)
if (_objects[i] && (_objects[i]->getFlammable() < flam))
flam = _objects[i]->getFlammable();
return flam;
}
/*
* Fuel of a tile is the highest fuel of it's objects.
* @return how long to burn.
*/
int Tile::getFuel() const
{
int fuel = 0;
for (int i=0; i<4; ++i)
if (_objects[i] && (_objects[i]->getFuel() > fuel))
fuel = _objects[i]->getFuel();
return fuel;
}
/*
* Flammability of the particular part of the tile
* @return Flammability : the lower the value, the higher the chance the tile/object catches fire.
*/
int Tile::getFlammability(TilePart part) const
{
return _objects[part]->getFlammable();
}
/*
* Fuel of particular part of the tile
* @return how long to burn.
*/
int Tile::getFuel(TilePart part) const
{
return _objects[part]->getFuel();
}
/*
* Ignite starts fire on a tile, it will burn <fuel> rounds. Fuel of a tile is the highest fuel of its objects.
* NOT the sum of the fuel of the objects!
*/
void Tile::ignite(int power)
{
if (getFlammability() != 255)
{
power = power - (getFlammability() / 10) + 15;
if (power < 0)
{
power = 0;
}
if (RNG::percent(power) && getFuel())
{
if (_fire == 0)
{
_smoke = 15 - Clamp(getFlammability() / 10, 1, 12);
_overlaps = 1;
_fire = getFuel() + 1;
_animationOffset = RNG::generate(0,3);
}
}
}
}
/**
* Animate the tile. This means to advance the current frame for every object.
* Ufo doors are a bit special, they animated only when triggered.
* When ufo doors are on frame 0(closed) or frame 7(open) they are not animated further.
*/
void Tile::animate()
{
int newframe;
for (int i=0; i < 4; ++i)
{
if (_objects[i])
{
if (_objects[i]->isUFODoor() && (_currentFrame[i] == 0 || _currentFrame[i] == 7)) // ufo door is static
{
continue;
}
newframe = _currentFrame[i] + 1;
if (_objects[i]->isUFODoor() && _objects[i]->getSpecialType() == START_POINT && newframe == 3)
{
newframe = 7;
}
if (newframe == 8)
{
newframe = 0;
}
_currentFrame[i] = newframe;
}
}
for (std::list<Particle*>::iterator i = _particles.begin(); i != _particles.end();)
{
if (!(*i)->animate())
{
delete *i;
i = _particles.erase(i);
}
else
{
++i;
}
}
}
/**
* Get the sprite of a certain part of the tile.
* @param part
* @return Pointer to the sprite.
*/
Surface *Tile::getSprite(int part) const
{
if (_objects[part] == 0)
return 0;
return _objects[part]->getDataset()->getSurfaceset()->getFrame(_objects[part]->getSprite(_currentFrame[part]));
}
/**
* Set a unit on this tile.
* @param unit
* @param tileBelow
*/
void Tile::setUnit(BattleUnit *unit, Tile *tileBelow)
{
if (unit != 0)
{
unit->setTile(this, tileBelow);
}
_unit = unit;
}
/**
* Set the amount of turns this tile is on fire. 0 = no fire.
* @param fire : amount of turns this tile is on fire.
*/
void Tile::setFire(int fire)
{
_fire = fire;
_animationOffset = RNG::generate(0,3);
}
/**
* Get the amount of turns this tile is on fire. 0 = no fire.
* @return fire : amount of turns this tile is on fire.
*/
int Tile::getFire() const
{
return _fire;
}
/**
* Set the amount of turns this tile is smoking. 0 = no smoke.
* @param smoke : amount of turns this tile is smoking.
*/
void Tile::addSmoke(int smoke)
{
if (_fire == 0)
{
if (_overlaps == 0)
{
_smoke = Clamp(_smoke + smoke, 1, 15);
}
else
{
_smoke += smoke;
}
_animationOffset = RNG::generate(0,3);
addOverlap();
}
}
/**
* Set the amount of turns this tile is smoking. 0 = no smoke.
* @param smoke : amount of turns this tile is smoking.
*/
void Tile::setSmoke(int smoke)
{
_smoke = smoke;
_animationOffset = RNG::generate(0,3);
}
/**
* Get the amount of turns this tile is smoking. 0 = no smoke.
* @return smoke : amount of turns this tile is smoking.
*/
int Tile::getSmoke() const
{
return _smoke;
}
/**
* Get the number of frames the fire or smoke animation is off-sync.
* To void fire and smoke animations of different tiles moving nice in sync - it looks fake.
* @return offset
*/
int Tile::getAnimationOffset() const
{
return _animationOffset;
}
/**
* Add an item on the tile.
* @param item
* @param ground
*/
void Tile::addItem(BattleItem *item, RuleInventory *ground)
{
item->setSlot(ground);
_inventory.push_back(item);
item->setTile(this);
}
/**
* Remove an item from the tile.
* @param item
*/
void Tile::removeItem(BattleItem *item)
{
for (std::vector<BattleItem*>::iterator i = _inventory.begin(); i != _inventory.end(); ++i)
{
if ((*i) == item)
{
_inventory.erase(i);
break;
}
}
item->setTile(0);
}
/**
* Get the topmost item sprite to draw on the battlescape.
* @return item sprite ID in floorob, or -1 when no item
*/
int Tile::getTopItemSprite()
{
int biggestWeight = -1;
int biggestItem = -1;
for (std::vector<BattleItem*>::iterator i = _inventory.begin(); i != _inventory.end(); ++i)
{
if ((*i)->getRules()->getWeight() > biggestWeight)
{
biggestWeight = (*i)->getRules()->getWeight();
biggestItem = (*i)->getRules()->getFloorSprite();
}
}
return biggestItem;
}
/**
* New turn preparations.
* average out any smoke added by the number of overlaps.
* apply fire/smoke damage to units as applicable.
*/
void Tile::prepareNewTurn(bool smokeDamage)
{
// we've received new smoke in this turn, but we're not on fire, average out the smoke.
if ( _overlaps != 0 && _smoke != 0 && _fire == 0)
{
_smoke = Clamp((_smoke / _overlaps) - 1, 0, 15);
}
// if we still have smoke/fire
if (_smoke)
{
if (_unit && !_unit->isOut())
{
if (_fire)
{
// this is how we avoid hitting the same unit multiple times.
if ((_unit->getArmor()->getSize() == 1 || !_unit->tookFireDamage())
//and avoid setting fire elementals on fire
&& _unit->getSpecialAbility() != SPECAB_BURNFLOOR && _unit->getSpecialAbility() != SPECAB_BURN_AND_EXPLODE)
{
_unit->toggleFireDamage();
// _smoke becomes our damage value
_unit->damage(Position(0, 0, 0), _smoke, DT_IN, true);
// try to set the unit on fire.
if (RNG::percent(40 * _unit->getArmor()->getDamageModifier(DT_IN)))
{
int burnTime = RNG::generate(0, int(5.0f * _unit->getArmor()->getDamageModifier(DT_IN)));
if (_unit->getFire() < burnTime)
{
_unit->setFire(burnTime);
}
}
}
}
// no fire: must be smoke
else
{
if (smokeDamage)
{
// try to knock this guy out.
if (_unit->getArmor()->getDamageModifier(DT_SMOKE) > 0.0 && _unit->getArmor()->getSize() == 1)
{
_unit->damage(Position(0,0,0), (_smoke / 4) + 1, DT_SMOKE, true);
}
}
}
}
}
_overlaps = 0;
}
/**
* Get the inventory on this tile.
* @return pointer to a vector of battleitems.
*/
std::vector<BattleItem *> *Tile::getInventory()
{
return &_inventory;
}
/**
* Set the marker color on this tile.
* @param color
*/
void Tile::setMarkerColor(int color)
{
_markerColor = color;
}
/**
* Get the marker color on this tile.
* @return color
*/
int Tile::getMarkerColor() const
{
return _markerColor;
}
/**
* Set the tile visible flag.
* @param visibility
*/
void Tile::setVisible(int visibility)
{
_visible += visibility;
}
/**
* Get the tile visible flag.
* @return visibility
*/
int Tile::getVisible() const
{
return _visible;
}
/**
* set the direction used for path previewing.
* @param dir
*/
void Tile::setPreview(int dir)
{
_preview = dir;
}
/**
* retrieve the direction stored by the pathfinding.
* @return preview
*/
int Tile::getPreview() const
{
return _preview;
}
/**
* set the number to be displayed for pathfinding preview.
* @param tu
*/
void Tile::setTUMarker(int tu)
{
_TUMarker = tu;
}
/**
* get the number to be displayed for pathfinding preview.
* @return marker
*/
int Tile::getTUMarker() const
{
return _TUMarker;
}
/**
* get the overlap value of this tile.
* @return overlap
*/
int Tile::getOverlaps() const
{
return _overlaps;
}
/**
* increment the overlap value on this tile.
*/
void Tile::addOverlap()
{
++_overlaps;
}
/**
* set the danger flag on this tile.
*/
void Tile::setDangerous(bool danger)
{
_danger = danger;
}
/**
* get the danger flag on this tile.
* @return the danger flag for this tile.
*/
bool Tile::getDangerous() const
{
return _danger;
}
/**
* adds a particle to this tile's internal storage buffer.
* @param particle the particle to add.
*/
void Tile::addParticle(Particle *particle)
{
_particles.push_back(particle);
}
/**
* gets a pointer to this tile's particle array.
* @return a pointer to the internal array of particles.
*/
std::list<Particle *> *Tile::getParticleCloud()
{
return &_particles;
}
/**
* sets the flag of an obstacle for single part.
*/
void Tile::setObstacle(int part)
{
_obstacle |= (1 << part);
}
/**
* resets obstacle flag for all parts of the tile.
*/
void Tile::resetObstacle(void)
{
_obstacle = 0;
}
}
↑ V807 Decreased performance. Consider creating a pointer to avoid using the '(* i)->getRules()' expression repeatedly.
↑ V807 Decreased performance. Consider creating a pointer to avoid using the '_unit->getArmor()' expression repeatedly.