浏览代码

Pathfinder now uses CGameState directly instead of inheriting callback

Ivan Savenko 5 月之前
父节点
当前提交
fe2f5f9217

+ 1 - 1
AI/Nullkiller/Pathfinding/AIPathfinderConfig.cpp

@@ -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];

+ 1 - 1
AI/Nullkiller/Pathfinding/AIPathfinderConfig.h

@@ -35,7 +35,7 @@ namespace AIPathfinding
 
 		~AIPathfinderConfig();
 
-		CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs) override;
+		CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs) override;
 	};
 }
 

+ 1 - 1
AI/VCAI/Pathfinding/AIPathfinderConfig.cpp

@@ -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)
 		{

+ 1 - 1
AI/VCAI/Pathfinding/AIPathfinderConfig.h

@@ -30,6 +30,6 @@ namespace AIPathfinding
 
 		~AIPathfinderConfig();
 
-		CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState & gs) override;
+		CPathfinderHelper * getOrCreatePathfinderHelper(const PathNodeInfo & source, const CGameState & gs) override;
 	};
 }

+ 1 - 1
lib/gameState/CGameState.cpp

@@ -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();
 }
 

+ 3 - 3
lib/pathfinder/CGPathNode.cpp

@@ -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);
 

+ 3 - 3
lib/pathfinder/CGPathNode.h

@@ -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;
 };

+ 16 - 16
lib/pathfinder/CPathfinder.cpp

@@ -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);
 	}
 

+ 6 - 7
lib/pathfinder/CPathfinder.h

@@ -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;

+ 1 - 1
lib/pathfinder/PathfinderOptions.cpp

@@ -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);

+ 2 - 2
lib/pathfinder/PathfinderOptions.h

@@ -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();
 };