Bladeren bron

Refactoring of hoverText from objects:

- removed hoverText field
- split getHoverText() method into 3:
- - getObjectName() for generic name
- - getHoverText(Player) for player-specific text
- - getHoverText(Hero) for hero-specific strings
Ivan Savenko 11 jaren geleden
bovenliggende
commit
a0689fa377

+ 3 - 3
AI/VCAI/Goals.cpp

@@ -66,7 +66,7 @@ std::string Goals::AbstractGoal::name() const //TODO: virtualize
 		{
 			auto obj = cb->getObjInstance(ObjectInstanceID(objid));
 			if (obj)
-				desc = "GET OBJ " + obj->getHoverText();
+				desc = "GET OBJ " + obj->getObjectName();
 		}
 		case FIND_OBJ:
 			desc = "FIND OBJ " + boost::lexical_cast<std::string>(objid);
@@ -75,7 +75,7 @@ std::string Goals::AbstractGoal::name() const //TODO: virtualize
 		{
 			auto obj = cb->getObjInstance(ObjectInstanceID(objid));
 			if (obj)
-				desc = "VISIT HERO " + obj->getHoverText();
+				desc = "VISIT HERO " + obj->getObjectName();
 		}
 			break;
 		case GET_ART_TYPE:
@@ -493,7 +493,7 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
 
 			if (topObj->ID == Obj::HERO && cb->getPlayerRelations(h->tempOwner, topObj->tempOwner) != PlayerRelations::ENEMIES)
 				if (topObj != hero.get(true)) //the hero we want to free
-					logAi->errorStream() << boost::format("%s stands in the way of %s") % topObj->getHoverText()  % h->getHoverText();
+					logAi->errorStream() << boost::format("%s stands in the way of %s") % topObj->getObjectName()  % h->getObjectName();
 			if (topObj->ID == Obj::QUEST_GUARD || topObj->ID == Obj::BORDERGUARD)
 			{
 				if (shouldVisit(h, topObj))

+ 6 - 6
AI/VCAI/VCAI.cpp

@@ -81,7 +81,7 @@ struct ObjInfo
 	ObjInfo(){}
 	ObjInfo(const CGObjectInstance *obj):
 		pos(obj->pos),
-		name(obj->getHoverText())
+		name(obj->getObjectName())
 	{
 	}
 };
@@ -241,7 +241,7 @@ void VCAI::artifactDisassembled(const ArtifactLocation &al)
 
 void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visitedObj, bool start)
 {
-	LOG_TRACE_PARAMS(logAi, "start '%i'; obj '%s'", start % (visitedObj ? visitedObj->hoverName : std::string("n/a")));
+	LOG_TRACE_PARAMS(logAi, "start '%i'; obj '%s'", start % (visitedObj ? visitedObj->getObjectName() : std::string("n/a")));
 	NET_EVENT_HANDLER;
 	if(start)
 	{
@@ -780,13 +780,13 @@ void VCAI::makeTurnInternal()
 bool VCAI::goVisitObj(const CGObjectInstance * obj, HeroPtr h)
 {
 	int3 dst = obj->visitablePos();
-    logAi->debugStream() << boost::format("%s will try to visit %s at (%s)") % h->name % obj->getHoverText() % strFromInt3(dst);
+	logAi->debugStream() << boost::format("%s will try to visit %s at (%s)") % h->name % obj->getObjectName() % strFromInt3(dst);
 	return moveHeroToTile(dst, h);
 }
 
 void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
 {
-	LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getHoverText() % obj->pos);
+	LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getObjectName() % obj->pos);
 	switch (obj->ID)
 	{
 		case Obj::CREATURE_GENERATOR1:
@@ -1434,7 +1434,7 @@ void VCAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int
 	assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
 	status.setBattle(ONGOING_BATTLE);
 	const CGObjectInstance *presumedEnemy = backOrNull(cb->getVisitableObjs(tile)); //may be nullptr in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit
-	battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->hoverName : "unknown enemy") % tile);
+	battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile);
 	CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side);
 }
 
@@ -1468,7 +1468,7 @@ void VCAI::reserveObject(HeroPtr h, const CGObjectInstance *obj)
 {
 	reservedObjs.insert(obj);
 	reservedHeroesMap[h].insert(obj);
-	logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText();
+	logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (intptr_t)obj << "; name=" << obj->getObjectName();
 }
 
 void VCAI::unreserveObject(HeroPtr h, const CGObjectInstance *obj)

+ 1 - 1
client/AdventureMapClasses.cpp

@@ -317,7 +317,7 @@ void CTownList::CTownItem::showTooltip()
 
 std::string CTownList::CTownItem::getHoverText()
 {
-	return town->hoverName;
+	return town->getObjectName();
 }
 
 CTownList::CTownList(int size, Point position, std::string btnUp, std::string btnDown):

+ 1 - 2
client/CAdvmapInterface.cpp

@@ -1234,10 +1234,9 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
 	}
 	const CGObjectInstance *objAtTile = getBlockingObject(mapPos);
 
-	//std::vector<std::string> temp = LOCPLINT->cb->getObjDescriptions(mapPos);
 	if (objAtTile)
 	{
-		std::string text = objAtTile->getHoverText();
+		std::string text = curHero() ? objAtTile->getHoverText(curHero()) : objAtTile->getHoverText(LOCPLINT->playerID);
 		boost::replace_all(text,"\n"," ");
 		statusbar.setText(text);
 	}

+ 2 - 2
client/CKingdomInterface.cpp

@@ -500,7 +500,7 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst
 			OwnedObjectInfo &info = visibleObjects[object->subID];
 			if (info.count++ == 0)
 			{
-				info.hoverText = object->getHoverText();
+				info.hoverText = object->getObjectName();
 				info.imageID = object->subID;
 			}
 		}
