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

CGameState: move two pathfinding-related functions to CPathfinderHelper

Both getMovementCost and getNeighbours have nothing to do with gamestate.
This commit is contained in:
ArseniyShestakov
2015-11-10 02:15:27 +03:00
parent d3c8ca7c1c
commit b2e1ee5363
8 changed files with 111 additions and 113 deletions

View File

@ -2061,103 +2061,6 @@ PlayerRelations::PlayerRelations CGameState::getPlayerRelations( PlayerColor col
return PlayerRelations::ENEMIES;
}
void CGameState::getNeighbours(const TerrainTile &srct, int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand, bool limitCoastSailing)
{
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
//vec.reserve(8); //optimization
for (auto & dir : dirs)
{
const int3 hlp = tile + dir;
if(!map->isInTheMap(hlp))
continue;
const TerrainTile &hlpt = map->getTile(hlp);
// //we cannot visit things from blocked tiles
// if(srct.blocked && !srct.visitable && hlpt.visitable && srct.blockingObjects.front()->ID != HEROI_TYPE)
// {
// continue;
// }
if(srct.terType == ETerrainType::WATER && limitCoastSailing && hlpt.terType == ETerrainType::WATER && dir.x && dir.y) //diagonal move through water
{
int3 hlp1 = tile,
hlp2 = tile;
hlp1.x += dir.x;
hlp2.y += dir.y;
if(map->getTile(hlp1).terType != ETerrainType::WATER || map->getTile(hlp2).terType != ETerrainType::WATER)
continue;
}
if((indeterminate(onLand) || onLand == (hlpt.terType!=ETerrainType::WATER) )
&& hlpt.terType != ETerrainType::ROCK)
{
vec.push_back(hlp);
}
}
}
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;
TerrainTile &s = map->getTile(src),
&d = map->getTile(dest);
//get basic cost
int ret = h->getTileCost(d, s, turn);
auto flyBonus = h->getBonusAtTurn(Bonus::FLYING_MOVEMENT, turn);
auto waterWalkingBonus = h->getBonusAtTurn(Bonus::WATER_WALKING, turn);
if(d.blocked && flyBonus)
{
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 && waterWalkingBonus)
{
ret *= (100.0 + waterWalkingBonus->val) / 100.0;
}
}
if(src.x != dest.x && src.y != dest.y) //it's diagonal move
{
int old = ret;
ret *= 1.414213;
//diagonal move costs too much but normal move is possible - allow diagonal move for remaining move points
if(ret > remainingMovePoints && remainingMovePoints >= old)
{
return remainingMovePoints;
}
}
int left = remainingMovePoints-ret;
if(checkLast && left > 0 && remainingMovePoints-ret < 250) //it might be the last tile - if no further move possible we take all move points
{
std::vector<int3> vec;
vec.reserve(8); //optimization
getNeighbours(d, dest, vec, s.terType != ETerrainType::WATER, true);
for(auto & elem : vec)
{
int fcost = getMovementCost(h, dest, elem, left, turn, false);
if(fcost <= left)
{
return ret;
}
}
ret = remainingMovePoints;
}
return ret;
}
void CGameState::apply(CPack *pack)
{
ui16 typ = typeList.getTypeID(pack);