diff --git a/AI/VCAI/Pathfinding/AIPathfinderConfig.cpp b/AI/VCAI/Pathfinding/AIPathfinderConfig.cpp index 68e516e1a..dc067db74 100644 --- a/AI/VCAI/Pathfinding/AIPathfinderConfig.cpp +++ b/AI/VCAI/Pathfinding/AIPathfinderConfig.cpp @@ -41,6 +41,7 @@ namespace AIPathfinding std::shared_ptr nodeStorage) :PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage)), hero(nodeStorage->getHero()) { + options.ignoreGuards = false; options.useEmbarkAndDisembark = true; options.useTeleportTwoWay = true; options.useTeleportOneWay = true; diff --git a/config/gameConfig.json b/config/gameConfig.json index 5b6e17b5c..56260f4e2 100644 --- a/config/gameConfig.json +++ b/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 diff --git a/lib/GameSettings.cpp b/lib/GameSettings.cpp index 6df29e210..e3ef38929 100644 --- a/lib/GameSettings.cpp +++ b/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" }, diff --git a/lib/GameSettings.h b/lib/GameSettings.h index 750c9abab..7241e9b92 100644 --- a/lib/GameSettings.h +++ b/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, diff --git a/lib/pathfinder/PathfinderOptions.cpp b/lib/pathfinder/PathfinderOptions.cpp index 4c83acafc..5b0ca709a 100644 --- a/lib/pathfinder/PathfinderOptions.cpp +++ b/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)) diff --git a/lib/pathfinder/PathfinderOptions.h b/lib/pathfinder/PathfinderOptions.h index 96d75cb2a..973135e30 100644 --- a/lib/pathfinder/PathfinderOptions.h +++ b/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 diff --git a/lib/pathfinder/PathfindingRules.cpp b/lib/pathfinder/PathfindingRules.cpp index d041aff85..49de31ff7 100644 --- a/lib/pathfinder/PathfindingRules.cpp +++ b/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; diff --git a/server/processors/TurnOrderProcessor.cpp b/server/processors/TurnOrderProcessor.cpp index f0b0fda8d..1743bb3be 100644 --- a/server/processors/TurnOrderProcessor.cpp +++ b/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(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(out, gameHandler->gameState(), hero); + config->options.ignoreGuards = true; CPathfinder pathfinder(gameHandler->gameState(), config); pathfinder.calculatePaths();