@@ -511,7 +511,7 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst
 			OwnedObjectInfo &info = visibleObjects[iter->second];
 			if (info.count++ == 0)
 			{
-				info.hoverText = object->hoverName;
+				info.hoverText = object->getObjectName();
 				info.imageID = iter->second;
 			}
 		}

+ 1 - 1
client/CMT.cpp

@@ -589,7 +589,7 @@ void processCommand(const std::string &message)
 	}
 	else if(cn == "bonuses")
 	{
-        std::cout << "Bonuses of " << adventureInt->selection->getHoverText() << std::endl
+		std::cout << "Bonuses of " << adventureInt->selection->getObjectName() << std::endl
 			<< adventureInt->selection->getBonusList() << std::endl;
 
         std::cout << "\nInherited bonuses:\n";

+ 1 - 1
client/CQuestLog.cpp

@@ -140,7 +140,7 @@ void CQuestLog::init()
 		MetaString text;
 		quests[i].quest->getRolloverText (text, false);
 		if (quests[i].obj)
-			text.addReplacement (quests[i].obj->getHoverText()); //get name of the object
+			text.addReplacement (quests[i].obj->getObjectName()); //get name of the object
 		CQuestLabel * label = new CQuestLabel (Rect(28, 199 + i * 24, 172,30), FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
 		label->callback = boost::bind(&CQuestLog::selectQuest, this, i);
 		labels.push_back(label);

+ 0 - 1
client/Client.h

@@ -170,7 +170,6 @@ public:
 	bool removeObject(const CGObjectInstance * obj) override {return false;};
 	void setBlockVis(ObjectInstanceID objid, bool bv) override {};
 	void setOwner(const CGObjectInstance * obj, PlayerColor owner) override {};
-	void setHoverName(const CGObjectInstance * obj, MetaString * name) override {};
 	void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false) override {};
 	void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) override {}; 
 

+ 5 - 5
client/GUIClasses.cpp

@@ -1848,7 +1848,7 @@ CObjectListWindow::CObjectListWindow(const std::vector<int> &_items, CIntObject
 	items.reserve(_items.size());
 	for(int id : _items)
 	{
-		items.push_back(std::make_pair(id, CGI->mh->map->objects[id]->hoverName));
+		items.push_back(std::make_pair(id, CGI->mh->map->objects[id]->getObjectName()));
 	}
 
 	init(titlePic, _title, _descr);
@@ -2614,7 +2614,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
 		break; case Obj::BLACK_MARKET:   title = CGI->generaltexth->allTexts[349];
 		break; case Obj::TRADING_POST:  title = CGI->generaltexth->allTexts[159];
 		break; case Obj::TRADING_POST_SNOW: title = CGI->generaltexth->allTexts[159];
-		break; default:  title = market->o->getHoverText();
+		break; default:  title = market->o->getObjectName();
 		}
 	}
 
@@ -4571,7 +4571,7 @@ void CHeroArea::clickRight(tribool down, bool previousState)
 void CHeroArea::hover(bool on)
 {
 	if (on && hero)
-		GH.statusbar->setText(hero->hoverName);
+		GH.statusbar->setText(hero->getObjectName());
 	else
 		GH.statusbar->clear();
 }
@@ -5634,7 +5634,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn
 	slotsCount=7;
 	resources =  CDefHandler::giveDefEss("SMALRES.DEF");
 
-	new CLabel(325, 32, FONT_BIG, CENTER, Colors::YELLOW, fort->hoverName);//Hill Fort
+	new CLabel(325, 32, FONT_BIG, CENTER, Colors::YELLOW, fort->getObjectName());//Hill Fort
 
 	heroPic = new CHeroArea(30, 60, hero);
 
@@ -6181,7 +6181,7 @@ void CRClickPopup::createAndPush(const CGObjectInstance *obj, const Point &p, EA
 	if(iWin)
 		GH.pushInt(iWin);
 	else
-		CRClickPopup::createAndPush(obj->getHoverText());
+		CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID));
 }
 
 CRClickPopup::CRClickPopup()

+ 1 - 1
client/mapHandler.cpp

@@ -1054,7 +1054,7 @@ void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terN
 	{
 		if(elem.first->ID == Obj::HOLE) //Hole
 		{
-			out = elem.first->hoverName;
+			out = elem.first->getObjectName();
 			return;
 		}
 	}

+ 0 - 1
client/mapHandler.h

@@ -108,7 +108,6 @@ public:
 	std::pair<SDL_Surface *, bool> getVisBitmap(const int3 & pos, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap) const; //returns appropriate bitmap and info if alpha blitting is necessary
 	ui8 getPhaseShift(const CGObjectInstance *object) const;
 
-	std::vector< std::string > getObjDescriptions(int3 pos); //returns desriptions of objects blocking given position
 	void getTerrainDescr(const int3 &pos, std::string & out, bool terName); //if tername == false => empty string when tile is clear
 	CGObjectInstance * createObject(int id, int subid, int3 pos, int owner=254); //creates a new object with a certain id and subid
 	bool printObject(const CGObjectInstance * obj); //puts appropriate things to ttiles, so obj will be visible on map

+ 1 - 0
lib/CCreatureSet.cpp

@@ -224,6 +224,7 @@ ui64 CCreatureSet::getPower (SlotID slot) const
 {
 	return getStack(slot).getPower();
 }
+
 std::string CCreatureSet::getRoughAmount (SlotID slot) const
 {
 	int quantity = CCreature::getQuantityID(getStackCount(slot));

+ 0 - 12
lib/CGameInfoCallback.cpp

@@ -260,18 +260,6 @@ int CGameInfoCallback::getDate(Date::EDateType mode) const
 	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	return gs->getDate(mode);
 }
