浏览代码

Added option to ignore guards in pathfinder

Used for simturns contact detection, by default disabled for player
pathfinding
Ivan Savenko 1 年之前
父节点
当前提交
8303ce5d13

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

@@ -41,6 +41,7 @@ namespace AIPathfinding
 		std::shared_ptr<AINodeStorage> nodeStorage)
 		:PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage)), hero(nodeStorage->getHero())
 	{
+		options.ignoreGuards = false;
 		options.useEmbarkAndDisembark = true;
 		options.useTeleportTwoWay = true;
 		options.useTeleportOneWay = true;

+ 2 - 0
config/gameConfig.json

@@ -371,6 +371,8 @@
 		
 		"pathfinder" :
 		{
+			// if enabled, pathfinder will build path through locations guarded by wandering monsters
+			"ignoreGuards" : false,
 			// if enabled, pathfinder will take use of any available boats
 			"useBoat" : true,
 			// if enabled, pathfinder will take use of any bidirectional monoliths 

+ 1 - 0
lib/GameSettings.cpp

@@ -95,6 +95,7 @@ void GameSettings::load(const JsonNode & input)
 		{EGameSettings::TEXTS_ROAD,                             "textData",  "road"                       },
 		{EGameSettings::TEXTS_SPELL,                            "textData",  "spell"                      },
 		{EGameSettings::TEXTS_TERRAIN,                          "textData",  "terrain"                    },
+		{EGameSettings::PATHFINDER_IGNORE_GUARDS,               "pathfinder", "ignoreGuards"              },
 		{EGameSettings::PATHFINDER_USE_BOAT,                    "pathfinder", "useBoat"                   },
 		{EGameSettings::PATHFINDER_USE_MONOLITH_TWO_WAY,        "pathfinder", "useMonolithTwoWay"         },
 		{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE, "pathfinder", "useMonolithOneWayUnique"   },

+ 1 - 0
lib/GameSettings.h

@@ -60,6 +60,7 @@ enum class EGameSettings
 	MAP_FORMAT_JSON_VCMI,
 	MAP_FORMAT_IN_THE_WAKE_OF_GODS,
 	PATHFINDER_USE_BOAT,
+	PATHFINDER_IGNORE_GUARDS,
 	PATHFINDER_USE_MONOLITH_TWO_WAY,
 	PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE,
 	PATHFINDER_USE_MONOLITH_ONE_WAY_RANDOM,

+ 1 - 0
lib/pathfinder/PathfinderOptions.cpp

@@ -21,6 +21,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 PathfinderOptions::PathfinderOptions()
 	: useFlying(true)
 	, useWaterWalking(true)
+	, ignoreGuards(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_IGNORE_GUARDS))
 	, useEmbarkAndDisembark(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_USE_BOAT))
 	, useTeleportTwoWay(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_USE_MONOLITH_TWO_WAY))
 	, useTeleportOneWay(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE))

+ 1 - 0
lib/pathfinder/PathfinderOptions.h

@@ -25,6 +25,7 @@ struct DLL_LINKAGE PathfinderOptions
 	bool useFlying;
 	bool useWaterWalking;
 	bool useEmbarkAndDisembark;
+	bool ignoreGuards;
 	bool useTeleportTwoWay; // Two-way monoliths and Subterranean Gate
 	bool useTeleportOneWay; // One-way monoliths with one known exit only
 	bool useTeleportOneWayRandom; // One-way monoliths with more than one known exit

+ 7 - 1
lib/pathfinder/PathfindingRules.cpp

@@ -271,7 +271,12 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking
 	case EPathNodeAction::BATTLE:
 		/// Movement after BATTLE action only possible from guarded tile to guardian tile
 		if(destination.guarded)
-			return BlockingReason::DESTINATION_GUARDED;
+		{
+			if (pathfinderHelper->options.ignoreGuards)
+				return BlockingReason::DESTINATION_GUARDED;
+			else
+				return BlockingReason::NONE;
+		}
 
 		break;
 	}
@@ -299,6 +304,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
 		if(source.guarded)
 		{
 			if(!(pathfinderConfig->options.originalMovementRules && source.node->layer == EPathfindingLayer::AIR) 
+				&& !pathfinderConfig->options.ignoreGuards
 				&&	(!destination.isGuardianTile || pathfinderHelper->getGuardiansCount(source.coord) > 1)) // Can step into tile of guard
 			{
 				return BlockingReason::SOURCE_GUARDED;

+ 2 - 0
server/processors/TurnOrderProcessor.cpp

@@ -106,6 +106,7 @@ bool TurnOrderProcessor::playersInContact(PlayerColor left, PlayerColor right) c
 	{
 		CPathsInfo out(mapSize, hero);
 		auto config = std::make_shared<SingleHeroPathfinderConfig>(out, gameHandler->gameState(), hero);
+		config->options.ignoreGuards = true;
 		CPathfinder pathfinder(gameHandler->gameState(), config);
 		pathfinder.calculatePaths();
 
@@ -120,6 +121,7 @@ bool TurnOrderProcessor::playersInContact(PlayerColor left, PlayerColor right) c
 	{
 		CPathsInfo out(mapSize, hero);
 		auto config = std::make_shared<SingleHeroPathfinderConfig>(out, gameHandler->gameState(), hero);
+		config->options.ignoreGuards = true;
 		CPathfinder pathfinder(gameHandler->gameState(), config);
 		pathfinder.calculatePaths();