1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

202 lines
5.6 KiB
C++
Raw Normal View History

/*
* TurnInfo.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 "TurnInfo.h"
#include "../IGameCallback.h"
#include "../IGameSettings.h"
#include "../TerrainHandler.h"
#include "../VCMI_Lib.h"
#include "../bonuses/BonusList.h"
#include "../json/JsonNode.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../mapObjects/MiscObjects.h"
VCMI_LIB_NAMESPACE_BEGIN
TConstBonusListPtr TurnInfoBonusList::getBonusList(const CGHeroInstance * target, const CSelector & bonusSelector)
{
std::lock_guard guard(bonusListMutex);
if (target->getTreeVersion() == bonusListVersion)
return bonusList;
bonusList = target->getBonuses(bonusSelector);
bonusListVersion = target->getTreeVersion();
return bonusList;
}
int TurnInfo::hasWaterWalking() const
{
return waterWalkingTest;
}
int TurnInfo::hasFlyingMovement() const
{
return flyingMovementTest;
}
int TurnInfo::hasNoTerrainPenalty(const TerrainId &terrain) const
{
return noterrainPenalty[terrain.num];
}
int TurnInfo::hasFreeShipBoarding() const
{
return freeShipBoardingTest;
}
int TurnInfo::getFlyingMovementValue() const
{
return flyingMovementValue;
}
int TurnInfo::getWaterWalkingValue() const
{
return waterWalkingValue;
}
int TurnInfo::getRoughTerrainDiscountValue() const
{
return roughTerrainDiscountValue;
}
int TurnInfo::getMovePointsLimitLand() const
{
return movePointsLimitLand;
}
int TurnInfo::getMovePointsLimitWater() const
{
return movePointsLimitWater;
}
TurnInfo::TurnInfo(TurnInfoCache * sharedCache, const CGHeroInstance * target, int Turn)
: target(target)
, noterrainPenalty(VLC->terrainTypeHandler->size())
{
CSelector daySelector = Selector::days(Turn);
int lowestSpeed;
if (target->getTreeVersion() == sharedCache->heroLowestSpeedVersion)
{
lowestSpeed = sharedCache->heroLowestSpeedValue;
}
else
{
lowestSpeed = target->getLowestCreatureSpeed();
sharedCache->heroLowestSpeedValue = lowestSpeed;
sharedCache->heroLowestSpeedVersion = target->getTreeVersion();
}
{
static const CSelector selector = Selector::type()(BonusType::WATER_WALKING);
const auto & bonuses = sharedCache->waterWalking.getBonusList(target, selector);
waterWalkingTest = bonuses->getFirst(daySelector) != nullptr;
waterWalkingValue = bonuses->valOfBonuses(daySelector);
}
{
static const CSelector selector = Selector::type()(BonusType::FLYING_MOVEMENT);
const auto & bonuses = sharedCache->flyingMovement.getBonusList(target, selector);
flyingMovementTest = bonuses->getFirst(daySelector) != nullptr;
flyingMovementValue = bonuses->valOfBonuses(daySelector);
}
{
static const CSelector selector = Selector::type()(BonusType::FREE_SHIP_BOARDING);
2024-12-30 12:40:53 +00:00
const auto & bonuses = sharedCache->freeShipBoarding.getBonusList(target, selector);
freeShipBoardingTest = bonuses->getFirst(daySelector) != nullptr;
}
{
static const CSelector selector = Selector::type()(BonusType::ROUGH_TERRAIN_DISCOUNT);
2024-12-30 12:40:53 +00:00
const auto & bonuses = sharedCache->roughTerrainDiscount.getBonusList(target, selector);
roughTerrainDiscountValue = bonuses->valOfBonuses(daySelector);
}
{
static const CSelector selector = Selector::typeSubtype(BonusType::MOVEMENT, BonusCustomSubtype::heroMovementSea);
const auto & vectorSea = target->cb->getSettings().getValue(EGameSettings::HEROES_MOVEMENT_POINTS_SEA).Vector();
2024-12-30 12:40:53 +00:00
const auto & bonuses = sharedCache->movementPointsLimitWater.getBonusList(target, selector);
int baseMovementPointsSea;
if (lowestSpeed < vectorSea.size())
baseMovementPointsSea = vectorSea[lowestSpeed].Integer();
else
baseMovementPointsSea = vectorSea.back().Integer();
movePointsLimitWater = bonuses->valOfBonuses(daySelector, baseMovementPointsSea);
}
{
static const CSelector selector = Selector::typeSubtype(BonusType::MOVEMENT, BonusCustomSubtype::heroMovementLand);
const auto & vectorLand = target->cb->getSettings().getValue(EGameSettings::HEROES_MOVEMENT_POINTS_LAND).Vector();
2024-12-30 12:40:53 +00:00
const auto & bonuses = sharedCache->movementPointsLimitLand.getBonusList(target, selector);
int baseMovementPointsLand;
if (lowestSpeed < vectorLand.size())
baseMovementPointsLand = vectorLand[lowestSpeed].Integer();
else
baseMovementPointsLand = vectorLand.back().Integer();
movePointsLimitLand = bonuses->valOfBonuses(daySelector, baseMovementPointsLand);
}
{
static const CSelector selector = Selector::type()(BonusType::NO_TERRAIN_PENALTY);
2024-12-30 12:40:53 +00:00
const auto & bonuses = sharedCache->noTerrainPenalty.getBonusList(target, selector);
for (const auto & bonus : *bonuses)
{
TerrainId affectedTerrain = bonus->subtype.as<TerrainId>();
noterrainPenalty.at(affectedTerrain.num) = true;
}
const auto nativeTerrain = target->getNativeTerrain();
if (nativeTerrain.hasValue())
noterrainPenalty.at(nativeTerrain.num) = true;
if (nativeTerrain == ETerrainId::ANY_TERRAIN)
boost::range::fill(noterrainPenalty, true);
}
}
bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
{
switch(layer.toEnum())
{
case EPathfindingLayer::AIR:
if(target && target->boat && target->boat->layer == EPathfindingLayer::AIR)
break;
if(!hasFlyingMovement())
return false;
break;
case EPathfindingLayer::WATER:
if(target && target->boat && target->boat->layer == EPathfindingLayer::WATER)
break;
if(!hasWaterWalking())
return false;
break;
}
return true;
}
int TurnInfo::getMaxMovePoints(const EPathfindingLayer & layer) const
{
return layer == EPathfindingLayer::SAIL ? getMovePointsLimitWater() : getMovePointsLimitLand();
}
VCMI_LIB_NAMESPACE_END