-std::vector < std::string > CGameInfoCallback::getObjDescriptions(int3 pos) const
-{
-	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
-	std::vector<std::string> ret;
-	const TerrainTile *t = getTile(pos);
-	ERROR_RET_VAL_IF(!t, "Not a valid tile given!", ret);
-
-
-	for(const CGObjectInstance * obj : t->blockingObjects)
-		ret.push_back(obj->getHoverText());
-	return ret;
-}
 
 bool CGameInfoCallback::isVisible(int3 pos, boost::optional<PlayerColor> Player) const
 {

+ 0 - 1
lib/CGameInfoCallback.h

@@ -83,7 +83,6 @@ public:
 	std::vector <const CGObjectInstance * > getVisitableObjs(int3 pos, bool verbose = true)const;
 	std::vector <const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
 	const CGObjectInstance * getTopObj (int3 pos) const;
-	std::vector <std::string > getObjDescriptions(int3 pos)const; //returns descriptions of objects at pos in order from the lowest to the highest
 	PlayerColor getOwner(ObjectInstanceID heroID) const;
 	const CGObjectInstance *getObjByQuestIdentifier(int identifier) const; //nullptr if object has been removed (eg. killed)
 

+ 1 - 2
lib/CGameState.cpp

@@ -1053,7 +1053,6 @@ void CGameState::randomizeMapObjects()
 		if(!obj) continue;
 
 		randomizeObject(obj);
-		obj->hoverName = VLC->objtypeh->getObjectName(obj->ID);
 
 		//handle Favouring Winds - mark tiles under it
 		if(obj->ID == Obj::FAVORABLE_WINDS)
@@ -2980,7 +2979,7 @@ void InfoAboutArmy::initFromArmy(const CArmedInstance *Army, bool detailed)
 {
 	army = ArmyDescriptor(Army, detailed);
 	owner = Army->tempOwner;
-	name = Army->getHoverText();
+	name = Army->getObjectName();
 }
 
 void InfoAboutHero::assign(const InfoAboutHero & iah)

+ 0 - 1
lib/IGameCallback.h

@@ -48,7 +48,6 @@ public:
 	virtual bool removeObject(const CGObjectInstance * obj)=0;
 	virtual void setBlockVis(ObjectInstanceID objid, bool bv)=0;
 	virtual void setOwner(const CGObjectInstance * objid, PlayerColor owner)=0;
-	virtual void setHoverName(const CGObjectInstance * obj, MetaString * name)=0;
 	virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false)=0;
 	virtual void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false)=0; 
 	virtual void showBlockingDialog(BlockingDialog *iw) =0;

+ 0 - 15
lib/NetPacks.h

@@ -1045,21 +1045,6 @@ struct SetObjectProperty : public CPackForClient//1001
 	}
 };
 
-struct SetHoverName : public CPackForClient//1002
-{
-	DLL_LINKAGE void applyGs(CGameState *gs);
-
-	ObjectInstanceID id;
-	MetaString name;
-	SetHoverName(){type = 1002;}
-	SetHoverName(ObjectInstanceID ID, MetaString& Name):id(ID),name(Name){type = 1002;}
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & id & name;
-	}
-};
-
 struct ChangeObjectVisitors : public CPackForClient // 1003
 {
 	enum VisitMode

+ 2 - 8
lib/NetPacksLib.cpp

@@ -302,7 +302,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
 {
 
 	CGObjectInstance *obj = gs->getObjInstance(id);
-	logGlobal->debugStream() << "removing object id=" << id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText();
+	logGlobal->debugStream() << "removing object id=" << id << "; address=" << (intptr_t)obj << "; name=" << obj->getObjectName();
 	//unblock tiles
 	gs->map->removeBlockVisTiles(obj);
 
@@ -608,14 +608,13 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs )
 	const TerrainTile &t = gs->map->getTile(pos);
 	o->appearance = VLC->objtypeh->getHandlerFor(o->ID, o->subID)->getTemplates(t.terType).front();
 	id = o->id = ObjectInstanceID(gs->map->objects.size());
-	o->hoverName = VLC->objtypeh->getObjectName(ID);
 
 	gs->map->objects.push_back(o);
 	gs->map->addBlockVisTiles(o);
 	o->initObj();
 	gs->map->calculateGuardingGreaturePositions();
 
-	logGlobal->debugStream() << "added object id=" << id << "; address=" << (intptr_t)o << "; name=" << o->getHoverText();
+	logGlobal->debugStream() << "added object id=" << id << "; address=" << (intptr_t)o << "; name=" << o->getObjectName();
 }
 
 DLL_LINKAGE void NewArtifact::applyGs( CGameState *gs )
@@ -1012,11 +1011,6 @@ DLL_LINKAGE void SetObjectProperty::applyGs( CGameState *gs )
 	}
 }
 
-DLL_LINKAGE void SetHoverName::applyGs( CGameState *gs )
-{
-	name.toString(gs->getObj(id)->hoverName);
-}
-
 DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs )
 {
 	CGHeroInstance * h = gs->getHero(hero->id);

+ 4 - 3
lib/mapObjects/CBank.cpp

@@ -41,11 +41,12 @@ void CBank::initObj()
 	VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, cb->gameState()->getRandomGenerator());
 }
 
-const std::string & CBank::getHoverText() const
+std::string CBank::getHoverText(PlayerColor player) const
 {
+	// TODO: USE BANK_SPECIFIC NAMES
+	// TODO: record visited players
 	bool visited = (bc == nullptr);
-	hoverName = visitedTxt(visited); // FIXME: USE BANK_SPECIFIC NAMES
-	return hoverName;
+	return visitedTxt(visited);
 }
 
 void CBank::setConfig(const BankConfig & config)

+ 1 - 1
lib/mapObjects/CBank.h

@@ -32,7 +32,7 @@ public:
 	void setConfig(const BankConfig & bc);
 
 	void initObj() override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
 	void newTurn() const override;
 	bool wasVisited (PlayerColor player) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;

+ 3 - 5
lib/mapObjects/CGHeroInstance.cpp

@@ -418,19 +418,17 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
 	}
 }
 
