Просмотр исходного кода

CPathfinder: handle event object properly everywhere

Also add forgoted check for AdvmapInterface to avoid possible crash.
ArseniyShestakov 10 лет назад
Родитель
Сommit
ab9680a7d9
3 измененных файлов с 27 добавлено и 8 удалено
  1. 1 1
      client/windows/CAdvmapInterface.cpp
  2. 23 7
      lib/CPathfinder.cpp
  3. 3 0
      lib/CPathfinder.h

+ 1 - 1
client/windows/CAdvmapInterface.cpp

@@ -1545,7 +1545,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
 
 		case CGPathNode::VISIT:
 		case CGPathNode::BLOCKING_VISIT:
-			if(objAtTile->ID == Obj::HERO)
+			if(objAtTile && objAtTile->ID == Obj::HERO)
 			{
 				if(selection == objAtTile)
 					CCS->curh->changeGraphic(ECursor::ADVENTURE, 2);

+ 23 - 7
lib/CPathfinder.cpp

@@ -352,13 +352,13 @@ bool CPathfinder::isMovementToDestPossible() const
 
 		if(cp->layer == ELayer::LAND)
 		{
-			if(!dtObj)
+			if(!isDestVisitableObj())
 				return false;
 
 			if(dtObj->ID != Obj::BOAT && dtObj->ID != Obj::HERO)
 				return false;
 		}
-		else if(dtObj && dtObj->ID == Obj::BOAT)
+		else if(isDestVisitableObj() && dtObj->ID == Obj::BOAT)
 		{
 			/// Hero in boat can't visit empty boats
 			return false;
@@ -441,7 +441,7 @@ CGPathNode::ENodeAction CPathfinder::getDestAction() const
 		/// don't break - next case shared for both land and sail layers
 
 	case ELayer::SAIL:
-		if(dtObj)
+		if(isDestVisitableObj())
 		{
 			auto objRel = getPlayerRelations(dtObj->tempOwner, hero->tempOwner);
 
@@ -495,8 +495,7 @@ bool CPathfinder::isSourceInitialPosition() const
 
 bool CPathfinder::isSourceVisitableObj() const
 {
-	/// Hero can't visit objects while walking on water or flying
-	return ctObj != nullptr && (cp->layer == ELayer::LAND || cp->layer == ELayer::SAIL);
+	return isVisitableObj(ctObj, cp->layer);
 }
 
 bool CPathfinder::isSourceGuarded() const
@@ -505,7 +504,7 @@ bool CPathfinder::isSourceGuarded() const
 	/// It's possible at least in these cases:
 	/// - Map start with hero on guarded tile
 	/// - Dimention door used
-	///  TODO: check what happen when there is several guards
+	/// TODO: check what happen when there is several guards
 	if(guardingCreaturePosition(cp->coord) != int3(-1, -1, -1) && !isSourceInitialPosition())
 	{
 		return true;
@@ -514,6 +513,11 @@ bool CPathfinder::isSourceGuarded() const
 	return false;
 }
 
+bool CPathfinder::isDestVisitableObj() const
+{
+	return isVisitableObj(dtObj, dp->layer);
+}
+
 bool CPathfinder::isDestinationGuarded(const bool ignoreAccessibility) const
 {
 	/// isDestinationGuarded is exception needed for garrisons.
@@ -600,7 +604,7 @@ CGPathNode::EAccessibility CPathfinder::evaluateAccessibility(const int3 & pos,
 					{
 						return CGPathNode::BLOCKVIS;
 					}
-					else if(obj->ID != Obj::EVENT) //pathfinder should ignore placed events
+					else if(canSeeObj(obj))
 					{
 						return CGPathNode::VISITABLE;
 					}
@@ -633,6 +637,18 @@ CGPathNode::EAccessibility CPathfinder::evaluateAccessibility(const int3 & pos,
 	return CGPathNode::ACCESSIBLE;
 }
 
+bool CPathfinder::isVisitableObj(const CGObjectInstance * obj, const ELayer layer) const
+{
+	/// Hero can't visit objects while walking on water or flying
+	return canSeeObj(obj) && (layer == ELayer::LAND || layer == ELayer::SAIL);
+}
+
+bool CPathfinder::canSeeObj(const CGObjectInstance * obj) const
+{
+	/// Pathfinder should ignore placed events
+	return obj != nullptr && obj->ID != Obj::EVENT;
+}
+
 bool CPathfinder::canMoveBetween(const int3 & a, const int3 & b) const
 {
 	return gs->checkForVisitableDir(a, b);

+ 3 - 0
lib/CPathfinder.h

@@ -188,12 +188,15 @@ private:
 	bool isSourceInitialPosition() const;
 	bool isSourceVisitableObj() const;
 	bool isSourceGuarded() const;
+	bool isDestVisitableObj() const;
 	bool isDestinationGuarded(const bool ignoreAccessibility = true) const;
 	bool isDestinationGuardian() const;
 
 	void initializeGraph();
 
 	CGPathNode::EAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile * tinfo, const ELayer layer) const;
+	bool isVisitableObj(const CGObjectInstance * obj, const ELayer layer) const;
+	bool canSeeObj(const CGObjectInstance * obj) 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;