Jelajahi Sumber

Fixed #1820, better detection of object below cursor that uses same logic as renderer

Ivan Savenko 11 tahun lalu
induk
melakukan
c956b3f02a

+ 7 - 5
client/CAdvmapInterface.cpp

@@ -1127,17 +1127,19 @@ void CAdvMapInt::endingTurn()
 	LOCPLINT->cb->endTurn();
 }
 
-const CGObjectInstance* CAdvMapInt::getBlockingObject(const int3 &mapPos)
+const CGObjectInstance* CAdvMapInt::getActiveObject(const int3 &mapPos)
 {
 	std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mapPos);  //blocking objects at tile
 
 	if (bobjs.empty())
 		return nullptr;
 
+	return *boost::range::max_element(bobjs, &CMapHandler::compareObjectBlitOrder);
+/*
 	if (bobjs.back()->ID == Obj::HERO)
 		return bobjs.back();
 	else
-		return bobjs.front();
+		return bobjs.front();*/
 }
 
 void CAdvMapInt::tileLClicked(const int3 &mapPos)
@@ -1147,7 +1149,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
 
 	const TerrainTile *tile = LOCPLINT->cb->getTile(mapPos);
 
-	const CGObjectInstance *topBlocking = getBlockingObject(mapPos);
+	const CGObjectInstance *topBlocking = getActiveObject(mapPos);
 
 	int3 selPos = selection->getSightCenter();
 	if(spellBeingCasted && isInScreenRange(selPos, mapPos))
@@ -1232,7 +1234,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
 		statusbar.clear();
 		return;
 	}
-	const CGObjectInstance *objAtTile = getBlockingObject(mapPos);
+	const CGObjectInstance *objAtTile = getActiveObject(mapPos);
 
 	if (objAtTile)
 	{
@@ -1432,7 +1434,7 @@ void CAdvMapInt::tileRClicked(const int3 &mapPos)
 		return;
 	}
 
-	const CGObjectInstance * obj = getBlockingObject(mapPos);
+	const CGObjectInstance * obj = getActiveObject(mapPos);
 	if(!obj)
 	{
 		// Bare or undiscovered terrain

+ 2 - 2
client/CAdvmapInterface.h

@@ -85,8 +85,8 @@ public:
 /// can get to the towns and heroes. 
 class CAdvMapInt : public CIntObject
 {
-	//get top selectable object at tile
-	const CGObjectInstance *getBlockingObject(const int3 &tile);
+	//Return object that must be active at this tile (=clickable)
+	const CGObjectInstance *getActiveObject(const int3 &tile);
 
 public:
 	CAdvMapInt();

+ 6 - 1
client/GUIClasses.cpp

@@ -6181,7 +6181,12 @@ void CRClickPopup::createAndPush(const CGObjectInstance *obj, const Point &p, EA
 	if(iWin)
 		GH.pushInt(iWin);
 	else
-		CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID));
+	{
+		if (adventureInt->curHero())
+			CRClickPopup::createAndPush(obj->getHoverText(adventureInt->curHero()));
+		else
+			CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID));
+	}
 }
 
 CRClickPopup::CRClickPopup()

+ 5 - 2
lib/mapObjects/CRewardableObject.cpp

@@ -308,6 +308,7 @@ bool CRewardableObject::wasVisited (PlayerColor player) const
 	switch (visitMode)
 	{
 		case VISIT_UNLIMITED:
+		case VISIT_BONUS:
 			return false;
 		case VISIT_ONCE: // FIXME: hide this info deeper and return same as player?
 			for (auto & visit : info)
@@ -329,6 +330,8 @@ bool CRewardableObject::wasVisited (const CGHeroInstance * h) const
 	switch (visitMode)
 	{
 		case VISIT_UNLIMITED:
+			return false;
+		case VISIT_BONUS:
 			return h->hasBonusFrom(Bonus::OBJECT, ID);
 		case VISIT_HERO:
 			return h->visitedObjects.count(ObjectInstanceID(id));
@@ -389,7 +392,7 @@ static std::string & visitedTxt(const bool visited)
 
 std::string CRewardableObject::getHoverText(PlayerColor player) const
 {
-	if(visitMode != VISIT_UNLIMITED)
+	if(visitMode == VISIT_PLAYER || visitMode == VISIT_ONCE)
 		return getObjectName() + " " + visitedTxt(wasVisited(player));
 	return getObjectName();
 }
@@ -611,7 +614,7 @@ void CGPickable::initObj()
 
 CGBonusingObject::CGBonusingObject()
 {
-	visitMode = VISIT_UNLIMITED;
+	visitMode = VISIT_BONUS;
 	selectMode = SELECT_FIRST;
 }
 

+ 1 - 0
lib/mapObjects/CRewardableObject.h

@@ -177,6 +177,7 @@ protected:
 		VISIT_UNLIMITED, // any number of times. Side effect - object hover text won't contain visited/not visited text
 		VISIT_ONCE,      // only once, first to visit get all the rewards
 		VISIT_HERO,      // every hero can visit object once
+		VISIT_BONUS,     // can be visited by any hero that don't have bonus from this object
 		VISIT_PLAYER     // every player can visit object once
 	};