-const std::string & CGHeroInstance::getHoverText() const
+std::string CGHeroInstance::getObjectName() const
 {
 	if(ID != Obj::PRISON)
 	{
-		hoverName = VLC->generaltexth->allTexts[15];
+		std::string hoverName = VLC->generaltexth->allTexts[15];
 		boost::algorithm::replace_first(hoverName,"%s",name);
 		boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name);
 		return hoverName;
 	}
 	else
-		hoverName = VLC->objtypeh->getObjectName(ID);
-
-	return hoverName;
+		return CGObjectInstance::getObjectName();
 }
 
 const std::string & CGHeroInstance::getBiography() const

+ 1 - 1
lib/mapObjects/CGHeroInstance.h

@@ -205,7 +205,7 @@ public:
 
 	void initObj() override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	const std::string & getHoverText() const override;
+	std::string getObjectName() const override;
 protected:
 	void setPropertyDer(ui8 what, ui32 val) override;//synchr
 

+ 7 - 3
lib/mapObjects/CGTownInstance.cpp

@@ -55,7 +55,7 @@ void CGDwelling::initObj()
 	}
 }
 
-void CGDwelling::setProperty(ui8 what, ui32 val)
+void CGDwelling::setPropertyDer(ui8 what, ui32 val)
 {
 	switch (what)
 	{
@@ -77,8 +77,8 @@ void CGDwelling::setProperty(ui8 what, ui32 val)
 			creatures[0].second[0] = CreatureID(val);
 			break;
 	}
-	CGObjectInstance::setProperty(what,val);
 }
+
 void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(ID == Obj::REFUGEE_CAMP && !creatures[0].first) //Refugee Camp, no available cres
@@ -523,11 +523,15 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
 	cb->stopHeroVisitCastle(this, h);
 }
 
+std::string CGTownInstance::getObjectName() const
+{
+	return name + ", " + town->faction->name;
+}
+
 void CGTownInstance::initObj()
 ///initialize town structures
 {
 	blockVisit = true;
-	hoverName = name + ", " + town->faction->name;
 
 	if (subID == ETownType::DUNGEON)
 		creatures.resize(GameConstants::CREATURES_PER_TOWN+1);//extra dwelling for Dungeon

+ 2 - 1
lib/mapObjects/CGTownInstance.h

@@ -59,7 +59,7 @@ public:
 	void initObj() override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void newTurn() const override;
-	void setProperty(ui8 what, ui32 val) override;
+	void setPropertyDer(ui8 what, ui32 val) override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 
@@ -243,6 +243,7 @@ public:
 	void onHeroLeave(const CGHeroInstance * h) const override;
 	void initObj() override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
+	std::string getObjectName() const override;
 protected:
 	void setPropertyDer(ui8 what, ui32 val) override;
 };

+ 17 - 22
lib/mapObjects/CObjectHandler.cpp

@@ -53,12 +53,6 @@ static void showInfoDialog(const CGHeroInstance* h, const ui32 txtID, const ui16
 	showInfoDialog(playerID,txtID,soundID);
 }
 
-static std::string & visitedTxt(const bool visited)
-{
-	int id = visited ? 352 : 353;
-	return VLC->generaltexth->allTexts[id];
-}
-
 ///IObjectInterface
 void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
 {}
@@ -139,10 +133,6 @@ CGObjectInstance::~CGObjectInstance()
 {
 }
 
-const std::string & CGObjectInstance::getHoverText() const
-{
-	return hoverName;
-}
 void CGObjectInstance::setOwner(PlayerColor ow)
 {
 	tempOwner = ow;
@@ -223,6 +213,8 @@ void CGObjectInstance::initObj()
 
 void CGObjectInstance::setProperty( ui8 what, ui32 val )
 {
+	setPropertyDer(what, val); // call this before any actual changes (needed at least for dwellings)
+
 	switch(what)
 	{
 	case ObjProperty::OWNER:
@@ -238,7 +230,6 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val )
 		subID = val;
 		break;
 	}
-	setPropertyDer(what, val);
 }
 
 void CGObjectInstance::setPropertyDer( ui8 what, ui32 val )
@@ -265,17 +256,6 @@ int3 CGObjectInstance::getVisitableOffset() const
 	return int3(0,0,0);
 }
 
-void CGObjectInstance::getNameVis( std::string &hname ) const
-{
-	const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
-	hname = VLC->objtypeh->getObjectName(ID);
-	if(h)
-	{
-		const bool visited = h->hasBonusFrom(Bonus::OBJECT,ID);
-		hname + " " + visitedTxt(visited);
-	}
-}
-
 void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) const
 {
 	GiveBonus gbonus;
@@ -287,6 +267,21 @@ void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) con
 	cb->giveHeroBonus(&gbonus);
 }
 
