123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- /*
- * Unit.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "Unit.h"
- #include "../VCMI_Lib.h"
- #include "../texts/CGeneralTextHandler.h"
- #include "../serializer/JsonDeserializer.h"
- #include "../serializer/JsonSerializer.h"
- #include <vcmi/Faction.h>
- #include <vcmi/FactionService.h>
- VCMI_LIB_NAMESPACE_BEGIN
- namespace battle
- {
- ///Unit
- Unit::~Unit() = default;
- bool Unit::isDead() const
- {
- return !alive() && !isGhost();
- }
- bool Unit::isTurret() const
- {
- return creatureIndex() == CreatureID::ARROW_TOWERS;
- }
- std::string Unit::getDescription() const
- {
- boost::format fmt("Unit %d of side %d");
- fmt % unitId() % static_cast<int>(unitSide());
- return fmt.str();
- }
- //TODO: deduplicate these functions
- const IBonusBearer* Unit::getBonusBearer() const
- {
- return this;
- }
- const BattleHexArray & Unit::getSurroundingHexes(BattleHex assumedPosition) const
- {
- BattleHex hex = (assumedPosition.toInt() != BattleHex::INVALID) ? assumedPosition : getPosition(); //use hypothetical position
- return getSurroundingHexes(hex, doubleWide(), unitSide());
- }
- const BattleHexArray & Unit::getSurroundingHexes(BattleHex position, bool twoHex, BattleSide side)
- {
- if(!twoHex)
- return position.getNeighbouringTiles();
- return position.getNeighbouringTilesDoubleWide(side);
- }
- BattleHexArray Unit::getAttackableHexes(const Unit * attacker) const
- {
- const BattleHexArray & defenderHexes = battle::Unit::getHexes(
- getPosition(),
- doubleWide(),
- unitSide());
-
- BattleHexArray targetableHexes;
- for(auto defenderHex : defenderHexes)
- {
- auto hexes = battle::Unit::getHexes(
- defenderHex,
- attacker->doubleWide(),
- unitSide());
- if(hexes.size() == 2 && BattleHex::getDistance(hexes.front(), hexes.back()) != 1)
- hexes.pop_back();
- for(auto hex : hexes)
- targetableHexes.insert(hex.getNeighbouringTiles());
- }
- return targetableHexes;
- }
- bool Unit::coversPos(BattleHex pos) const
- {
- return getPosition() == pos || (doubleWide() && (occupiedHex() == pos));
- }
- const BattleHexArray & Unit::getHexes() const
- {
- return getHexes(getPosition(), doubleWide(), unitSide());
- }
- const BattleHexArray & Unit::getHexes(BattleHex assumedPos) const
- {
- return getHexes(assumedPos, doubleWide(), unitSide());
- }
- const BattleHexArray & Unit::getHexes(BattleHex assumedPos, bool twoHex, BattleSide side)
- {
- static BattleHexArray::ArrayOfBattleHexArrays precomputed[4];
- int index = side == BattleSide::ATTACKER ? 0 : 2;
- if(!precomputed[index + twoHex][assumedPos.toInt()].empty())
- return precomputed[index + twoHex][assumedPos.toInt()];
- // first run, compute
- BattleHexArray hexes;
- hexes.insert(assumedPos);
- if(twoHex)
- hexes.insert(occupiedHex(assumedPos, twoHex, side));
- precomputed[index + twoHex][assumedPos.toInt()] = std::move(hexes);
- return precomputed[index + twoHex][assumedPos.toInt()];
- }
- BattleHex Unit::occupiedHex() const
- {
- return occupiedHex(getPosition(), doubleWide(), unitSide());
- }
- BattleHex Unit::occupiedHex(BattleHex assumedPos) const
- {
- return occupiedHex(assumedPos, doubleWide(), unitSide());
- }
- BattleHex Unit::occupiedHex(BattleHex assumedPos, bool twoHex, BattleSide side)
- {
- if(twoHex)
- {
- if(side == BattleSide::ATTACKER)
- return assumedPos.toInt() - 1;
- else
- return assumedPos.toInt() + 1;
- }
- else
- {
- return BattleHex::INVALID;
- }
- }
- void Unit::addText(MetaString & text, EMetaText type, int32_t serial, const boost::logic::tribool & plural) const
- {
- if(boost::logic::indeterminate(plural))
- serial = VLC->generaltexth->pluralText(serial, getCount());
- else if(plural)
- serial = VLC->generaltexth->pluralText(serial, 2);
- else
- serial = VLC->generaltexth->pluralText(serial, 1);
- text.appendLocalString(type, serial);
- }
- void Unit::addNameReplacement(MetaString & text, const boost::logic::tribool & plural) const
- {
- if(boost::logic::indeterminate(plural))
- text.replaceName(creatureId(), getCount());
- else if(plural)
- text.replaceNamePlural(creatureIndex());
- else
- text.replaceNameSingular(creatureIndex());
- }
- std::string Unit::formatGeneralMessage(const int32_t baseTextId) const
- {
- const int32_t textId = VLC->generaltexth->pluralText(baseTextId, getCount());
- MetaString text;
- text.appendLocalString(EMetaText::GENERAL_TXT, textId);
- text.replaceName(creatureId(), getCount());
- return text.toString();
- }
- int Unit::getRawSurrenderCost() const
- {
- //we pay for our stack that comes from our army slots - condition eliminates summoned cres and war machines
- if(unitSlot().validSlot())
- return creatureCost() * getCount();
- else
- return 0;
- }
- ///UnitInfo
- void UnitInfo::serializeJson(JsonSerializeFormat & handler)
- {
- handler.serializeInt("count", count);
- handler.serializeId("type", type, CreatureID(CreatureID::NONE));
- handler.serializeInt("side", side);
- si16 positionValue = position.toInt();
- handler.serializeInt("position", positionValue);
- position = positionValue;
- handler.serializeBool("summoned", summoned);
- }
- void UnitInfo::save(JsonNode & data)
- {
- data.clear();
- JsonSerializer ser(nullptr, data);
- ser.serializeStruct("newUnitInfo", *this);
- }
- void UnitInfo::load(uint32_t id_, const JsonNode & data)
- {
- id = id_;
- JsonDeserializer deser(nullptr, data);
- deser.serializeStruct("newUnitInfo", *this);
- }
- }
- VCMI_LIB_NAMESPACE_END
|