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:
parent
edf7756783
commit
08cfbe79cf
@ -802,8 +802,8 @@ void AIGateway::makeTurn()
|
|||||||
//for debug purpose
|
//for debug purpose
|
||||||
for (auto h : cb->getHeroesInfo())
|
for (auto h : cb->getHeroesInfo())
|
||||||
{
|
{
|
||||||
if (h->movement)
|
if (h->movementPointsRemaining())
|
||||||
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movement);
|
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movementPointsRemaining());
|
||||||
}
|
}
|
||||||
#if NKAI_TRACE_LEVEL == 0
|
#if NKAI_TRACE_LEVEL == 0
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
if(ai->nullkiller->isHeroLocked(existingHero)
|
if(ai->nullkiller->isHeroLocked(existingHero)
|
||||||
|| existingHero->getArmyStrength() > hero->getArmyStrength()
|
|| existingHero->getArmyStrength() > hero->getArmyStrength()
|
||||||
|| ai->nullkiller->heroManager->getHeroRole(existingHero) == HeroRole::MAIN
|
|| ai->nullkiller->heroManager->getHeroRole(existingHero) == HeroRole::MAIN
|
||||||
|| existingHero->movement
|
|| existingHero->movementPointsRemaining()
|
||||||
|| existingHero->artifactsWorn.size() > (existingHero->hasSpellbook() ? 2 : 1))
|
|| existingHero->artifactsWorn.size() > (existingHero->hasSpellbook() ? 2 : 1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ Goals::TGoalVec StartupBehavior::decompose() const
|
|||||||
for(const CGTownInstance * town : towns)
|
for(const CGTownInstance * town : towns)
|
||||||
{
|
{
|
||||||
if(town->garrisonHero
|
if(town->garrisonHero
|
||||||
&& town->garrisonHero->movement
|
&& town->garrisonHero->movementPointsRemaining()
|
||||||
&& !town->visitingHero
|
&& !town->visitingHero
|
||||||
&& ai->nullkiller->getHeroLockedReason(town->garrisonHero) != HeroLockedReason::DEFENCE)
|
&& ai->nullkiller->getHeroLockedReason(town->garrisonHero) != HeroLockedReason::DEFENCE)
|
||||||
{
|
{
|
||||||
|
@ -790,7 +790,7 @@ public:
|
|||||||
if(garrisonHero && swapCommand.getLockingReason() == HeroLockedReason::DEFENCE)
|
if(garrisonHero && swapCommand.getLockingReason() == HeroLockedReason::DEFENCE)
|
||||||
{
|
{
|
||||||
auto defenderRole = evaluationContext.evaluator.ai->heroManager->getHeroRole(garrisonHero);
|
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.movementCost += mpLeft;
|
||||||
evaluationContext.movementCostByRole[defenderRole] += mpLeft;
|
evaluationContext.movementCostByRole[defenderRole] += mpLeft;
|
||||||
|
@ -78,7 +78,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(hero->movement)
|
if(hero->movementPointsRemaining() > 0)
|
||||||
{
|
{
|
||||||
ai->nullkiller->setActive(hero, node.coord);
|
ai->nullkiller->setActive(hero, node.coord);
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hero->movement)
|
if(hero->movementPointsRemaining())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -135,14 +135,14 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hero->movement > 0)
|
if(hero->movementPointsRemaining() > 0)
|
||||||
{
|
{
|
||||||
CGPath path;
|
CGPath path;
|
||||||
bool isOk = cb->getPathsInfo(hero)->getPath(path, node.coord);
|
bool isOk = cb->getPathsInfo(hero)->getPath(path, node.coord);
|
||||||
|
|
||||||
if(isOk && path.nodes.back().turns > 0)
|
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);
|
ai->nullkiller->lockHero(hero, HeroLockedReason::HERO_CHAIN);
|
||||||
return;
|
return;
|
||||||
|
@ -888,7 +888,7 @@ void AINodeStorage::setHeroes(std::map<const CGHeroInstance *, HeroRole> heroes)
|
|||||||
if(actor->hero->tempOwner != ai->playerID)
|
if(actor->hero->tempOwner != ai->playerID)
|
||||||
{
|
{
|
||||||
bool onLand = !actor->hero->boat || actor->hero->boat->layer != EPathfindingLayer::SAIL;
|
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;
|
playerID = actor->hero->tempOwner;
|
||||||
@ -1053,7 +1053,7 @@ struct TowmPortalFinder
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
AIPathNode * node = nodeOptional.value();
|
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();
|
movementCost += bestNode->getCost();
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ ChainActor::ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t
|
|||||||
{
|
{
|
||||||
initialPosition = hero->visitablePos();
|
initialPosition = hero->visitablePos();
|
||||||
layer = hero->boat ? hero->boat->layer : EPathfindingLayer::LAND;
|
layer = hero->boat ? hero->boat->layer : EPathfindingLayer::LAND;
|
||||||
initialMovement = hero->movement;
|
initialMovement = hero->movementPointsRemaining();
|
||||||
initialTurn = 0;
|
initialTurn = 0;
|
||||||
armyValue = hero->getArmyStrength();
|
armyValue = hero->getArmyStrength();
|
||||||
heroFightingStrength = hero->getFightingStrength();
|
heroFightingStrength = hero->getFightingStrength();
|
||||||
@ -75,7 +75,7 @@ int ChainActor::maxMovePoints(CGPathNode::ELayer layer)
|
|||||||
throw std::logic_error("Asking movement points for static actor");
|
throw std::logic_error("Asking movement points for static actor");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return hero->maxMovePointsCached(layer, tiCache.get());
|
return hero->movementPointsLimitCached(layer, tiCache.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ChainActor::toString() const
|
std::string ChainActor::toString() const
|
||||||
|
@ -267,7 +267,7 @@ TGoalVec Explore::getAllPossibleSubgoals()
|
|||||||
if(!ai->isAbleToExplore(h))
|
if(!ai->isAbleToExplore(h))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return !h->movement; //saves time, immobile heroes are useless anyway
|
return !h->movementPointsRemaining(); //saves time, immobile heroes are useless anyway
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ std::vector<CGPathNode *> AINodeStorage::getInitialNodes()
|
|||||||
auto initialNode = getOrCreateNode(hpos, hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND, NORMAL_CHAIN).value();
|
auto initialNode = getOrCreateNode(hpos, hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND, NORMAL_CHAIN).value();
|
||||||
|
|
||||||
initialNode->turns = 0;
|
initialNode->turns = 0;
|
||||||
initialNode->moveRemains = hero->movement;
|
initialNode->moveRemains = hero->movementPointsRemaining();
|
||||||
initialNode->danger = 0;
|
initialNode->danger = 0;
|
||||||
initialNode->setCost(0.0);
|
initialNode->setCost(0.0);
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ void AINodeStorage::calculateTownPortalTeleportations(
|
|||||||
auto skillLevel = hero->getSpellSchoolLevel(townPortal);
|
auto skillLevel = hero->getSpellSchoolLevel(townPortal);
|
||||||
auto movementCost = GameConstants::BASE_MOVEMENT_COST * (skillLevel >= 3 ? 2 : 3);
|
auto movementCost = GameConstants::BASE_MOVEMENT_COST * (skillLevel >= 3 ? 2 : 3);
|
||||||
|
|
||||||
if(hero->movement < movementCost)
|
if(hero->movementPointsRemaining() < movementCost)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -813,8 +813,8 @@ void VCAI::makeTurn()
|
|||||||
//for debug purpose
|
//for debug purpose
|
||||||
for (auto h : cb->getHeroesInfo())
|
for (auto h : cb->getHeroesInfo())
|
||||||
{
|
{
|
||||||
if (h->movement)
|
if (h->movementPointsRemaining())
|
||||||
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movement);
|
logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movementPointsRemaining());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (boost::thread_interrupted & e)
|
catch (boost::thread_interrupted & e)
|
||||||
@ -949,7 +949,7 @@ void VCAI::mainLoop()
|
|||||||
if (bestGoal->hero) //lock this hero to fulfill goal
|
if (bestGoal->hero) //lock this hero to fulfill goal
|
||||||
{
|
{
|
||||||
setGoal(bestGoal->hero, bestGoal);
|
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))
|
if (!vstd::erase_if_present(possibleGoals, bestGoal))
|
||||||
{
|
{
|
||||||
@ -1354,7 +1354,7 @@ void VCAI::wander(HeroPtr h)
|
|||||||
|
|
||||||
TimeCheck tc("looking for wander destination");
|
TimeCheck tc("looking for wander destination");
|
||||||
|
|
||||||
while(h->movement)
|
while(h->movementPointsRemaining())
|
||||||
{
|
{
|
||||||
validateVisitableObjs();
|
validateVisitableObjs();
|
||||||
ah->updatePaths(getMyHeroes());
|
ah->updatePaths(getMyHeroes());
|
||||||
@ -2031,7 +2031,7 @@ void VCAI::tryRealize(Goals::RecruitHero & g)
|
|||||||
|
|
||||||
void VCAI::tryRealize(Goals::VisitTile & 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!");
|
throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
|
||||||
if(g.tile == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2)
|
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)
|
void VCAI::tryRealize(Goals::VisitObj & g)
|
||||||
{
|
{
|
||||||
auto position = g.tile;
|
auto position = g.tile;
|
||||||
if(!g.hero->movement)
|
if(!g.hero->movementPointsRemaining())
|
||||||
throw cannotFulfillGoalException("Cannot visit object: hero is out of MPs!");
|
throw cannotFulfillGoalException("Cannot visit object: hero is out of MPs!");
|
||||||
if(position == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2)
|
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)
|
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!");
|
throw cannotFulfillGoalException("Cannot visit target hero: hero is out of MPs!");
|
||||||
|
|
||||||
const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(g.objid));
|
const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(g.objid));
|
||||||
@ -2263,7 +2263,7 @@ bool VCAI::canAct(HeroPtr h) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return h->movement;
|
return h->movementPointsRemaining();
|
||||||
}
|
}
|
||||||
|
|
||||||
HeroPtr VCAI::primaryHero() const
|
HeroPtr VCAI::primaryHero() const
|
||||||
@ -2412,7 +2412,7 @@ void VCAI::performTypicalActions()
|
|||||||
if(!h) //hero might be lost. getUnblockedHeroes() called once on start of turn
|
if(!h) //hero might be lost. getUnblockedHeroes() called once on start of turn
|
||||||
continue;
|
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);
|
makePossibleUpgrades(*h);
|
||||||
pickBestArtifacts(*h);
|
pickBestArtifacts(*h);
|
||||||
try
|
try
|
||||||
|
@ -388,7 +388,7 @@ void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffe
|
|||||||
void ClientCommandManager::handleMpCommand()
|
void ClientCommandManager::handleMpCommand()
|
||||||
{
|
{
|
||||||
if(const CGHeroInstance* h = LOCPLINT->localState->getCurrentHero())
|
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)
|
void ClientCommandManager::handleSetCommand(std::istringstream& singleWordBuffer)
|
||||||
|
@ -124,7 +124,7 @@ const CGHeroInstance * PlayerLocalState::getNextWanderingHero(const CGHeroInstan
|
|||||||
if (isHeroSleeping(hero))
|
if (isHeroSleeping(hero))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hero->movement == 0)
|
if (hero->movementPointsRemaining() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!firstSuitable)
|
if (!firstSuitable)
|
||||||
|
@ -676,7 +676,7 @@ void AdventureMapInterface::onTileHovered(const int3 &mapPos)
|
|||||||
|
|
||||||
void AdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode)
|
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 movementPointsLastTurnCost = maxMovementPointsAtStartOfLastTurn - pathNode.moveRemains;
|
||||||
const int remainingPointsAfterMove = pathNode.turns == 0 ? pathNode.moveRemains : 0;
|
const int remainingPointsAfterMove = pathNode.turns == 0 ? pathNode.moveRemains : 0;
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ void AdventureMapShortcuts::endTurn()
|
|||||||
{
|
{
|
||||||
for(auto hero : LOCPLINT->localState->getWanderingHeroes())
|
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:
|
// Only show hero reminder if conditions met:
|
||||||
// - There still movement points
|
// - There still movement points
|
||||||
@ -418,7 +418,7 @@ bool AdventureMapShortcuts::optionHeroSelected()
|
|||||||
bool AdventureMapShortcuts::optionHeroCanMove()
|
bool AdventureMapShortcuts::optionHeroCanMove()
|
||||||
{
|
{
|
||||||
const auto * hero = LOCPLINT->localState->getCurrentHero();
|
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()
|
bool AdventureMapShortcuts::optionHasNextHero()
|
||||||
|
@ -234,7 +234,7 @@ CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero)
|
|||||||
|
|
||||||
void CHeroList::CHeroItem::update()
|
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));
|
mana->setFrame(std::min<size_t>(mana->size()-1, hero->mana / 5));
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
@ -903,11 +903,9 @@ void SetMovePoints::applyGs(CGameState * gs) const
|
|||||||
assert(hero);
|
assert(hero);
|
||||||
|
|
||||||
if(absolute)
|
if(absolute)
|
||||||
hero->movement = val;
|
hero->setMovementPoints(val);
|
||||||
else
|
else
|
||||||
hero->movement += val;
|
hero->setMovementPoints(hero->movementPointsRemaining() + val);
|
||||||
|
|
||||||
vstd::amax(hero->movement, 0); //not less than 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoWChange::applyGs(CGameState *gs)
|
void FoWChange::applyGs(CGameState *gs)
|
||||||
@ -1276,7 +1274,7 @@ void TryMoveHero::applyGs(CGameState *gs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
h->movement = movePoints;
|
h->setMovementPoints(movePoints);
|
||||||
|
|
||||||
if((result == SUCCESS || result == BLOCKING_VISIT || result == EMBARK || result == DISEMBARK) && start != end)
|
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
|
{ // this is a fresh hero who hasn't appeared yet
|
||||||
if (boatId >= 0) //Hero spawns on water
|
if (boatId >= 0) //Hero spawns on water
|
||||||
{
|
{
|
||||||
h->movement = h->maxMovePoints(false);
|
h->setMovementPoints(h->movementPointsLimit(false));
|
||||||
}
|
}
|
||||||
else
|
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->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->getIndex())->getTemplates().front();
|
||||||
|
|
||||||
h->setOwner(player);
|
h->setOwner(player);
|
||||||
h->movement = h->maxMovePoints(true);
|
h->setMovementPoints(h->movementPointsLimit(true));
|
||||||
h->pos = h->convertFromVisitablePos(oldVisitablePos);
|
h->pos = h->convertFromVisitablePos(oldVisitablePos);
|
||||||
gs->map->heroesOnMap.emplace_back(h);
|
gs->map->heroesOnMap.emplace_back(h);
|
||||||
gs->getPlayerState(h->getOwner())->heroes.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());
|
logGlobal->error("Hero %d not found in NewTurn::applyGs", h.id.getNum());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
hero->movement = h.move;
|
hero->setMovementPoints(h.move);
|
||||||
hero->mana = h.mana;
|
hero->mana = h.mana;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ static int lowestSpeed(const CGHeroInstance * chi)
|
|||||||
return ret;
|
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;
|
int64_t ret = GameConstants::BASE_MOVEMENT_COST;
|
||||||
|
|
||||||
@ -201,10 +201,20 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
|
|||||||
return true;
|
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);
|
TurnInfo ti(this);
|
||||||
return maxMovePointsCached(onLand, &ti);
|
return movementPointsLimitCached(onLand, &ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGHeroInstance::getLowestCreatureSpeed() const
|
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);
|
updateArmyMovementBonus(onLand, ti);
|
||||||
return ti->valOfBonuses(BonusType::MOVEMENT, !!onLand);
|
return ti->valOfBonuses(BonusType::MOVEMENT, !!onLand);
|
||||||
@ -454,14 +464,14 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
const auto boatPos = visitablePos();
|
const auto boatPos = visitablePos();
|
||||||
if (cb->gameState()->map->getTile(boatPos).isWater())
|
if (cb->gameState()->map->getTile(boatPos).isWater())
|
||||||
{
|
{
|
||||||
smp.val = maxMovePoints(false);
|
smp.val = movementPointsLimit(false);
|
||||||
//Create a new boat for hero
|
//Create a new boat for hero
|
||||||
cb->createObject(boatPos, Obj::BOAT, getBoatType().getNum());
|
cb->createObject(boatPos, Obj::BOAT, getBoatType().getNum());
|
||||||
boatId = cb->getTopObj(boatPos)->id;
|
boatId = cb->getTopObj(boatPos)->id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
smp.val = maxMovePoints(true);
|
smp.val = movementPointsLimit(true);
|
||||||
}
|
}
|
||||||
cb->giveHero(id, h->tempOwner, boatId); //recreates def and adds hero to player
|
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
|
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
|
EDiggingStatus CGHeroInstance::diggingStatus() const
|
||||||
{
|
{
|
||||||
if(static_cast<int>(movement) < maxMovePoints(true))
|
if(static_cast<int>(movement) < movementPointsLimit(true))
|
||||||
return EDiggingStatus::LACK_OF_MOVEMENT;
|
return EDiggingStatus::LACK_OF_MOVEMENT;
|
||||||
if(!VLC->arth->objects[ArtifactID::GRAIL]->canBePutAt(this))
|
if(!VLC->arth->objects[ArtifactID::GRAIL]->canBePutAt(this))
|
||||||
return EDiggingStatus::BACKPACK_IS_FULL;
|
return EDiggingStatus::BACKPACK_IS_FULL;
|
||||||
|
@ -49,6 +49,7 @@ class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator,
|
|||||||
private:
|
private:
|
||||||
std::set<SpellID> spells; //known spells (spell IDs)
|
std::set<SpellID> spells; //known spells (spell IDs)
|
||||||
mutable int lowestCreatureSpeed;
|
mutable int lowestCreatureSpeed;
|
||||||
|
ui32 movement; //remaining movement points
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -67,7 +68,6 @@ public:
|
|||||||
si32 portrait; //may be custom
|
si32 portrait; //may be custom
|
||||||
si32 mana; // remaining spell points
|
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
|
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;
|
EHeroGender gender;
|
||||||
|
|
||||||
std::string nameCustom;
|
std::string nameCustom;
|
||||||
@ -155,7 +155,6 @@ public:
|
|||||||
EAlignment getAlignment() const;
|
EAlignment getAlignment() const;
|
||||||
bool needsLastStack()const override;
|
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
|
//INativeTerrainProvider
|
||||||
FactionID getFaction() const override;
|
FactionID getFaction() const override;
|
||||||
TerrainId getNativeTerrain() 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 setSecSkillLevel(const SecondarySkill & which, int val, bool abs); // abs == 0 - changes by value; 1 - sets to value
|
||||||
void levelUp(const std::vector<SecondarySkill> & skills);
|
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
|
//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
|
//update army movement bonus
|
||||||
void updateArmyMovementBonus(bool onLand, const TurnInfo * ti) const;
|
void updateArmyMovementBonus(bool onLand, const TurnInfo * ti) const;
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ int CPathfinderHelper::getMovementCost(
|
|||||||
|
|
||||||
bool isAirLayer = (hero->boat && hero->boat->layer == EPathfindingLayer::AIR) || ti->hasBonusOfType(BonusType::FLYING_MOVEMENT);
|
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(isSailLayer)
|
||||||
{
|
{
|
||||||
if(ct->hasFavorableWinds())
|
if(ct->hasFavorableWinds())
|
||||||
|
@ -123,7 +123,7 @@ std::vector<CGPathNode *> NodeStorage::getInitialNodes()
|
|||||||
auto * initialNode = getNode(out.hpos, out.hero->boat ? out.hero->boat->layer : EPathfindingLayer::LAND);
|
auto * initialNode = getNode(out.hpos, out.hero->boat ? out.hero->boat->layer : EPathfindingLayer::LAND);
|
||||||
|
|
||||||
initialNode->turns = 0;
|
initialNode->turns = 0;
|
||||||
initialNode->moveRemains = out.hero->movement;
|
initialNode->moveRemains = out.hero->movementPointsRemaining();
|
||||||
initialNode->setCost(0.0);
|
initialNode->setCost(0.0);
|
||||||
|
|
||||||
if(!initialNode->coord.valid())
|
if(!initialNode->coord.valid())
|
||||||
|
@ -107,9 +107,9 @@ int TurnInfo::valOfBonuses(BonusType type, int subtype) const
|
|||||||
int TurnInfo::getMaxMovePoints(const EPathfindingLayer & layer) const
|
int TurnInfo::getMaxMovePoints(const EPathfindingLayer & layer) const
|
||||||
{
|
{
|
||||||
if(maxMovePointsLand == -1)
|
if(maxMovePointsLand == -1)
|
||||||
maxMovePointsLand = hero->maxMovePointsCached(true, this);
|
maxMovePointsLand = hero->movementPointsLimitCached(true, this);
|
||||||
if(maxMovePointsWater == -1)
|
if(maxMovePointsWater == -1)
|
||||||
maxMovePointsWater = hero->maxMovePointsCached(false, this);
|
maxMovePointsWater = hero->movementPointsLimitCached(false, this);
|
||||||
|
|
||||||
return layer == EPathfindingLayer::SAIL ? maxMovePointsWater : maxMovePointsLand;
|
return layer == EPathfindingLayer::SAIL ? maxMovePointsWater : maxMovePointsLand;
|
||||||
}
|
}
|
||||||
|
@ -80,10 +80,10 @@ void Rewardable::Interface::grantRewardAfterLevelup(IGameCallback * cb, const Re
|
|||||||
{
|
{
|
||||||
SetMovePoints smp;
|
SetMovePoints smp;
|
||||||
smp.hid = hero->id;
|
smp.hid = hero->id;
|
||||||
smp.val = hero->movement;
|
smp.val = hero->movementPointsRemaining();
|
||||||
|
|
||||||
if (info.reward.movePercentage >= 0) // percent from max
|
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);
|
smp.val = std::max<si32>(0, smp.val + info.reward.movePoints);
|
||||||
|
|
||||||
cb->setMovePoints(&smp);
|
cb->setMovePoints(&smp);
|
||||||
|
@ -297,7 +297,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
|
|||||||
return ESpellCastResult::ERROR;
|
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!");
|
env->complain("Hero needs movement points to cast Dimension Door!");
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
@ -335,8 +335,8 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
|
|||||||
{
|
{
|
||||||
SetMovePoints smp;
|
SetMovePoints smp;
|
||||||
smp.hid = ObjectInstanceID(parameters.caster->getCasterUnitId());
|
smp.hid = ObjectInstanceID(parameters.caster->getCasterUnitId());
|
||||||
if(movementCost < static_cast<int>(parameters.caster->getHeroCaster()->movement))
|
if(movementCost < static_cast<int>(parameters.caster->getHeroCaster()->movementPointsRemaining()))
|
||||||
smp.val = parameters.caster->getHeroCaster()->movement - movementCost;
|
smp.val = parameters.caster->getHeroCaster()->movementPointsRemaining() - movementCost;
|
||||||
else
|
else
|
||||||
smp.val = 0;
|
smp.val = 0;
|
||||||
env->apply(&smp);
|
env->apply(&smp);
|
||||||
@ -369,7 +369,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
|
|||||||
if(nullptr == destination)
|
if(nullptr == destination)
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
|
|
||||||
if(static_cast<int>(parameters.caster->getHeroCaster()->movement) < moveCost)
|
if(static_cast<int>(parameters.caster->getHeroCaster()->movementPointsRemaining()) < moveCost)
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
|
|
||||||
if(destination->visitingHero)
|
if(destination->visitingHero)
|
||||||
@ -419,7 +419,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
|
|||||||
return ESpellCastResult::ERROR;
|
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!");
|
env->complain("This hero has not enough movement points!");
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
@ -441,7 +441,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
|
|||||||
{
|
{
|
||||||
SetMovePoints smp;
|
SetMovePoints smp;
|
||||||
smp.hid = ObjectInstanceID(parameters.caster->getCasterUnitId());
|
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);
|
env->apply(&smp);
|
||||||
}
|
}
|
||||||
return ESpellCastResult::OK;
|
return ESpellCastResult::OK;
|
||||||
@ -468,7 +468,7 @@ ESpellCastResult TownPortalMechanics::beginCast(SpellCastEnvironment * env, cons
|
|||||||
|
|
||||||
const int moveCost = movementCost(parameters);
|
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;
|
InfoWindow iw;
|
||||||
iw.player = parameters.caster->getCasterOwner();
|
iw.player = parameters.caster->getCasterOwner();
|
||||||
|
@ -1773,9 +1773,9 @@ void CGameHandler::newTurn()
|
|||||||
if (hero->isInitialized() && hero->stacks.size())
|
if (hero->isInitialized() && hero->stacks.size())
|
||||||
{
|
{
|
||||||
// reset retreated or surrendered heroes
|
// 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 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;
|
NewTurn::Hero hth;
|
||||||
hth.id = hero->id;
|
hth.id = hero->id;
|
||||||
@ -1864,7 +1864,7 @@ void CGameHandler::newTurn()
|
|||||||
hth.id = h->id;
|
hth.id = h->id;
|
||||||
auto ti = std::make_unique<TurnInfo>(h, 1);
|
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
|
// 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();
|
hth.mana = h->getManaNewTurn();
|
||||||
|
|
||||||
n.heroes.insert(hth);
|
n.heroes.insert(hth);
|
||||||
@ -2280,7 +2280,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
tmh.start = h->pos;
|
tmh.start = h->pos;
|
||||||
tmh.end = dst;
|
tmh.end = dst;
|
||||||
tmh.result = TryMoveHero::FAILED;
|
tmh.result = TryMoveHero::FAILED;
|
||||||
tmh.movePoints = h->movement;
|
tmh.movePoints = h->movementPointsRemaining();
|
||||||
|
|
||||||
//check if destination tile is available
|
//check if destination tile is available
|
||||||
auto pathfinderHelper = std::make_unique<CPathfinderHelper>(gs, h, PathfinderOptions());
|
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 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 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
|
//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)
|
//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!"))
|
&& complain("Tiles are not neighboring!"))
|
||||||
|| ((h->inTownGarrison)
|
|| ((h->inTownGarrison)
|
||||||
&& complain("Can not move garrisoned hero!"))
|
&& 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!"))
|
&& complain("Hero doesn't have any movement points left!"))
|
||||||
|| ((transit && !canFly && !CGTeleport::isTeleport(t.topVisitableObj()))
|
|| ((transit && !canFly && !CGTeleport::isTeleport(t.topVisitableObj()))
|
||||||
&& complain("Hero cannot transit over this tile!"))
|
&& complain("Hero cannot transit over this tile!"))
|
||||||
@ -2387,14 +2387,14 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
|
|
||||||
if (!transit && embarking)
|
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);
|
return doMove(TryMoveHero::EMBARK, IGNORE_GUARDS, DONT_VISIT_DEST, LEAVING_TILE);
|
||||||
// In H3 embark ignore guards
|
// In H3 embark ignore guards
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disembarking)
|
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);
|
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!
|
//still here? it is standard movement!
|
||||||
{
|
{
|
||||||
tmh.movePoints = (int)h->movement >= cost
|
tmh.movePoints = (int)h->movementPointsRemaining() >= cost
|
||||||
? h->movement - cost
|
? h->movementPointsRemaining() - cost
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
EGuardLook lookForGuards = CHECK_FOR_GUARDS;
|
EGuardLook lookForGuards = CHECK_FOR_GUARDS;
|
||||||
|
Loading…
Reference in New Issue
Block a user