+std::string CGObjectInstance::getObjectName() const
+{
+	return VLC->objtypeh->getObjectName(ID);
+}
+
+std::string CGObjectInstance::getHoverText(PlayerColor player) const
+{
+	return getObjectName();
+}
+
+std::string CGObjectInstance::getHoverText(const CGHeroInstance * hero) const
+{
+	return getHoverText(hero->tempOwner);
+}
+
 void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
 {
 	switch(ID)

+ 12 - 10
lib/mapObjects/CObjectHandler.h

@@ -95,8 +95,6 @@ public:
 class DLL_LINKAGE CGObjectInstance : public IObjectInterface
 {
 public:
-	mutable std::string hoverName;
-
 	/// Position of bottom-right corner of object on map
 	int3 pos;
 	/// Type of object, e.g. town, hero, creature.
@@ -141,33 +139,37 @@ public:
 	virtual int getSightRadious() const;
 	/// returns (x,y,0) offset to a visitable tile of object
 	virtual int3 getVisitableOffset() const;
-	/// returns text visible in status bar
-	/// TODO: should accept selected hero as parameter and possibly - moved into object handler
-	virtual const std::string & getHoverText() const;
 	/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
 	virtual void setType(si32 ID, si32 subID);
 
+	/// returns text visible in status bar with specific hero/player active.
+
+	/// Returns generic name of object, without any player-specific info
+	virtual std::string getObjectName() const;
+
+	/// Returns hover name for situation when there are no selected heroes. Default = object name
+	virtual std::string getHoverText(PlayerColor player) const;
+	/// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name
+	virtual std::string getHoverText(const CGHeroInstance * hero) const;
+
 	/** OVERRIDES OF IObjectInterface **/
 
 	void initObj() override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
-	void setProperty(ui8 what, ui32 val) override;
+	void setProperty(ui8 what, ui32 val) override final;
 
 	//friend class CGameHandler;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & hoverName & pos & ID & subID & id & tempOwner & blockVisit & appearance;
+		h & pos & ID & subID & id & tempOwner & blockVisit & appearance;
 		//definfo is handled by map serializer
 	}
 protected:
 	/// virtual method that allows synchronously update object state on server and all clients
 	virtual void setPropertyDer(ui8 what, ui32 val);
 
-	/// Adds (visited) text if selected hero has visited object
-	/// TODO: remove?
-	void getNameVis(std::string &hname) const;
 	/// Gives dummy bonus from this object to hero. Can be used to track visited state
 	void giveDummyBonus(ObjectInstanceID heroID, ui8 duration = Bonus::ONE_DAY) const;
 };

+ 10 - 25
lib/mapObjects/CQuest.cpp

@@ -434,25 +434,15 @@ void CGSeerHut::getRolloverText (MetaString &text, bool onHover) const
 		text.addReplacement(seerName);
 }
 
-const std::string & CGSeerHut::getHoverText() const
+std::string CGSeerHut::getHoverText(PlayerColor player) const
 {
-	switch (ID)
+	std::string hoverName = getObjectName();
+	if (ID == Obj::SEER_HUT && quest->progress != CQuest::NOT_ACTIVE)
 	{
-	case Obj::SEER_HUT:
-		if (quest->progress != CQuest::NOT_ACTIVE)
-		{
-			hoverName = VLC->generaltexth->allTexts[347];
-			boost::algorithm::replace_first(hoverName,"%s", seerName);
-		}
-		else //just seer hut
-			hoverName = VLC->objtypeh->getObjectName(ID);
-		break;
-	case Obj::QUEST_GUARD:
-		hoverName = VLC->objtypeh->getObjectName(ID);
-		break;
-	default:
-		logGlobal->debugStream() << "unrecognized quest object";
+		hoverName = VLC->generaltexth->allTexts[347];
+		boost::algorithm::replace_first(hoverName,"%s", seerName);
 	}
+
 	if (quest->progress & quest->missionType) //rollover when the quest is active
 	{
 		MetaString ms;
@@ -757,19 +747,14 @@ bool CGKeys::wasMyColorVisited (PlayerColor player) const
 		return false;
 }
 
-const std::string& CGKeys::getHoverText() const
+std::string CGKeys::getHoverText(PlayerColor player) const
 {
-	bool visited = wasMyColorVisited (cb->getLocalPlayer());
-	hoverName = getName() + "\n" + visitedTxt(visited);
-	return hoverName;
+	return getObjectName() + "\n" + visitedTxt(wasMyColorVisited(player));
 }
 
-
-const std::string CGKeys::getName() const
+std::string CGKeys::getObjectName() const
 {
-	std::string name;
-	name = VLC->generaltexth->tentColors[subID] + " " + VLC->objtypeh->getObjectName(ID);
-	return name;
+	return VLC->generaltexth->tentColors[subID] + " " + CGObjectInstance::getObjectName();
 }
 
 bool CGKeymasterTent::wasVisited (PlayerColor player) const

+ 3 - 3
lib/mapObjects/CQuest.h

@@ -95,7 +95,7 @@ public:
 
 	CGSeerHut() : IQuestObject(){};
 	void initObj() override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
 	void newTurn() const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
@@ -138,10 +138,10 @@ public:
 	static std::map <PlayerColor, std::set <ui8> > playerKeyMap; //[players][keysowned]
 	//SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black
 
-	const std::string getName() const; //depending on color
 	bool wasMyColorVisited (PlayerColor player) const;
 
-	const std::string & getHoverText() const override;
+	std::string getObjectName() const override; //depending on color
+	std::string getHoverText(PlayerColor player) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 9 - 10
lib/mapObjects/CRewardableObject.cpp

@@ -375,19 +375,18 @@ static std::string & visitedTxt(const bool visited)
 	return VLC->generaltexth->allTexts[id];
 }
 
-const std::string & CRewardableObject::getHoverText() const
+std::string CRewardableObject::getHoverText(PlayerColor player) const
 {
-	const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
-	hoverName = VLC->objtypeh->getObjectName(ID);
 	if(visitMode != VISIT_UNLIMITED)
-	{
-		bool visited = wasVisited(cb->getCurrentPlayer());
-		if (h)
-			visited |= wasVisited(h);
+		return getObjectName() + " " + visitedTxt(wasVisited(player));
+	return getObjectName();
+}
 
-		hoverName += " " + visitedTxt(visited);
-	}
-	return hoverName;
+std::string CRewardableObject::getHoverText(const CGHeroInstance * hero) const
+{
+	if(visitMode != VISIT_UNLIMITED)
+		return getObjectName() + " " + visitedTxt(wasVisited(hero));
+	return getObjectName();
 }
 
 void CRewardableObject::setPropertyDer(ui8 what, ui32 val)

+ 2 - 1
lib/mapObjects/CRewardableObject.h

@@ -209,7 +209,8 @@ protected:
 
 public:
 	void setPropertyDer(ui8 what, ui32 val) override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
 
 	/// Visitability checks. Note that hero check includes check for hero owner (returns true if object was visited by player)
 	bool wasVisited (PlayerColor player) const override;

