mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Pathfinder now uses IGameInfoCallback instead of CGameState
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
#include "PathfindingRules.h"
|
||||
#include "TurnInfo.h"
|
||||
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../IGameSettings.h"
|
||||
#include "../CPlayerState.h"
|
||||
#include "../TerrainHandler.h"
|
||||
@@ -75,8 +74,8 @@ void CPathfinderHelper::calculateNeighbourTiles(NeighbourTilesVector & result, c
|
||||
}
|
||||
}
|
||||
|
||||
CPathfinder::CPathfinder(const CGameState & gamestate, std::shared_ptr<PathfinderConfig> config):
|
||||
gamestate(gamestate),
|
||||
CPathfinder::CPathfinder(const IGameInfoCallback & gameInfo, std::shared_ptr<PathfinderConfig> config):
|
||||
gameInfo(gameInfo),
|
||||
config(std::move(config))
|
||||
{
|
||||
initializeGraph();
|
||||
@@ -112,14 +111,14 @@ void CPathfinder::calculatePaths()
|
||||
|
||||
for(auto * initialNode : initialNodes)
|
||||
{
|
||||
if(!gamestate.isInTheMap(initialNode->coord)/* || !gameState().getMap().isInTheMap(dest)*/) //check input
|
||||
if(!gameInfo.isInTheMap(initialNode->coord)/* || !gameInfo.getMap().isInTheMap(dest)*/) //check input
|
||||
{
|
||||
logGlobal->error("CGameState::calculatePaths: Hero outside the gameState().map? How dare you...");
|
||||
logGlobal->error("CgameInfo::calculatePaths: Hero outside the gameInfo.map? How dare you...");
|
||||
throw std::runtime_error("Wrong checksum");
|
||||
}
|
||||
|
||||
source.setNode(gamestate, initialNode);
|
||||
auto * hlp = config->getOrCreatePathfinderHelper(source, gamestate);
|
||||
source.setNode(gameInfo, initialNode);
|
||||
auto * hlp = config->getOrCreatePathfinderHelper(source, gameInfo);
|
||||
|
||||
if(hlp->isHeroPatrolLocked())
|
||||
continue;
|
||||
@@ -134,14 +133,14 @@ void CPathfinder::calculatePaths()
|
||||
counter++;
|
||||
auto * node = topAndPop();
|
||||
|
||||
source.setNode(gamestate, node);
|
||||
source.setNode(gameInfo, node);
|
||||
source.node->locked = true;
|
||||
|
||||
int movement = source.node->moveRemains;
|
||||
uint8_t turn = source.node->turns;
|
||||
float cost = source.node->getCost();
|
||||
|
||||
auto * hlp = config->getOrCreatePathfinderHelper(source, gamestate);
|
||||
auto * hlp = config->getOrCreatePathfinderHelper(source, gameInfo);
|
||||
|
||||
hlp->updateTurnInfo(turn);
|
||||
if(movement == 0)
|
||||
@@ -155,7 +154,7 @@ void CPathfinder::calculatePaths()
|
||||
}
|
||||
|
||||
source.isInitialPosition = source.nodeHero == hlp->hero;
|
||||
source.updateInfo(hlp, gamestate);
|
||||
source.updateInfo(hlp, gameInfo);
|
||||
|
||||
//add accessible neighbouring nodes to the queue
|
||||
for(EPathfindingLayer layer = EPathfindingLayer::LAND; layer < EPathfindingLayer::NUM_LAYERS; layer.advance(1))
|
||||
@@ -170,8 +169,8 @@ void CPathfinder::calculatePaths()
|
||||
if(neighbour->locked)
|
||||
continue;
|
||||
|
||||
destination.setNode(gamestate, neighbour);
|
||||
hlp = config->getOrCreatePathfinderHelper(destination, gamestate);
|
||||
destination.setNode(gameInfo, neighbour);
|
||||
hlp = config->getOrCreatePathfinderHelper(destination, gameInfo);
|
||||
|
||||
if(!hlp->isPatrolMovementAllowed(neighbour->coord))
|
||||
continue;
|
||||
@@ -183,7 +182,7 @@ void CPathfinder::calculatePaths()
|
||||
destination.turn = turn;
|
||||
destination.movementLeft = movement;
|
||||
destination.cost = cost;
|
||||
destination.updateInfo(hlp, gamestate);
|
||||
destination.updateInfo(hlp, gameInfo);
|
||||
destination.isGuardianTile = destination.guarded && isDestinationGuardian();
|
||||
|
||||
for(const auto & rule : config->rules)
|
||||
@@ -201,7 +200,7 @@ void CPathfinder::calculatePaths()
|
||||
}
|
||||
|
||||
//just add all passable teleport exits
|
||||
hlp = config->getOrCreatePathfinderHelper(source, gamestate);
|
||||
hlp = config->getOrCreatePathfinderHelper(source, gameInfo);
|
||||
|
||||
/// For now we disable teleports usage for patrol movement
|
||||
/// VCAI not aware about patrol and may stuck while attempt to use teleport
|
||||
@@ -221,7 +220,7 @@ void CPathfinder::calculatePaths()
|
||||
if(teleportNode->accessible == EPathAccessibility::BLOCKED)
|
||||
continue;
|
||||
|
||||
destination.setNode(gamestate, teleportNode);
|
||||
destination.setNode(gameInfo, teleportNode);
|
||||
destination.turn = turn;
|
||||
destination.movementLeft = movement;
|
||||
destination.cost = cost;
|
||||
@@ -244,20 +243,20 @@ TeleporterTilesVector CPathfinderHelper::getAllowedTeleportChannelExits(const Te
|
||||
{
|
||||
TeleporterTilesVector allowedExits;
|
||||
|
||||
for(const auto & objId : gameState().getTeleportChannelExits(channelID, hero->tempOwner))
|
||||
for(const auto & objId : gameInfo.getTeleportChannelExits(channelID, hero->tempOwner))
|
||||
{
|
||||
const auto * obj = gameState().getObj(objId);
|
||||
const auto * obj = gameInfo.getObj(objId);
|
||||
if(dynamic_cast<const CGWhirlpool *>(obj))
|
||||
{
|
||||
auto pos = obj->getBlockedPos();
|
||||
for(const auto & p : pos)
|
||||
{
|
||||
ObjectInstanceID topObject = gameState().getMap().getTile(p).topVisitableObj();
|
||||
if(topObject.hasValue() && gameState().getObj(topObject)->ID == obj->ID)
|
||||
ObjectInstanceID topObject = gameInfo.getTile(p)->topVisitableObj();
|
||||
if(topObject.hasValue() && gameInfo.getObj(topObject)->ID == obj->ID)
|
||||
allowedExits.push_back(p);
|
||||
}
|
||||
}
|
||||
else if(obj && CGTeleport::isExitPassable(gameState(), hero, obj))
|
||||
else if(obj && CGTeleport::isExitPassable(gameInfo, hero, obj))
|
||||
allowedExits.push_back(obj->visitablePos());
|
||||
}
|
||||
|
||||
@@ -268,7 +267,7 @@ TeleporterTilesVector CPathfinderHelper::getCastleGates(const PathNodeInfo & sou
|
||||
{
|
||||
TeleporterTilesVector allowedExits;
|
||||
|
||||
for(const auto & town : gameState().getPlayerState(hero->tempOwner)->getTowns())
|
||||
for(const auto & town : gameInfo.getPlayerState(hero->tempOwner)->getTowns())
|
||||
{
|
||||
if(town->id != source.nodeObject->id && town->getVisitingHero() == nullptr
|
||||
&& town->hasBuilt(BuildingSubID::CASTLE_GATE))
|
||||
@@ -391,19 +390,19 @@ EPathNodeAction CPathfinder::getTeleportDestAction() const
|
||||
|
||||
bool CPathfinder::isDestinationGuardian() const
|
||||
{
|
||||
return gamestate.guardingCreaturePosition(destination.node->coord) == destination.node->coord;
|
||||
return gameInfo.guardingCreaturePosition(destination.node->coord) == destination.node->coord;
|
||||
}
|
||||
|
||||
void CPathfinderHelper::initializePatrol()
|
||||
{
|
||||
auto state = PATROL_NONE;
|
||||
|
||||
if(hero->patrol.patrolling && !gameState().getPlayerState(hero->tempOwner)->human)
|
||||
if(hero->patrol.patrolling && !gameInfo.getPlayerState(hero->tempOwner)->human)
|
||||
{
|
||||
if(hero->patrol.patrolRadius)
|
||||
{
|
||||
state = PATROL_RADIUS;
|
||||
gameState().getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadius, ETileVisibility::REVEALED, std::optional<PlayerColor>(), int3::DIST_MANHATTAN);
|
||||
gameInfo.getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadius, ETileVisibility::REVEALED, std::optional<PlayerColor>(), int3::DIST_MANHATTAN);
|
||||
}
|
||||
else
|
||||
state = PATROL_LOCKED;
|
||||
@@ -415,17 +414,17 @@ void CPathfinderHelper::initializePatrol()
|
||||
void CPathfinder::initializeGraph()
|
||||
{
|
||||
INodeStorage * nodeStorage = config->nodeStorage.get();
|
||||
nodeStorage->initialize(config->options, &gamestate);
|
||||
nodeStorage->initialize(config->options, gameInfo);
|
||||
}
|
||||
|
||||
bool CPathfinderHelper::canMoveBetween(const int3 & a, const int3 & b) const
|
||||
{
|
||||
return gameState().checkForVisitableDir(a, b);
|
||||
return gameInfo.checkForVisitableDir(a, b);
|
||||
}
|
||||
|
||||
bool CPathfinderHelper::isAllowedTeleportEntrance(const CGTeleport * obj) const
|
||||
{
|
||||
if(!obj || !gameState().isTeleportEntrancePassable(obj, hero->tempOwner))
|
||||
if(!obj || !gameInfo.isTeleportEntrancePassable(obj, hero->tempOwner))
|
||||
return false;
|
||||
|
||||
const auto * whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
|
||||
@@ -442,14 +441,14 @@ bool CPathfinderHelper::isAllowedTeleportEntrance(const CGTeleport * obj) const
|
||||
|
||||
bool CPathfinderHelper::addTeleportTwoWay(const CGTeleport * obj) const
|
||||
{
|
||||
return options.useTeleportTwoWay && gameState().isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
|
||||
return options.useTeleportTwoWay && gameInfo.isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
|
||||
}
|
||||
|
||||
bool CPathfinderHelper::addTeleportOneWay(const CGTeleport * obj) const
|
||||
{
|
||||
if(options.useTeleportOneWay && gameState().isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
||||
if(options.useTeleportOneWay && gameInfo.isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
||||
{
|
||||
auto passableExits = CGTeleport::getPassableExits(gameState(), hero, gameState().getTeleportChannelExits(obj->channel, hero->tempOwner));
|
||||
auto passableExits = CGTeleport::getPassableExits(gameInfo, hero, gameInfo.getTeleportChannelExits(obj->channel, hero->tempOwner));
|
||||
if(passableExits.size() == 1)
|
||||
return true;
|
||||
}
|
||||
@@ -458,9 +457,9 @@ bool CPathfinderHelper::addTeleportOneWay(const CGTeleport * obj) const
|
||||
|
||||
bool CPathfinderHelper::addTeleportOneWayRandom(const CGTeleport * obj) const
|
||||
{
|
||||
if(options.useTeleportOneWayRandom && gameState().isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
||||
if(options.useTeleportOneWayRandom && gameInfo.isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
||||
{
|
||||
auto passableExits = CGTeleport::getPassableExits(gameState(), hero, gameState().getTeleportChannelExits(obj->channel, hero->tempOwner));
|
||||
auto passableExits = CGTeleport::getPassableExits(gameInfo, hero, gameInfo.getTeleportChannelExits(obj->channel, hero->tempOwner));
|
||||
if(passableExits.size() > 1)
|
||||
return true;
|
||||
}
|
||||
@@ -495,11 +494,11 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) const
|
||||
|
||||
int CPathfinderHelper::getGuardiansCount(int3 tile) const
|
||||
{
|
||||
return gameState().getGuardingCreatures(tile).size();
|
||||
return gameInfo.getGuardingCreatures(tile).size();
|
||||
}
|
||||
|
||||
CPathfinderHelper::CPathfinderHelper(const CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options):
|
||||
gs(gs),
|
||||
CPathfinderHelper::CPathfinderHelper(const IGameInfoCallback & gameInfo, const CGHeroInstance * Hero, const PathfinderOptions & Options):
|
||||
gameInfo(gameInfo),
|
||||
turn(-1),
|
||||
owner(Hero->tempOwner),
|
||||
hero(Hero),
|
||||
@@ -573,7 +572,6 @@ void CPathfinderHelper::getNeighbours(
|
||||
const boost::logic::tribool & onLand,
|
||||
const bool limitCoastSailing) const
|
||||
{
|
||||
const CMap * map = &gameState().getMap();
|
||||
const TerrainType * sourceTerrain = sourceTile.getTerrain();
|
||||
|
||||
static constexpr std::array dirs = {
|
||||
@@ -585,11 +583,11 @@ void CPathfinderHelper::getNeighbours(
|
||||
for(const auto & dir : dirs)
|
||||
{
|
||||
const int3 destCoord = srcCoord + dir;
|
||||
if(!map->isInTheMap(destCoord))
|
||||
if(!gameInfo.isInTheMap(destCoord))
|
||||
continue;
|
||||
|
||||
const TerrainTile & destTile = map->getTile(destCoord);
|
||||
const TerrainType * destTerrain = destTile.getTerrain();
|
||||
const TerrainTile * destTile = gameInfo.getTile(destCoord);
|
||||
const TerrainType * destTerrain = destTile->getTerrain();
|
||||
if(!destTerrain->isPassable())
|
||||
continue;
|
||||
|
||||
@@ -598,7 +596,7 @@ void CPathfinderHelper::getNeighbours(
|
||||
{
|
||||
const int3 horizontalNeighbour = srcCoord + int3{dir.x, 0, 0};
|
||||
const int3 verticalNeighbour = srcCoord + int3{0, dir.y, 0};
|
||||
if(map->getTile(horizontalNeighbour).isLand() || map->getTile(verticalNeighbour).isLand())
|
||||
if(gameInfo.getTile(horizontalNeighbour)->isLand() || gameInfo.getTile(verticalNeighbour)->isLand())
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -670,7 +668,7 @@ int CPathfinderHelper::getMovementCost(
|
||||
}
|
||||
else if(isAirLayer)
|
||||
{
|
||||
int baseCost = gameState().getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||
int baseCost = gameInfo.getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||
vstd::amin(movementCost, baseCost + ti->getFlyingMovementValue());
|
||||
}
|
||||
else if(isWaterLayer && ti->hasWaterWalking())
|
||||
@@ -716,7 +714,7 @@ ui32 CPathfinderHelper::getTileMovementCost(const TerrainTile & dest, const Terr
|
||||
//if hero can move without penalty - either all-native army, or creatures like Nomads in army
|
||||
if(ti->hasNoTerrainPenalty(from.getTerrainID()))
|
||||
{
|
||||
int baseCost = gameState().getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||
int baseCost = gameInfo.getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||
return std::min(baseCost, costWithPathfinding);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user