Explorar el Código

CPathfinder: update teleport code and use TurnInfo for whirlpools

ArseniyShestakov hace 10 años
padre
commit
8f72d73241
Se han modificado 2 ficheros con 29 adiciones y 30 borrados
  1. 27 29
      lib/CPathfinder.cpp
  2. 2 1
      lib/CPathfinder.h

+ 27 - 29
lib/CPathfinder.cpp

@@ -203,36 +203,16 @@ void CPathfinder::addNeighbours(const int3 & coord)
 		vstd::concatenate(neighbours, tiles);
 }
 
-void CPathfinder::addTeleportExits(bool noTeleportExcludes)
+void CPathfinder::addTeleportExits()
 {
 	neighbours.clear();
 	if(!isSourceVisitableObj())
 		return;
 
-	auto isAllowedTeleportEntrance = [&](const CGTeleport * obj) -> bool
+	const CGTeleport * objTeleport = dynamic_cast<const CGTeleport *>(ctObj);
+	if(isAllowedTeleportEntrance(objTeleport))
 	{
-		if(!gs->isTeleportEntrancePassable(obj, hero->tempOwner))
-			return false;
-
-		if(noTeleportExcludes)
-			return true;
-
-		auto whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
-		if(whirlpool)
-		{
-			if(addTeleportWhirlpool(whirlpool))
-				return true;
-		}
-		else if(addTeleportTwoWay(obj) || addTeleportOneWay(obj) || addTeleportOneWayRandom(obj))
-			return true;
-
-		return false;
-	};
-
-	const CGTeleport * sTileTeleport = dynamic_cast<const CGTeleport *>(ctObj);
-	if(isAllowedTeleportEntrance(sTileTeleport))
-	{
-		for(auto objId : gs->getTeleportChannelExits(sTileTeleport->channel, hero->tempOwner))
+		for(auto objId : gs->getTeleportChannelExits(objTeleport->channel, hero->tempOwner))
 		{
 			auto obj = getObj(objId);
 			if(dynamic_cast<const CGWhirlpool *>(obj))
@@ -401,18 +381,19 @@ bool CPathfinder::isMovementAfterDestPossible() const
 	/// TODO: Investigate what kind of limitation is possible to apply on movement from visitable tiles
 	/// Likely in many cases we don't need to add visitable tile to queue when hero don't fly
 	case CGPathNode::VISIT:
+	{
 		/// For now we only add visitable tile into queue when it's teleporter that allow transit
 		/// Movement from visitable tile when hero is standing on it is possible into any layer
-		if(CGTeleport::isTeleport(dtObj))
+		const CGTeleport * objTeleport = dynamic_cast<const CGTeleport *>(dtObj);
+		if(isAllowedTeleportEntrance(objTeleport))
 		{
 			/// For now we'll always allow transit over teleporters
 			/// Transit over whirlpools only allowed when hero protected
-			auto whirlpool = dynamic_cast<const CGWhirlpool *>(dtObj);
-			if(!whirlpool || options.useTeleportWhirlpool)
-				return true;
+			return true;
 		}
 
 		break;
+	}
 
 	case CGPathNode::NORMAL:
 		return true;
@@ -635,6 +616,23 @@ bool CPathfinder::canMoveBetween(const int3 & a, const int3 & b) const
 	return gs->checkForVisitableDir(a, b);
 }
 
+bool CPathfinder::isAllowedTeleportEntrance(const CGTeleport * obj) const
+{
+	if(!obj || !gs->isTeleportEntrancePassable(obj, hero->tempOwner))
+		return false;
+
+	auto whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
+	if(whirlpool)
+	{
+		if(addTeleportWhirlpool(whirlpool))
+			return true;
+	}
+	else if(addTeleportTwoWay(obj) || addTeleportOneWay(obj) || addTeleportOneWayRandom(obj))
+		return true;
+
+	return false;
+}
+
 bool CPathfinder::addTeleportTwoWay(const CGTeleport * obj) const
 {
 	return options.useTeleportTwoWay && gs->isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
@@ -664,7 +662,7 @@ bool CPathfinder::addTeleportOneWayRandom(const CGTeleport * obj) const
 
 bool CPathfinder::addTeleportWhirlpool(const CGWhirlpool * obj) const
 {
-	return options.useTeleportWhirlpool && obj;
+	return options.useTeleportWhirlpool && hlp->hasBonusOfType(Bonus::WHIRLPOOL_PROTECTION) && obj;
 }
 
 TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn)

+ 2 - 1
lib/CPathfinder.h

@@ -166,7 +166,7 @@ private:
 	CGPathNode::ENodeAction destAction;
 
 	void addNeighbours(const int3 & coord);
-	void addTeleportExits(bool noTeleportExcludes = false);
+	void addTeleportExits();
 
 	bool isLayerTransitionPossible() const;
 	bool isMovementToDestPossible() const;
@@ -184,6 +184,7 @@ private:
 	CGPathNode::EAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile * tinfo) const;
 	bool canMoveBetween(const int3 & a, const int3 & b) const; //checks only for visitable objects that may make moving between tiles impossible, not other conditions (like tiles itself accessibility)
 
+	bool isAllowedTeleportEntrance(const CGTeleport * obj) const;
 	bool addTeleportTwoWay(const CGTeleport * obj) const;
 	bool addTeleportOneWay(const CGTeleport * obj) const;
 	bool addTeleportOneWayRandom(const CGTeleport * obj) const;