+ 94 - 83
lib/mapObjects/MiscObjects.cpp

@@ -78,17 +78,16 @@ bool CPlayersVisited::wasVisited( TeamID team ) const
 	return false;
 }
 
-const std::string & CGCreature::getHoverText() const
+std::string CGCreature::getHoverText(PlayerColor player) const
 {
 	if(stacks.empty())
 	{
-		static const std::string errorValue("!!!INVALID_STACK!!!");
-
 		//should not happen...
 		logGlobal->errorStream() << "Invalid stack at tile " << pos << ": subID=" << subID << "; id=" << id;
-		return errorValue; // references to temporary are illegal - use pre-constructed string
+		return "!!!INVALID_STACK!!!";
 	}
 
+	std::string hoverName;
 	MetaString ms;
 	int pom = stacks.begin()->second->getQuantityID();
 	pom = 172 + 3*pom;
@@ -96,30 +95,34 @@ const std::string & CGCreature::getHoverText() const
 	ms << " " ;
 	ms.addTxt(MetaString::CRE_PL_NAMES,subID);
 	ms.toString(hoverName);
+	return hoverName;
+}
 
-	if(const CGHeroInstance *selHero = cb->getSelectedHero(cb->getCurrentPlayer()))
-	{
-		const JsonNode & texts = VLC->generaltexth->localizedTexts["adventureMap"]["monsterThreat"];
-
-		hoverName += texts["title"].String();
-		int choice;
-		double ratio = ((double)getArmyStrength() / selHero->getTotalStrength());
-		     if (ratio < 0.1)  choice = 0;
-		else if (ratio < 0.25) choice = 1;
-		else if (ratio < 0.6)  choice = 2;
-		else if (ratio < 0.9)  choice = 3;
-		else if (ratio < 1.1)  choice = 4;
-		else if (ratio < 1.3)  choice = 5;
-		else if (ratio < 1.8)  choice = 6;
-		else if (ratio < 2.5)  choice = 7;
-		else if (ratio < 4)    choice = 8;
-		else if (ratio < 8)    choice = 9;
-		else if (ratio < 20)   choice = 10;
-		else                   choice = 11;
-		hoverName += texts["levels"].Vector()[choice].String();
-	}
+std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
+{
+	std::string hoverName = getHoverText(hero->tempOwner);
+
+	const JsonNode & texts = VLC->generaltexth->localizedTexts["adventureMap"]["monsterThreat"];
+
+	hoverName += texts["title"].String();
+	int choice;
+	double ratio = ((double)getArmyStrength() / hero->getTotalStrength());
+		 if (ratio < 0.1)  choice = 0;
+	else if (ratio < 0.25) choice = 1;
+	else if (ratio < 0.6)  choice = 2;
+	else if (ratio < 0.9)  choice = 3;
+	else if (ratio < 1.1)  choice = 4;
+	else if (ratio < 1.3)  choice = 5;
+	else if (ratio < 1.8)  choice = 6;
+	else if (ratio < 2.5)  choice = 7;
+	else if (ratio < 4)    choice = 8;
+	else if (ratio < 8)    choice = 9;
+	else if (ratio < 20)   choice = 10;
+	else                   choice = 11;
+	hoverName += texts["levels"].Vector()[choice].String();
 	return hoverName;
 }
+
 void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
 {
 	int action = takenAction(h);
@@ -443,21 +446,6 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
 	}
 	else
 	{
-		//int killedAmount=0;
-		//for(std::set<std::pair<ui32,si32> >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++)
-		//	if(i->first == subID)
-		//		killedAmount += i->second;
-		//cb->setAmount(id, slots.find(0)->second.second - killedAmount);
-
-		/*
-		MetaString ms;
-		int pom = slots.find(0)->second.getQuantityID();
-		pom = 174 + 3*pom + 1;
-		ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID);
-		cb->setHoverName(id,&ms);
-		cb->setObjProperty(id, 11, slots.begin()->second.count * 1000);
-		*/
-
 		//merge stacks into one
 		TSlots::const_iterator i;
 		CCreature * cre = VLC->creh->creatures[formation.basicType];
@@ -554,37 +542,47 @@ void CGMine::initObj()
 		assert(!possibleResources.empty());
 		producedResource = *RandomGeneratorUtil::nextItem(possibleResources, cb->gameState()->getRandomGenerator());
 		tempOwner = PlayerColor::NEUTRAL;
-		hoverName = VLC->generaltexth->mines[7].first + "\n" + VLC->generaltexth->allTexts[202] + " " + troglodytes->getQuantityTXT(false) + " " + troglodytes->type->namePl;
 	}
 	else
 	{
 		producedResource = static_cast<Res::ERes>(subID);
-
-		MetaString ms;
-		ms << std::pair<ui8,ui32>(9,producedResource);
 		if(tempOwner >= PlayerColor::PLAYER_LIMIT)
 			tempOwner = PlayerColor::NEUTRAL;
-		else
-			ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner.getNum()) << ")";
-		ms.toString(hoverName);
 	}
 
 	producedQuantity = defaultResProduction();
 }
 
-void CGMine::flagMine(PlayerColor player) const
+std::string CGMine::getObjectName() const
 {
-	assert(tempOwner != player);
-	cb->setOwner(this, player); //not ours? flag it!
+	return VLC->generaltexth->mines.at(subID).first;
+}
 
