1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-01 00:45:26 +02:00

Pathfinding: implement duration checking for fly and water walking

Now pathfinder take into account different bonuses for different tuns. So if you only have FLYING_MOVEMENT bonus from Fly spell for one turn then pathfinder will only let you use air layer within one turn only.

That work for cost calculations too. Let's say you have two bonuses:
 - FLYING_MOVEMENT with 20% penalty for next 2 turns
 - FLYING_MOVEMENT with 40% penalty for 5 turns
Now pathfinder using correct penalty for each turn so movements in air layer going to be more expensive on 3-5 turns.
This commit is contained in:
ArseniyShestakov
2015-11-09 19:57:26 +03:00
parent 5106738160
commit d3c8ca7c1c
7 changed files with 47 additions and 26 deletions

View File

@ -2100,7 +2100,7 @@ void CGameState::getNeighbours(const TerrainTile &srct, int3 tile, std::vector<i
}
}
int CGameState::getMovementCost(const CGHeroInstance *h, const int3 &src, const int3 &dest, int remainingMovePoints, bool checkLast)
int CGameState::getMovementCost(const CGHeroInstance *h, const int3 &src, const int3 &dest, int remainingMovePoints, const int &turn, bool checkLast)
{
if(src == dest) //same tile
return 0;
@ -2109,19 +2109,21 @@ int CGameState::getMovementCost(const CGHeroInstance *h, const int3 &src, const
&d = map->getTile(dest);
//get basic cost
int ret = h->getTileCost(d,s);
int ret = h->getTileCost(d, s, turn);
if(d.blocked && h->canFly())
auto flyBonus = h->getBonusAtTurn(Bonus::FLYING_MOVEMENT, turn);
auto waterWalkingBonus = h->getBonusAtTurn(Bonus::WATER_WALKING, turn);
if(d.blocked && flyBonus)
{
ret *= (100.0 + h->valOfBonuses(Bonus::FLYING_MOVEMENT)) / 100.0;
ret *= (100.0 + flyBonus->val) / 100.0;
}
else if(d.terType == ETerrainType::WATER)
{
if(h->boat && s.hasFavourableWinds() && d.hasFavourableWinds()) //Favourable Winds
ret *= 0.666;
else if(!h->boat && h->canWalkOnSea())
else if(!h->boat && waterWalkingBonus)
{
ret *= (100.0 + h->valOfBonuses(Bonus::WATER_WALKING)) / 100.0;
ret *= (100.0 + waterWalkingBonus->val) / 100.0;
}
}
@ -2145,7 +2147,7 @@ int CGameState::getMovementCost(const CGHeroInstance *h, const int3 &src, const
getNeighbours(d, dest, vec, s.terType != ETerrainType::WATER, true);
for(auto & elem : vec)
{
int fcost = getMovementCost(h, dest, elem, left, false);
int fcost = getMovementCost(h, dest, elem, left, turn, false);
if(fcost <= left)
{
return ret;