1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Added encapsulation for movement points access

This commit is contained in:
Ivan Savenko 2023-06-21 20:38:26 +03:00
parent edf7756783
commit 08cfbe79cf
24 changed files with 86 additions and 74 deletions

View File

@ -802,8 +802,8 @@ void AIGateway::makeTurn()
//for debug purpose
for (auto h : cb->getHeroesInfo())
{
if (h->movement)
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movement);
if (h->movementPointsRemaining())
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movementPointsRemaining());
}
#if NKAI_TRACE_LEVEL == 0
}

View File

@ -187,7 +187,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
if(ai->nullkiller->isHeroLocked(existingHero)
|| existingHero->getArmyStrength() > hero->getArmyStrength()
|| ai->nullkiller->heroManager->getHeroRole(existingHero) == HeroRole::MAIN
|| existingHero->movement
|| existingHero->movementPointsRemaining()
|| existingHero->artifactsWorn.size() > (existingHero->hasSpellbook() ? 2 : 1))
continue;

View File

@ -206,7 +206,7 @@ Goals::TGoalVec StartupBehavior::decompose() const
for(const CGTownInstance * town : towns)
{
if(town->garrisonHero
&& town->garrisonHero->movement
&& town->garrisonHero->movementPointsRemaining()
&& !town->visitingHero
&& ai->nullkiller->getHeroLockedReason(town->garrisonHero) != HeroLockedReason::DEFENCE)
{

View File

@ -790,7 +790,7 @@ public:
if(garrisonHero && swapCommand.getLockingReason() == HeroLockedReason::DEFENCE)
{
auto defenderRole = evaluationContext.evaluator.ai->heroManager->getHeroRole(garrisonHero);
auto mpLeft = garrisonHero->movement / (float)garrisonHero->maxMovePoints(true);
auto mpLeft = garrisonHero->movementPointsRemaining() / (float)garrisonHero->movementPointsLimit(true);
evaluationContext.movementCost += mpLeft;
evaluationContext.movementCostByRole[defenderRole] += mpLeft;

View File

@ -78,7 +78,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
try
{
if(hero->movement)
if(hero->movementPointsRemaining() > 0)
{
ai->nullkiller->setActive(hero, node.coord);
@ -117,7 +117,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
}
}
if(hero->movement)
if(hero->movementPointsRemaining())
{
try
{
@ -135,14 +135,14 @@ void ExecuteHeroChain::accept(AIGateway * ai)
return;
}
if(hero->movement > 0)
if(hero->movementPointsRemaining() > 0)
{
CGPath path;
bool isOk = cb->getPathsInfo(hero)->getPath(path, node.coord);
if(isOk && path.nodes.back().turns > 0)
{
logAi->warn("Hero %s has %d mp which is not enough to continue his way towards %s.", hero->getNameTranslated(), hero->movement, node.coord.toString());
logAi->warn("Hero %s has %d mp which is not enough to continue his way towards %s.", hero->getNameTranslated(), hero->movementPointsRemaining(), node.coord.toString());
ai->nullkiller->lockHero(hero, HeroLockedReason::HERO_CHAIN);
return;

View File

@ -888,7 +888,7 @@ void AINodeStorage::setHeroes(std::map<const CGHeroInstance *, HeroRole> heroes)
if(actor->hero->tempOwner != ai->playerID)
{
bool onLand = !actor->hero->boat || actor->hero->boat->layer != EPathfindingLayer::SAIL;
actor->initialMovement = actor->hero->maxMovePoints(onLand);
actor->initialMovement = actor->hero->movementPointsLimit(onLand);
}
playerID = actor->hero->tempOwner;
@ -1053,7 +1053,7 @@ struct TowmPortalFinder
return std::nullopt;
AIPathNode * node = nodeOptional.value();
float movementCost = (float)movementNeeded / (float)hero->maxMovePoints(EPathfindingLayer::LAND);
float movementCost = (float)movementNeeded / (float)hero->movementPointsLimit(EPathfindingLayer::LAND);
movementCost += bestNode->getCost();

View File

@ -43,7 +43,7 @@ ChainActor::ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t
{
initialPosition = hero->visitablePos();
layer = hero->boat ? hero->boat->layer : EPathfindingLayer::LAND;
initialMovement = hero->movement;
initialMovement = hero->movementPointsRemaining();
initialTurn = 0;
armyValue = hero->getArmyStrength();
heroFightingStrength = hero->getFightingStrength();
@ -75,7 +75,7 @@ int ChainActor::maxMovePoints(CGPathNode::ELayer layer)
throw std::logic_error("Asking movement points for static actor");
#endif
return hero->maxMovePointsCached(layer, tiCache.get());
return hero->movementPointsLimitCached(layer, tiCache.get());
}
std::string ChainActor::toString() const

View File

@ -267,7 +267,7 @@ TGoalVec Explore::getAllPossibleSubgoals()
if(!ai->isAbleToExplore(h))
return true;
return !h->movement; //saves time, immobile heroes are useless anyway
return !h->movementPointsRemaining(); //saves time, immobile heroes are useless anyway
});
}

View File

@ -113,7 +113,7 @@ std::vector<CGPathNode *> AINodeStorage::getInitialNodes()
auto initialNode = getOrCreateNode(hpos, hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND, NORMAL_CHAIN).value();
initialNode->turns = 0;
initialNode->moveRemains = hero->movement;
initialNode->moveRemains = hero->movementPointsRemaining();
initialNode->danger = 0;
initialNode->setCost(0.0);
@ -245,7 +245,7 @@ void AINodeStorage::calculateTownPortalTeleportations(
auto skillLevel = hero->getSpellSchoolLevel(townPortal);
auto movementCost = GameConstants::BASE_MOVEMENT_COST * (skillLevel >= 3 ? 2 : 3);
if(hero->movement < movementCost)
if(hero->movementPointsRemaining() < movementCost)
{
return;
}

View File

@ -813,8 +813,8 @@ void VCAI::makeTurn()
//for debug purpose
for (auto h : cb->getHeroesInfo())
{
if (h->movement)
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movement);
if (h->movementPointsRemaining())
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movementPointsRemaining());
}
}
catch (boost::thread_interrupted & e)
@ -949,7 +949,7 @@ void VCAI::mainLoop()
if (bestGoal->hero) //lock this hero to fulfill goal
{
setGoal(bestGoal->hero, bestGoal);
if (!bestGoal->hero->movement || vstd::contains(invalidPathHeroes, bestGoal->hero))
if (!bestGoal->hero->movementPointsRemaining() || vstd::contains(invalidPathHeroes, bestGoal->hero))
{
if (!vstd::erase_if_present(possibleGoals, bestGoal))
{
@ -1354,7 +1354,7 @@ void VCAI::wander(HeroPtr h)
TimeCheck tc("looking for wander destination");
while(h->movement)
while(h->movementPointsRemaining())
{
validateVisitableObjs();
ah->updatePaths(getMyHeroes());
@ -2031,7 +2031,7 @@ void VCAI::tryRealize(Goals::RecruitHero & g)
void VCAI::tryRealize(Goals::VisitTile & g)
{
if(!g.hero->movement)
if(!g.hero->movementPointsRemaining())
throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
if(g.tile == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2)
{
@ -2047,7 +2047,7 @@ void VCAI::tryRealize(Goals::VisitTile & g)
void VCAI::tryRealize(Goals::VisitObj & g)
{
auto position = g.tile;
if(!g.hero->movement)
if(!g.hero->movementPointsRemaining())
throw cannotFulfillGoalException("Cannot visit object: hero is out of MPs!");
if(position == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2)
{
@ -2062,7 +2062,7 @@ void VCAI::tryRealize(Goals::VisitObj & g)
void VCAI::tryRealize(Goals::VisitHero & g)
{
if(!g.hero->movement)
if(!g.hero->movementPointsRemaining())
throw cannotFulfillGoalException("Cannot visit target hero: hero is out of MPs!");
const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(g.objid));
@ -2263,7 +2263,7 @@ bool VCAI::canAct(HeroPtr h) const
return false;
}
return h->movement;
return h->movementPointsRemaining();
}
HeroPtr VCAI::primaryHero() const
@ -2412,7 +2412,7 @@ void VCAI::performTypicalActions()
if(!h) //hero might be lost. getUnblockedHeroes() called once on start of turn
continue;
logAi->debug("Hero %s started wandering, MP=%d", h->getNameTranslated(), h->movement);
logAi->debug("Hero %s started wandering, MP=%d", h->getNameTranslated(), h->movementPointsRemaining());
makePossibleUpgrades(*h);
pickBestArtifacts(*h);
try

View File

@ -388,7 +388,7 @@ void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffe
void ClientCommandManager::handleMpCommand()
{
if(const CGHeroInstance* h = LOCPLINT->localState->getCurrentHero())
printCommandMessage(std::to_string(h->movement) + "; max: " + std::to_string(h->maxMovePoints(true)) + "/" + std::to_string(h->maxMovePoints(false)) + "\n");
printCommandMessage(std::to_string(h->movementPointsRemaining()) + "; max: " + std::to_string(h->movementPointsLimit(true)) + "/" + std::to_string(h->movementPointsLimit(false)) + "\n");
}
void ClientCommandManager::handleSetCommand(std::istringstream& singleWordBuffer)

View File

@ -124,7 +124,7 @@ const CGHeroInstance * PlayerLocalState::getNextWanderingHero(const CGHeroInstan
if (isHeroSleeping(hero))
continue;
if (hero->movement == 0)
if (hero->movementPointsRemaining() == 0)
continue;
if (!firstSuitable)

View File

@ -676,7 +676,7 @@ void AdventureMapInterface::onTileHovered(const int3 &mapPos)
void AdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode)
{
const int maxMovementPointsAtStartOfLastTurn = pathNode.turns > 0 ? hero.maxMovePoints(pathNode.layer == EPathfindingLayer::LAND) : hero.movement;
const int maxMovementPointsAtStartOfLastTurn = pathNode.turns > 0 ? hero.movementPointsLimit(pathNode.layer == EPathfindingLayer::LAND) : hero.movementPointsRemaining();
const int movementPointsLastTurnCost = maxMovementPointsAtStartOfLastTurn - pathNode.moveRemains;
const int remainingPointsAfterMove = pathNode.turns == 0 ? pathNode.moveRemains : 0;

View File

@ -224,7 +224,7 @@ void AdventureMapShortcuts::endTurn()
{
for(auto hero : LOCPLINT->localState->getWanderingHeroes())
{
if(!LOCPLINT->localState->isHeroSleeping(hero) && hero->movement > 0)
if(!LOCPLINT->localState->isHeroSleeping(hero) && hero->movementPointsRemaining() > 0)
{
// Only show hero reminder if conditions met:
// - There still movement points
@ -418,7 +418,7 @@ bool AdventureMapShortcuts::optionHeroSelected()
bool AdventureMapShortcuts::optionHeroCanMove()
{
const auto * hero = LOCPLINT->localState->getCurrentHero();
return optionInMapView() && hero && hero->movement != 0 && LOCPLINT->localState->hasPath(hero);
return optionInMapView() && hero && hero->movementPointsRemaining() != 0 && LOCPLINT->localState->hasPath(hero);
}
bool AdventureMapShortcuts::optionHasNextHero()

View File

@ -234,7 +234,7 @@ CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero)
void CHeroList::CHeroItem::update()
{
movement->setFrame(std::min<size_t>(movement->size()-1, hero->movement / 100));
movement->setFrame(std::min<size_t>(movement->size()-1, hero->movementPointsRemaining() / 100));
mana->setFrame(std::min<size_t>(mana->size()-1, hero->mana / 5));
redraw();
}

View File

@ -903,11 +903,9 @@ void SetMovePoints::applyGs(CGameState * gs) const
assert(hero);
if(absolute)
hero->movement = val;
hero->setMovementPoints(val);
else
hero->movement += val;
vstd::amax(hero->movement, 0); //not less than 0
hero->setMovementPoints(hero->movementPointsRemaining() + val);
}
void FoWChange::applyGs(CGameState *gs)
@ -1276,7 +1274,7 @@ void TryMoveHero::applyGs(CGameState *gs)
return;
}
h->movement = movePoints;
h->setMovementPoints(movePoints);
if((result == SUCCESS || result == BLOCKING_VISIT || result == EMBARK || result == DISEMBARK) && start != end)
{
@ -1422,11 +1420,11 @@ void HeroRecruited::applyGs(CGameState * gs) const
{ // this is a fresh hero who hasn't appeared yet
if (boatId >= 0) //Hero spawns on water
{
h->movement = h->maxMovePoints(false);
h->setMovementPoints(h->movementPointsLimit(false));
}
else
{
h->movement = h->maxMovePoints(true);
h->setMovementPoints(h->movementPointsLimit(true));
}
}
@ -1479,7 +1477,7 @@ void GiveHero::applyGs(CGameState * gs) const
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->getIndex())->getTemplates().front();
h->setOwner(player);
h->movement = h->maxMovePoints(true);
h->setMovementPoints(h->movementPointsLimit(true));
h->pos = h->convertFromVisitablePos(oldVisitablePos);
gs->map->heroesOnMap.emplace_back(h);
gs->getPlayerState(h->getOwner())->heroes.emplace_back(h);
@ -2052,7 +2050,7 @@ void NewTurn::applyGs(CGameState *gs)
logGlobal->error("Hero %d not found in NewTurn::applyGs", h.id.getNum());
continue;
}
hero->movement = h.move;
hero->setMovementPoints(h.move);
hero->mana = h.mana;
}

View File

@ -65,7 +65,7 @@ static int lowestSpeed(const CGHeroInstance * chi)
return ret;
}
ui32 CGHeroInstance::getTileCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const
ui32 CGHeroInstance::getTileMovementCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const
{
int64_t ret = GameConstants::BASE_MOVEMENT_COST;
@ -201,10 +201,20 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
return true;
}
int CGHeroInstance::maxMovePoints(bool onLand) const
int CGHeroInstance::movementPointsRemaining() const
{
return movement;
}
void CGHeroInstance::setMovementPoints(int points)
{
movement = std::max(0, points);
}
int CGHeroInstance::movementPointsLimit(bool onLand) const
{
TurnInfo ti(this);
return maxMovePointsCached(onLand, &ti);
return movementPointsLimitCached(onLand, &ti);
}
int CGHeroInstance::getLowestCreatureSpeed() const
@ -224,7 +234,7 @@ void CGHeroInstance::updateArmyMovementBonus(bool onLand, const TurnInfo * ti) c
}
}
int CGHeroInstance::maxMovePointsCached(bool onLand, const TurnInfo * ti) const
int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti) const
{
updateArmyMovementBonus(onLand, ti);
return ti->valOfBonuses(BonusType::MOVEMENT, !!onLand);
@ -454,14 +464,14 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
const auto boatPos = visitablePos();
if (cb->gameState()->map->getTile(boatPos).isWater())
{
smp.val = maxMovePoints(false);
smp.val = movementPointsLimit(false);
//Create a new boat for hero
cb->createObject(boatPos, Obj::BOAT, getBoatType().getNum());
boatId = cb->getTopObj(boatPos)->id;
}
else
{
smp.val = maxMovePoints(true);
smp.val = movementPointsLimit(true);
}
cb->giveHero(id, h->tempOwner, boatId); //recreates def and adds hero to player
cb->setObjProperty(id, ObjProperty::ID, Obj::HERO); //set ID to 34 AFTER hero gets correct flag color
@ -1170,7 +1180,7 @@ int CGHeroInstance::movementPointsAfterEmbark(int MPsBefore, int basicCost, bool
EDiggingStatus CGHeroInstance::diggingStatus() const
{
if(static_cast<int>(movement) < maxMovePoints(true))
if(static_cast<int>(movement) < movementPointsLimit(true))
return EDiggingStatus::LACK_OF_MOVEMENT;
if(!VLC->arth->objects[ArtifactID::GRAIL]->canBePutAt(this))
return EDiggingStatus::BACKPACK_IS_FULL;

View File

@ -49,6 +49,7 @@ class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator,
private:
std::set<SpellID> spells; //known spells (spell IDs)
mutable int lowestCreatureSpeed;
ui32 movement; //remaining movement points
public:
@ -67,7 +68,6 @@ public:
si32 portrait; //may be custom
si32 mana; // remaining spell points
std::vector<std::pair<SecondarySkill,ui8> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities
ui32 movement; //remaining movement points
EHeroGender gender;
std::string nameCustom;
@ -155,7 +155,6 @@ public:
EAlignment getAlignment() const;
bool needsLastStack()const override;
ui32 getTileCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling
//INativeTerrainProvider
FactionID getFaction() const override;
TerrainId getNativeTerrain() const override;
@ -196,9 +195,14 @@ public:
void setSecSkillLevel(const SecondarySkill & which, int val, bool abs); // abs == 0 - changes by value; 1 - sets to value
void levelUp(const std::vector<SecondarySkill> & skills);
int maxMovePoints(bool onLand) const;
/// returns base movement cost for movement between specific tiles. Does not accounts for diagonal movement or last tile exception
ui32 getTileMovementCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const;
void setMovementPoints(int points);
int movementPointsRemaining() const;
int movementPointsLimit(bool onLand) const;
//cached version is much faster, TurnInfo construction is costly
int maxMovePointsCached(bool onLand, const TurnInfo * ti) const;
int movementPointsLimitCached(bool onLand, const TurnInfo * ti) const;
//update army movement bonus
void updateArmyMovementBonus(bool onLand, const TurnInfo * ti) const;

View File

@ -621,7 +621,7 @@ int CPathfinderHelper::getMovementCost(
bool isAirLayer = (hero->boat && hero->boat->layer == EPathfindingLayer::AIR) || ti->hasBonusOfType(BonusType::FLYING_MOVEMENT);
int ret = hero->getTileCost(*dt, *ct, ti);
int ret = hero->getTileMovementCost(*dt, *ct, ti);
if(isSailLayer)
{
if(ct->hasFavorableWinds())

View File

@ -123,7 +123,7 @@ std::vector<CGPathNode *> NodeStorage::getInitialNodes()
auto * initialNode = getNode(out.hpos, out.hero->boat ? out.hero->boat->layer : EPathfindingLayer::LAND);
initialNode->turns = 0;
initialNode->moveRemains = out.hero->movement;
initialNode->moveRemains = out.hero->movementPointsRemaining();
initialNode->setCost(0.0);
if(!initialNode->coord.valid())

View File

@ -107,9 +107,9 @@ int TurnInfo::valOfBonuses(BonusType type, int subtype) const
int TurnInfo::getMaxMovePoints(const EPathfindingLayer & layer) const
{
if(maxMovePointsLand == -1)
maxMovePointsLand = hero->maxMovePointsCached(true, this);
maxMovePointsLand = hero->movementPointsLimitCached(true, this);
if(maxMovePointsWater == -1)
maxMovePointsWater = hero->maxMovePointsCached(false, this);
maxMovePointsWater = hero->movementPointsLimitCached(false, this);
return layer == EPathfindingLayer::SAIL ? maxMovePointsWater : maxMovePointsLand;
}

View File

@ -80,10 +80,10 @@ void Rewardable::Interface::grantRewardAfterLevelup(IGameCallback * cb, const Re
{
SetMovePoints smp;
smp.hid = hero->id;
smp.val = hero->movement;
smp.val = hero->movementPointsRemaining();
if (info.reward.movePercentage >= 0) // percent from max
smp.val = hero->maxMovePoints(hero->boat && hero->boat->layer == EPathfindingLayer::SAIL) * info.reward.movePercentage / 100;
smp.val = hero->movementPointsLimit(hero->boat && hero->boat->layer == EPathfindingLayer::SAIL) * info.reward.movePercentage / 100;
smp.val = std::max<si32>(0, smp.val + info.reward.movePoints);
cb->setMovePoints(&smp);

View File

@ -297,7 +297,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
return ESpellCastResult::ERROR;
}
if(parameters.caster->getHeroCaster()->movement <= 0) //unlike town portal non-zero MP is enough
if(parameters.caster->getHeroCaster()->movementPointsRemaining() <= 0) //unlike town portal non-zero MP is enough
{
env->complain("Hero needs movement points to cast Dimension Door!");
return ESpellCastResult::ERROR;
@ -335,8 +335,8 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
{
SetMovePoints smp;
smp.hid = ObjectInstanceID(parameters.caster->getCasterUnitId());
if(movementCost < static_cast<int>(parameters.caster->getHeroCaster()->movement))
smp.val = parameters.caster->getHeroCaster()->movement - movementCost;
if(movementCost < static_cast<int>(parameters.caster->getHeroCaster()->movementPointsRemaining()))
smp.val = parameters.caster->getHeroCaster()->movementPointsRemaining() - movementCost;
else
smp.val = 0;
env->apply(&smp);
@ -369,7 +369,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
if(nullptr == destination)
return ESpellCastResult::ERROR;
if(static_cast<int>(parameters.caster->getHeroCaster()->movement) < moveCost)
if(static_cast<int>(parameters.caster->getHeroCaster()->movementPointsRemaining()) < moveCost)
return ESpellCastResult::ERROR;
if(destination->visitingHero)
@ -419,7 +419,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
return ESpellCastResult::ERROR;
}
if(static_cast<int>(parameters.caster->getHeroCaster()->movement) < moveCost)
if(static_cast<int>(parameters.caster->getHeroCaster()->movementPointsRemaining()) < moveCost)
{
env->complain("This hero has not enough movement points!");
return ESpellCastResult::ERROR;
@ -441,7 +441,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
{
SetMovePoints smp;
smp.hid = ObjectInstanceID(parameters.caster->getCasterUnitId());
smp.val = std::max<ui32>(0, parameters.caster->getHeroCaster()->movement - moveCost);
smp.val = std::max<ui32>(0, parameters.caster->getHeroCaster()->movementPointsRemaining() - moveCost);
env->apply(&smp);
}
return ESpellCastResult::OK;
@ -468,7 +468,7 @@ ESpellCastResult TownPortalMechanics::beginCast(SpellCastEnvironment * env, cons
const int moveCost = movementCost(parameters);
if(static_cast<int>(parameters.caster->getHeroCaster()->movement) < moveCost)
if(static_cast<int>(parameters.caster->getHeroCaster()->movementPointsRemaining()) < moveCost)
{
InfoWindow iw;
iw.player = parameters.caster->getCasterOwner();

View File

@ -1773,9 +1773,9 @@ void CGameHandler::newTurn()
if (hero->isInitialized() && hero->stacks.size())
{
// reset retreated or surrendered heroes
auto maxmove = hero->maxMovePoints(true);
auto maxmove = hero->movementPointsLimit(true);
// if movement is greater than maxmove, we should decrease it
if (hero->movement != maxmove || hero->mana < hero->manaLimit())
if (hero->movementPointsRemaining() != maxmove || hero->mana < hero->manaLimit())
{
NewTurn::Hero hth;
hth.id = hero->id;
@ -1864,7 +1864,7 @@ void CGameHandler::newTurn()
hth.id = h->id;
auto ti = std::make_unique<TurnInfo>(h, 1);
// TODO: this code executed when bonuses of previous day not yet updated (this happen in NewTurn::applyGs). See issue 2356
hth.move = h->maxMovePointsCached(gs->map->getTile(h->visitablePos()).terType->isLand(), ti.get());
hth.move = h->movementPointsLimitCached(gs->map->getTile(h->visitablePos()).terType->isLand(), ti.get());
hth.mana = h->getManaNewTurn();
n.heroes.insert(hth);
@ -2280,7 +2280,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
tmh.start = h->pos;
tmh.end = dst;
tmh.result = TryMoveHero::FAILED;
tmh.movePoints = h->movement;
tmh.movePoints = h->movementPointsRemaining();
//check if destination tile is available
auto pathfinderHelper = std::make_unique<CPathfinderHelper>(gs, h, PathfinderOptions());
@ -2288,7 +2288,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
const bool canFly = pathfinderHelper->hasBonusOfType(BonusType::FLYING_MOVEMENT) || (h->boat && h->boat->layer == EPathfindingLayer::AIR);
const bool canWalkOnSea = pathfinderHelper->hasBonusOfType(BonusType::WATER_WALKING) || (h->boat && h->boat->layer == EPathfindingLayer::WATER);
const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movement);
const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movementPointsRemaining());
//it's a rock or blocked and not visitable tile
//OR hero is on land and dest is water and (there is not present only one object - boat)
@ -2302,7 +2302,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
&& complain("Tiles are not neighboring!"))
|| ((h->inTownGarrison)
&& complain("Can not move garrisoned hero!"))
|| (((int)h->movement < cost && dst != h->pos && !teleporting)
|| (((int)h->movementPointsRemaining() < cost && dst != h->pos && !teleporting)
&& complain("Hero doesn't have any movement points left!"))
|| ((transit && !canFly && !CGTeleport::isTeleport(t.topVisitableObj()))
&& complain("Hero cannot transit over this tile!"))
@ -2387,14 +2387,14 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
if (!transit && embarking)
{
tmh.movePoints = h->movementPointsAfterEmbark(h->movement, cost, false, ti);
tmh.movePoints = h->movementPointsAfterEmbark(h->movementPointsRemaining(), cost, false, ti);
return doMove(TryMoveHero::EMBARK, IGNORE_GUARDS, DONT_VISIT_DEST, LEAVING_TILE);
// In H3 embark ignore guards
}
if (disembarking)
{
tmh.movePoints = h->movementPointsAfterEmbark(h->movement, cost, true, ti);
tmh.movePoints = h->movementPointsAfterEmbark(h->movementPointsRemaining(), cost, true, ti);
return doMove(TryMoveHero::DISEMBARK, CHECK_FOR_GUARDS, VISIT_DEST, LEAVING_TILE);
}
@ -2420,8 +2420,8 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
//still here? it is standard movement!
{
tmh.movePoints = (int)h->movement >= cost
? h->movement - cost
tmh.movePoints = (int)h->movementPointsRemaining() >= cost
? h->movementPointsRemaining() - cost
: 0;
EGuardLook lookForGuards = CHECK_FOR_GUARDS;