mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Pathfinder now uses CGameState directly instead of inheriting callback
This commit is contained in:
@@ -56,7 +56,7 @@ namespace AIPathfinding
|
|||||||
|
|
||||||
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
||||||
|
|
||||||
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs)
|
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs)
|
||||||
{
|
{
|
||||||
auto hero = aiNodeStorage->getHero(source.node);
|
auto hero = aiNodeStorage->getHero(source.node);
|
||||||
auto & helper = pathfindingHelpers[hero];
|
auto & helper = pathfindingHelpers[hero];
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace AIPathfinding
|
|||||||
|
|
||||||
~AIPathfinderConfig();
|
~AIPathfinderConfig();
|
||||||
|
|
||||||
CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs) override;
|
CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace AIPathfinding
|
|||||||
|
|
||||||
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
||||||
|
|
||||||
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs)
|
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs)
|
||||||
{
|
{
|
||||||
if(!helper)
|
if(!helper)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ namespace AIPathfinding
|
|||||||
|
|
||||||
~AIPathfinderConfig();
|
~AIPathfinderConfig();
|
||||||
|
|
||||||
CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs) override;
|
CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1089,7 +1089,7 @@ void CGameState::apply(CPackForClient & pack)
|
|||||||
|
|
||||||
void CGameState::calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const
|
void CGameState::calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const
|
||||||
{
|
{
|
||||||
CPathfinder pathfinder(*const_cast<CGameState*>(this), config);
|
CPathfinder pathfinder(*this, config);
|
||||||
pathfinder.calculatePaths();
|
pathfinder.calculatePaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ PathNodeInfo::PathNodeInfo()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathNodeInfo::setNode(CGameState & gs, CGPathNode * n)
|
void PathNodeInfo::setNode(const CGameState & gs, CGPathNode * n)
|
||||||
{
|
{
|
||||||
node = n;
|
node = n;
|
||||||
guarded = false;
|
guarded = false;
|
||||||
@@ -132,7 +132,7 @@ void PathNodeInfo::setNode(CGameState & gs, CGPathNode * n)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathNodeInfo::updateInfo(CPathfinderHelper * hlp, CGameState & gs)
|
void PathNodeInfo::updateInfo(CPathfinderHelper * hlp, const CGameState & gs)
|
||||||
{
|
{
|
||||||
if(gs.guardingCreaturePosition(node->coord).isValid() && !isInitialPosition)
|
if(gs.guardingCreaturePosition(node->coord).isValid() && !isInitialPosition)
|
||||||
{
|
{
|
||||||
@@ -164,7 +164,7 @@ CDestinationNodeInfo::CDestinationNodeInfo():
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDestinationNodeInfo::setNode(CGameState & gs, CGPathNode * n)
|
void CDestinationNodeInfo::setNode(const CGameState & gs, CGPathNode * n)
|
||||||
{
|
{
|
||||||
PathNodeInfo::setNode(gs, n);
|
PathNodeInfo::setNode(gs, n);
|
||||||
|
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ struct DLL_LINKAGE PathNodeInfo
|
|||||||
|
|
||||||
PathNodeInfo();
|
PathNodeInfo();
|
||||||
|
|
||||||
virtual void setNode(CGameState & gs, CGPathNode * n);
|
virtual void setNode(const CGameState & gs, CGPathNode * n);
|
||||||
|
|
||||||
void updateInfo(CPathfinderHelper * hlp, CGameState & gs);
|
void updateInfo(CPathfinderHelper * hlp, const CGameState & gs);
|
||||||
|
|
||||||
bool isNodeObjectVisitable() const;
|
bool isNodeObjectVisitable() const;
|
||||||
};
|
};
|
||||||
@@ -237,7 +237,7 @@ struct DLL_LINKAGE CDestinationNodeInfo : public PathNodeInfo
|
|||||||
|
|
||||||
CDestinationNodeInfo();
|
CDestinationNodeInfo();
|
||||||
|
|
||||||
void setNode(CGameState & gs, CGPathNode * n) override;
|
void setNode(const CGameState & gs, CGPathNode * n) override;
|
||||||
|
|
||||||
virtual bool isBetterWay() const;
|
virtual bool isBetterWay() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void CPathfinderHelper::calculateNeighbourTiles(NeighbourTilesVector & result, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathfinder::CPathfinder(CGameState & gamestate, std::shared_ptr<PathfinderConfig> config):
|
CPathfinder::CPathfinder(const CGameState & gamestate, std::shared_ptr<PathfinderConfig> config):
|
||||||
gamestate(gamestate),
|
gamestate(gamestate),
|
||||||
config(std::move(config))
|
config(std::move(config))
|
||||||
{
|
{
|
||||||
@@ -244,16 +244,16 @@ TeleporterTilesVector CPathfinderHelper::getAllowedTeleportChannelExits(const Te
|
|||||||
{
|
{
|
||||||
TeleporterTilesVector allowedExits;
|
TeleporterTilesVector allowedExits;
|
||||||
|
|
||||||
for(const auto & objId : getTeleportChannelExits(channelID, hero->tempOwner))
|
for(const auto & objId : gameState().getTeleportChannelExits(channelID, hero->tempOwner))
|
||||||
{
|
{
|
||||||
const auto * obj = getObj(objId);
|
const auto * obj = gameState().getObj(objId);
|
||||||
if(dynamic_cast<const CGWhirlpool *>(obj))
|
if(dynamic_cast<const CGWhirlpool *>(obj))
|
||||||
{
|
{
|
||||||
auto pos = obj->getBlockedPos();
|
auto pos = obj->getBlockedPos();
|
||||||
for(const auto & p : pos)
|
for(const auto & p : pos)
|
||||||
{
|
{
|
||||||
ObjectInstanceID topObject = gameState().getMap().getTile(p).topVisitableObj();
|
ObjectInstanceID topObject = gameState().getMap().getTile(p).topVisitableObj();
|
||||||
if(topObject.hasValue() && getObj(topObject)->ID == obj->ID)
|
if(topObject.hasValue() && gameState().getObj(topObject)->ID == obj->ID)
|
||||||
allowedExits.push_back(p);
|
allowedExits.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ TeleporterTilesVector CPathfinderHelper::getCastleGates(const PathNodeInfo & sou
|
|||||||
{
|
{
|
||||||
TeleporterTilesVector allowedExits;
|
TeleporterTilesVector allowedExits;
|
||||||
|
|
||||||
for(const auto & town : getPlayerState(hero->tempOwner)->getTowns())
|
for(const auto & town : gameState().getPlayerState(hero->tempOwner)->getTowns())
|
||||||
{
|
{
|
||||||
if(town->id != source.nodeObject->id && town->getVisitingHero() == nullptr
|
if(town->id != source.nodeObject->id && town->getVisitingHero() == nullptr
|
||||||
&& town->hasBuilt(BuildingSubID::CASTLE_GATE))
|
&& town->hasBuilt(BuildingSubID::CASTLE_GATE))
|
||||||
@@ -398,7 +398,7 @@ void CPathfinderHelper::initializePatrol()
|
|||||||
{
|
{
|
||||||
auto state = PATROL_NONE;
|
auto state = PATROL_NONE;
|
||||||
|
|
||||||
if(hero->patrol.patrolling && !getPlayerState(hero->tempOwner)->human)
|
if(hero->patrol.patrolling && !gameState().getPlayerState(hero->tempOwner)->human)
|
||||||
{
|
{
|
||||||
if(hero->patrol.patrolRadius)
|
if(hero->patrol.patrolRadius)
|
||||||
{
|
{
|
||||||
@@ -425,7 +425,7 @@ bool CPathfinderHelper::canMoveBetween(const int3 & a, const int3 & b) const
|
|||||||
|
|
||||||
bool CPathfinderHelper::isAllowedTeleportEntrance(const CGTeleport * obj) const
|
bool CPathfinderHelper::isAllowedTeleportEntrance(const CGTeleport * obj) const
|
||||||
{
|
{
|
||||||
if(!obj || !isTeleportEntrancePassable(obj, hero->tempOwner))
|
if(!obj || !gameState().isTeleportEntrancePassable(obj, hero->tempOwner))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto * whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
|
const auto * whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
|
||||||
@@ -442,14 +442,14 @@ bool CPathfinderHelper::isAllowedTeleportEntrance(const CGTeleport * obj) const
|
|||||||
|
|
||||||
bool CPathfinderHelper::addTeleportTwoWay(const CGTeleport * obj) const
|
bool CPathfinderHelper::addTeleportTwoWay(const CGTeleport * obj) const
|
||||||
{
|
{
|
||||||
return options.useTeleportTwoWay && isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
|
return options.useTeleportTwoWay && gameState().isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPathfinderHelper::addTeleportOneWay(const CGTeleport * obj) const
|
bool CPathfinderHelper::addTeleportOneWay(const CGTeleport * obj) const
|
||||||
{
|
{
|
||||||
if(options.useTeleportOneWay && isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
if(options.useTeleportOneWay && gameState().isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
||||||
{
|
{
|
||||||
auto passableExits = CGTeleport::getPassableExits(gameState(), hero, getTeleportChannelExits(obj->channel, hero->tempOwner));
|
auto passableExits = CGTeleport::getPassableExits(gameState(), hero, gameState().getTeleportChannelExits(obj->channel, hero->tempOwner));
|
||||||
if(passableExits.size() == 1)
|
if(passableExits.size() == 1)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -458,9 +458,9 @@ bool CPathfinderHelper::addTeleportOneWay(const CGTeleport * obj) const
|
|||||||
|
|
||||||
bool CPathfinderHelper::addTeleportOneWayRandom(const CGTeleport * obj) const
|
bool CPathfinderHelper::addTeleportOneWayRandom(const CGTeleport * obj) const
|
||||||
{
|
{
|
||||||
if(options.useTeleportOneWayRandom && isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
if(options.useTeleportOneWayRandom && gameState().isTeleportChannelUnidirectional(obj->channel, hero->tempOwner))
|
||||||
{
|
{
|
||||||
auto passableExits = CGTeleport::getPassableExits(gameState(), hero, getTeleportChannelExits(obj->channel, hero->tempOwner));
|
auto passableExits = CGTeleport::getPassableExits(gameState(), hero, gameState().getTeleportChannelExits(obj->channel, hero->tempOwner));
|
||||||
if(passableExits.size() > 1)
|
if(passableExits.size() > 1)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -495,10 +495,10 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) const
|
|||||||
|
|
||||||
int CPathfinderHelper::getGuardiansCount(int3 tile) const
|
int CPathfinderHelper::getGuardiansCount(int3 tile) const
|
||||||
{
|
{
|
||||||
return getGuardingCreatures(tile).size();
|
return gameState().getGuardingCreatures(tile).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathfinderHelper::CPathfinderHelper(CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options):
|
CPathfinderHelper::CPathfinderHelper(const CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options):
|
||||||
gs(gs),
|
gs(gs),
|
||||||
turn(-1),
|
turn(-1),
|
||||||
owner(Hero->tempOwner),
|
owner(Hero->tempOwner),
|
||||||
@@ -670,7 +670,7 @@ int CPathfinderHelper::getMovementCost(
|
|||||||
}
|
}
|
||||||
else if(isAirLayer)
|
else if(isAirLayer)
|
||||||
{
|
{
|
||||||
int baseCost = getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
int baseCost = gameState().getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||||
vstd::amin(movementCost, baseCost + ti->getFlyingMovementValue());
|
vstd::amin(movementCost, baseCost + ti->getFlyingMovementValue());
|
||||||
}
|
}
|
||||||
else if(isWaterLayer && ti->hasWaterWalking())
|
else if(isWaterLayer && ti->hasWaterWalking())
|
||||||
@@ -716,7 +716,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 hero can move without penalty - either all-native army, or creatures like Nomads in army
|
||||||
if(ti->hasNoTerrainPenalty(from.getTerrainID()))
|
if(ti->hasNoTerrainPenalty(from.getTerrainID()))
|
||||||
{
|
{
|
||||||
int baseCost = getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
int baseCost = gameState().getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||||
return std::min(baseCost, costWithPathfinding);
|
return std::min(baseCost, costWithPathfinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ public:
|
|||||||
friend class CPathfinderHelper;
|
friend class CPathfinderHelper;
|
||||||
|
|
||||||
CPathfinder(
|
CPathfinder(
|
||||||
CGameState & _gs,
|
const CGameState & _gs,
|
||||||
std::shared_ptr<PathfinderConfig> config);
|
std::shared_ptr<PathfinderConfig> config);
|
||||||
|
|
||||||
void calculatePaths(); //calculates possible paths for hero, uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
|
void calculatePaths(); //calculates possible paths for hero, uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGameState & gamestate;
|
const CGameState & gamestate;
|
||||||
|
|
||||||
using ELayer = EPathfindingLayer;
|
using ELayer = EPathfindingLayer;
|
||||||
|
|
||||||
@@ -63,12 +63,12 @@ private:
|
|||||||
CGPathNode * topAndPop();
|
CGPathNode * topAndPop();
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CPathfinderHelper : private CGameInfoCallback
|
class DLL_LINKAGE CPathfinderHelper
|
||||||
{
|
{
|
||||||
/// returns base movement cost for movement between specific tiles. Does not accounts for diagonal movement or last tile exception
|
/// 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;
|
ui32 getTileMovementCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const;
|
||||||
|
|
||||||
CGameState & gs;
|
const CGameState & gs;
|
||||||
public:
|
public:
|
||||||
enum EPatrolState
|
enum EPatrolState
|
||||||
{
|
{
|
||||||
@@ -87,10 +87,9 @@ public:
|
|||||||
bool canCastWaterWalk;
|
bool canCastWaterWalk;
|
||||||
bool whirlpoolProtection;
|
bool whirlpoolProtection;
|
||||||
|
|
||||||
CPathfinderHelper(CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options);
|
CPathfinderHelper(const CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options);
|
||||||
virtual ~CPathfinderHelper();
|
virtual ~CPathfinderHelper();
|
||||||
CGameState & gameState() final { return gs; }
|
const CGameState & gameState() const { return gs; }
|
||||||
const CGameState & gameState() const final { return gs; }
|
|
||||||
void initializePatrol();
|
void initializePatrol();
|
||||||
bool isHeroPatrolLocked() const;
|
bool isHeroPatrolLocked() const;
|
||||||
bool canMoveFromNode(const PathNodeInfo & source) const;
|
bool canMoveFromNode(const PathNodeInfo & source) const;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ SingleHeroPathfinderConfig::SingleHeroPathfinderConfig(CPathsInfo & out, const I
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathfinderHelper * SingleHeroPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs)
|
CPathfinderHelper * SingleHeroPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs)
|
||||||
{
|
{
|
||||||
if (!pathfinderHelper)
|
if (!pathfinderHelper)
|
||||||
pathfinderHelper = std::make_unique<CPathfinderHelper>(gs, hero, options);
|
pathfinderHelper = std::make_unique<CPathfinderHelper>(gs, hero, options);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public:
|
|||||||
std::vector<std::shared_ptr<IPathfindingRule>> rules);
|
std::vector<std::shared_ptr<IPathfindingRule>> rules);
|
||||||
virtual ~PathfinderConfig() = default;
|
virtual ~PathfinderConfig() = default;
|
||||||
|
|
||||||
virtual CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs) = 0;
|
virtual CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE SingleHeroPathfinderConfig : public PathfinderConfig
|
class DLL_LINKAGE SingleHeroPathfinderConfig : public PathfinderConfig
|
||||||
@@ -114,7 +114,7 @@ public:
|
|||||||
SingleHeroPathfinderConfig(CPathsInfo & out, const IGameInfoCallback & gs, const CGHeroInstance * hero);
|
SingleHeroPathfinderConfig(CPathsInfo & out, const IGameInfoCallback & gs, const CGHeroInstance * hero);
|
||||||
virtual ~SingleHeroPathfinderConfig();
|
virtual ~SingleHeroPathfinderConfig();
|
||||||
|
|
||||||
CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs) override;
|
CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs) override;
|
||||||
|
|
||||||
static std::vector<std::shared_ptr<IPathfindingRule>> buildRuleSet();
|
static std::vector<std::shared_ptr<IPathfindingRule>> buildRuleSet();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user