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;
|
||||
|
||||
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs)
|
||||
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs)
|
||||
{
|
||||
auto hero = aiNodeStorage->getHero(source.node);
|
||||
auto & helper = pathfindingHelpers[hero];
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace AIPathfinding
|
||||
|
||||
~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;
|
||||
|
||||
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs)
|
||||
CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs)
|
||||
{
|
||||
if(!helper)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,6 @@ namespace AIPathfinding
|
||||
|
||||
~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
|
||||
{
|
||||
CPathfinder pathfinder(*const_cast<CGameState*>(this), config);
|
||||
CPathfinder pathfinder(*this, config);
|
||||
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;
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -219,9 +219,9 @@ struct DLL_LINKAGE 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;
|
||||
};
|
||||
@@ -237,7 +237,7 @@ struct DLL_LINKAGE CDestinationNodeInfo : public PathNodeInfo
|
||||
|
||||
CDestinationNodeInfo();
|
||||
|
||||
void setNode(CGameState & gs, CGPathNode * n) override;
|
||||
void setNode(const CGameState & gs, CGPathNode * n) override;
|
||||
|
||||
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),
|
||||
config(std::move(config))
|
||||
{
|
||||
@@ -244,16 +244,16 @@ TeleporterTilesVector CPathfinderHelper::getAllowedTeleportChannelExits(const Te
|
||||
{
|
||||
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))
|
||||
{
|
||||
auto pos = obj->getBlockedPos();
|
||||
for(const auto & p : pos)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,7 @@ TeleporterTilesVector CPathfinderHelper::getCastleGates(const PathNodeInfo & sou
|
||||
{
|
||||
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
|
||||
&& town->hasBuilt(BuildingSubID::CASTLE_GATE))
|
||||
@@ -398,7 +398,7 @@ void CPathfinderHelper::initializePatrol()
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -425,7 +425,7 @@ bool CPathfinderHelper::canMoveBetween(const int3 & a, const int3 & b) const
|
||||
|
||||
bool CPathfinderHelper::isAllowedTeleportEntrance(const CGTeleport * obj) const
|
||||
{
|
||||
if(!obj || !isTeleportEntrancePassable(obj, hero->tempOwner))
|
||||
if(!obj || !gameState().isTeleportEntrancePassable(obj, hero->tempOwner))
|
||||
return false;
|
||||
|
||||
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
|
||||
{
|
||||
return options.useTeleportTwoWay && isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
|
||||
return options.useTeleportTwoWay && gameState().isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
|
||||
}
|
||||
|
||||
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)
|
||||
return true;
|
||||
}
|
||||
@@ -458,9 +458,9 @@ bool CPathfinderHelper::addTeleportOneWay(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)
|
||||
return true;
|
||||
}
|
||||
@@ -495,10 +495,10 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) 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),
|
||||
turn(-1),
|
||||
owner(Hero->tempOwner),
|
||||
@@ -670,7 +670,7 @@ int CPathfinderHelper::getMovementCost(
|
||||
}
|
||||
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());
|
||||
}
|
||||
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(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@ public:
|
||||
friend class CPathfinderHelper;
|
||||
|
||||
CPathfinder(
|
||||
CGameState & _gs,
|
||||
const CGameState & _gs,
|
||||
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
|
||||
|
||||
private:
|
||||
CGameState & gamestate;
|
||||
const CGameState & gamestate;
|
||||
|
||||
using ELayer = EPathfindingLayer;
|
||||
|
||||
@@ -63,12 +63,12 @@ private:
|
||||
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
|
||||
ui32 getTileMovementCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const;
|
||||
|
||||
CGameState & gs;
|
||||
const CGameState & gs;
|
||||
public:
|
||||
enum EPatrolState
|
||||
{
|
||||
@@ -87,10 +87,9 @@ public:
|
||||
bool canCastWaterWalk;
|
||||
bool whirlpoolProtection;
|
||||
|
||||
CPathfinderHelper(CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options);
|
||||
CPathfinderHelper(const CGameState & gs, const CGHeroInstance * Hero, const PathfinderOptions & Options);
|
||||
virtual ~CPathfinderHelper();
|
||||
CGameState & gameState() final { return gs; }
|
||||
const CGameState & gameState() const final { return gs; }
|
||||
const CGameState & gameState() const { return gs; }
|
||||
void initializePatrol();
|
||||
bool isHeroPatrolLocked() 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)
|
||||
pathfinderHelper = std::make_unique<CPathfinderHelper>(gs, hero, options);
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
std::vector<std::shared_ptr<IPathfindingRule>> rules);
|
||||
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
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
SingleHeroPathfinderConfig(CPathsInfo & out, const IGameInfoCallback & gs, const CGHeroInstance * hero);
|
||||
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();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user