-	MetaString ms;
-	ms << std::pair<ui8,ui32>(9,subID) << "\n(" << std::pair<ui8,ui32>(6,23+player.getNum()) << ")";
-	if(subID == 7)
+std::string CGMine::getHoverText(PlayerColor player) const
+{
+
+	std::string hoverName = getObjectName(); // Sawmill
+
+	if (tempOwner != PlayerColor::NEUTRAL)
 	{
-		ms << "(%s)";
-		ms.addReplacement(MetaString::RES_NAMES, producedResource);
+		hoverName += "\n";
+		hoverName += VLC->generaltexth->arraytxt[23 + tempOwner.getNum()]; // owned by Red Player
+		hoverName += "\n(" + VLC->generaltexth->restypes[producedResource] + ")";
 	}
-	cb->setHoverName(this,&ms);
+
+	for (auto & slot : Slots()) // guarded by a few Pikeman
+	{
+		hoverName += "\n";
+		hoverName += getRoughAmount(slot.first);
+		hoverName += getCreature(slot.first)->namePl;
+	}
+	return hoverName;
+}
+
+void CGMine::flagMine(PlayerColor player) const
+{
+	assert(tempOwner != player);
+	cb->setOwner(this, player); //not ours? flag it!
 
 	InfoWindow iw;
 	iw.soundID = soundBase::FLAGMINE;
@@ -626,10 +624,14 @@ void CGMine::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) con
 		cb->startBattleI(hero, this);
 }
 
+std::string CGResource::getHoverText(PlayerColor player) const
+{
+	return VLC->generaltexth->restypes[subID];
+}
+
 void CGResource::initObj()
 {
 	blockVisit = true;
-	hoverName = VLC->generaltexth->restypes[subID];
 
 	if(!amount)
 	{
@@ -866,7 +868,6 @@ void CGArtifact::initObj()
 	blockVisit = true;
 	if(ID == Obj::ARTIFACT)
 	{
-		hoverName = VLC->arth->artifacts[subID]->Name();
 		if(!storedArtifact->artType)
 			storedArtifact->setType(VLC->arth->artifacts[subID]);
 	}
@@ -879,6 +880,11 @@ void CGArtifact::initObj()
 	//assert(storedArtifact->artType->id == subID); //this does not stop desync
 }
 
+std::string CGArtifact::getObjectName() const
+{
+	return VLC->arth->artifacts[subID]->Name();
+}
+
 void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(!stacksCount())
@@ -985,20 +991,25 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const
 	cb->showInfoDialog(&iw);
 }
 
-const std::string & CGWitchHut::getHoverText() const
+std::string CGWitchHut::getHoverText(PlayerColor player) const
 {
-	hoverName = VLC->objtypeh->getObjectName(ID);
-	if(wasVisited(cb->getLocalPlayer()))
+	std::string hoverName = getObjectName();
+	if(wasVisited(player))
 	{
 		hoverName += "\n" + VLC->generaltexth->allTexts[356]; // + (learn %s)
 		boost::algorithm::replace_first(hoverName,"%s",VLC->generaltexth->skillName[ability]);
-		const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
-		if(h && h->getSecSkillLevel(SecondarySkill(ability))) //hero knows that ability
-			hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned)
 	}
 	return hoverName;
 }
 
+std::string CGWitchHut::getHoverText(const CGHeroInstance * hero) const
+{
+	std::string hoverName = getHoverText(hero->tempOwner);
+	if(hero->getSecSkillLevel(SecondarySkill(ability))) //hero knows that ability
+		hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned)
+	return hoverName;
+}
+
 void CGMagicWell::onHeroVisit( const CGHeroInstance * h ) const
 {
 	int message;
@@ -1020,10 +1031,9 @@ void CGMagicWell::onHeroVisit( const CGHeroInstance * h ) const
 	showInfoDialog(h,message,soundBase::faerie);
 }
 
-const std::string & CGMagicWell::getHoverText() const
+std::string CGMagicWell::getHoverText(const CGHeroInstance * hero) const
 {
-	getNameVis(hoverName);
-	return hoverName;
+	return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(Bonus::OBJECT,ID));
 }
 
 void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const
@@ -1120,20 +1130,25 @@ void CGShrine::initObj()
 	}
 }
 
-const std::string & CGShrine::getHoverText() const
+std::string CGShrine::getHoverText(PlayerColor player) const
 {
-	hoverName = VLC->objtypeh->getObjectName(ID);
-	if(wasVisited(cb->getCurrentPlayer())) //TODO: use local player, not current
+	std::string hoverName = getObjectName();
+	if(wasVisited(player))
 	{
 		hoverName += "\n" + VLC->generaltexth->allTexts[355]; // + (learn %s)
 		boost::algorithm::replace_first(hoverName,"%s", spell.toSpell()->name);
-		const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
-		if(h && vstd::contains(h->spells,spell)) //hero knows that ability
-			hoverName += "\n\n" + VLC->generaltexth->allTexts[354]; // (Already learned)
 	}
 	return hoverName;
 }
 
+std::string CGShrine::getHoverText(const CGHeroInstance * hero) const
+{
+	std::string hoverName = getHoverText(hero->tempOwner);
+	if(vstd::contains(hero->spells, spell)) //hero knows that spell
+		hoverName += "\n\n" + VLC->generaltexth->allTexts[354]; // (Already learned)
+	return hoverName;
+}
+
 void CGSignBottle::initObj()
 {
 	//if no text is set than we pick random from the predefined ones
@@ -1329,10 +1344,9 @@ void CGSirens::initObj()
 	blockVisit = true;
 }
 
-const std::string & CGSirens::getHoverText() const
+std::string CGSirens::getHoverText(const CGHeroInstance * hero) const
 {
-	getNameVis(hoverName);
-	return hoverName;
+	return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(Bonus::OBJECT,ID));
 }
 
 void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
@@ -1503,11 +1517,9 @@ void CGObelisk::initObj()
 	obeliskCount++;
 }
 
-const std::string & CGObelisk::getHoverText() const
+std::string CGObelisk::getHoverText(PlayerColor player) const
 {
-	bool visited = wasVisited(cb->getLocalPlayer());
-	hoverName = VLC->objtypeh->getObjectName(ID) + " " + visitedTxt(visited);
-	return hoverName;
+	return getObjectName() + " " + visitedTxt(wasVisited(player));
 }
 
 void CGObelisk::setPropertyDer( ui8 what, ui32 val )
