diff --git a/lib/CPathfinder.cpp b/lib/CPathfinder.cpp index 427f12dfd..732261152 100644 --- a/lib/CPathfinder.cpp +++ b/lib/CPathfinder.cpp @@ -28,6 +28,8 @@ CPathfinder::PathfinderOptions::PathfinderOptions() useTeleportOneWayRandom = false; useTeleportWhirlpool = false; + useCastleGate = false; + lightweightFlyingMode = false; oneTurnSpecialLayersLimit = true; } @@ -253,6 +255,23 @@ void CPathfinder::addTeleportExits(bool noTeleportExcludes) neighbours.push_back(obj->visitablePos()); } } + + if(options.useCastleGate + && (sTileObj->ID == Obj::TOWN && sTileObj->subID == ETownType::INFERNO + && getPlayerRelations(hero->tempOwner, sTileObj->tempOwner) != PlayerRelations::ENEMIES)) + { + /// TODO: Find way to reuse CPlayerSpecificInfoCallback::getTownsInfo + /// This may be handy if we allow to use teleportation to friendly towns + auto towns = gs->getPlayer(hero->tempOwner)->towns; + for(const auto & town : towns) + { + if(town->id != sTileObj->id && town->visitingHero == nullptr + && town->hasBuilt(BuildingID::CASTLE_GATE, ETownType::INFERNO)) + { + neighbours.push_back(town->visitablePos()); + } + } + } } bool CPathfinder::isLayerTransitionPossible() const @@ -364,7 +383,7 @@ bool CPathfinder::isMovementToDestPossible() } else if(isDestinationGuardian()) destAction = CGPathNode::BATTLE; - else if(obj->blockVisit) + else if(obj->blockVisit && (!options.useCastleGate || obj->ID != Obj::TOWN)) destAction = CGPathNode::BLOCKING_VISIT; diff --git a/lib/CPathfinder.h b/lib/CPathfinder.h index e3946a6d9..e6c346dee 100644 --- a/lib/CPathfinder.h +++ b/lib/CPathfinder.h @@ -106,6 +106,11 @@ private: bool useTeleportOneWayRandom; // One-way monoliths with more than one known exit bool useTeleportWhirlpool; // Force enabled if hero protected or unaffected (have one stack of one creature) + /// TODO: Find out with client and server code, merge with normal teleporters. + /// Likely proper implementation would require some refactoring of CGTeleport. + /// So for now this is unfinished and disabled by default. + bool useCastleGate; + /// If true transition into air layer only possible from initial node. /// This is drastically decrease path calculation complexity (and time). /// Downside is less MP effective paths calculation.