@@ -1557,11 +1569,10 @@ void CGLighthouse::initObj()
 	}
 }
 
-const std::string & CGLighthouse::getHoverText() const
+std::string CGLighthouse::getHoverText(PlayerColor player) const
 {
-	hoverName = VLC->objtypeh->getObjectName(ID);
 	//TODO: owned by %s player
-	return hoverName;
+	return getObjectName();
 }
 
 void CGLighthouse::giveBonusTo( PlayerColor player ) const

+ 17 - 7
lib/mapObjects/MiscObjects.h

@@ -48,7 +48,8 @@ public:
 	bool refusedJoining;
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
 	void initObj() override;
 	void newTurn() const override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
@@ -106,7 +107,8 @@ public:
 	std::vector<si32> allowedAbilities;
 	ui32 ability;
 
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void initObj() override;
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -159,6 +161,8 @@ public:
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 
+	std::string getObjectName() const override;
+
 	void pick( const CGHeroInstance * h ) const;
 	void initObj() override;
 
@@ -179,6 +183,7 @@ public:
 	void initObj() override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
+	std::string getHoverText(PlayerColor player) const override;
 
 	void collectRes(PlayerColor player) const;
 
@@ -195,7 +200,8 @@ public:
 	SpellID spell; //id of spell or NONE if random
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void initObj() override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -217,6 +223,10 @@ public:
 	void flagMine(PlayerColor player) const;
 	void newTurn() const override;
 	void initObj() override;
+
+	std::string getObjectName() const override;
+	std::string getHoverText(PlayerColor player) const override;
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & static_cast<CArmedInstance&>(*this);
@@ -245,7 +255,7 @@ class DLL_LINKAGE CGMagicWell : public CGObjectInstance //objects giving bonuses
 {
 public:
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -257,7 +267,7 @@ class DLL_LINKAGE CGSirens : public CGObjectInstance
 {
 public:
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
 	void initObj() override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -352,7 +362,7 @@ public:
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void initObj() override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -367,7 +377,7 @@ class DLL_LINKAGE CGLighthouse : public CGObjectInstance
 public:
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void initObj() override;
-	const std::string & getHoverText() const override;
+	std::string getHoverText(PlayerColor player) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 1 - 1
lib/mapping/CMap.cpp

@@ -432,7 +432,7 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(int3 pos, Obj::EObj type)
 	}
 	assert(bestMatch != nullptr); // if this happens - victory conditions or map itself is very, very broken
 
-	logGlobal->errorStream() << "Will use " << bestMatch->getHoverText() << " from " << bestMatch->pos;
+	logGlobal->errorStream() << "Will use " << bestMatch->getObjectName() << " from " << bestMatch->pos;
 	return bestMatch;
 }
 

+ 0 - 1
lib/registerTypes/RegisterTypes.h

@@ -234,7 +234,6 @@ void registerTypesClientPacks1(Serializer &s)
 	s.template registerType<CPackForClient, NewTurn>();
 	s.template registerType<CPackForClient, InfoWindow>();
 	s.template registerType<CPackForClient, SetObjectProperty>();
-	s.template registerType<CPackForClient, SetHoverName>();
 	s.template registerType<CPackForClient, ShowInInfobox>();
 	s.template registerType<CPackForClient, AdvmapSpellCast>();
 	s.template registerType<CPackForClient, OpenWindow>();

+ 1 - 7
server/CGameHandler.cpp

@@ -1849,12 +1849,6 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner)
 	}
 }
 
-void CGameHandler::setHoverName(const CGObjectInstance * obj, MetaString* name)
-{
-	SetHoverName shn(obj->id, *name);
-	sendAndApply(&shn);
-}
-
 void CGameHandler::showBlockingDialog( BlockingDialog *iw )
 {
 	auto dialogQuery = make_shared<CBlockingDialogQuery>(*iw);
@@ -4992,7 +4986,7 @@ bool CGameHandler::isAllowedExchange( ObjectInstanceID id1, ObjectInstanceID id2
 
 void CGameHandler::objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h )
 {
-	logGlobal->traceStream()  << h->nodeName() << " visits " << obj->getHoverText();
+	logGlobal->traceStream()  << h->nodeName() << " visits " << obj->getObjectName();
 	auto visitQuery = make_shared<CObjectVisitQuery>(obj, h, obj->visitablePos());
 	queries.addQuery(visitQuery); //TODO real visit pos
 

+ 0 - 1
server/CGameHandler.h

@@ -127,7 +127,6 @@ public:
 	bool removeObject(const CGObjectInstance * obj) override;
 	void setBlockVis(ObjectInstanceID objid, bool bv) override;
 	void setOwner(const CGObjectInstance * obj, PlayerColor owner) override;
-	void setHoverName(const CGObjectInstance * objid, MetaString * name) override;
 	void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false) override;
 	void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) override; 
 	//void showInfoDialog(InfoWindow *iw) override;

+ 2 - 2
server/CQuery.cpp

@@ -322,7 +322,7 @@ CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu)
 void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
 {
 	assert(answer);
-	logGlobal->traceStream() << "Completing hero level-up query. " << hlu.hero->getHoverText() << " gains skill " << *answer;
+	logGlobal->traceStream() << "Completing hero level-up query. " << hlu.hero->getObjectName() << " gains skill " << *answer;
 	gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
 }
 
@@ -340,7 +340,7 @@ CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(const CommanderLevelU
 void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
 {
 	assert(answer);
-	logGlobal->traceStream() << "Completing commander level-up query. Commander of hero " << clu.hero->getHoverText() << " gains skill " << *answer;
+	logGlobal->traceStream() << "Completing commander level-up query. Commander of hero " << clu.hero->getObjectName() << " gains skill " << *answer;
 	gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
 }