소스 검색

Merge pull request #3141 from IvanSavenko/better_tooltips

Better tooltips
Ivan Savenko 1 년 전
부모
커밋
f4feaea177

+ 6 - 4
client/widgets/MiscWidgets.cpp

@@ -515,14 +515,16 @@ CreatureTooltip::CreatureTooltip(Point pos, const CGCreature * creature)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
 
-	auto creatureData = (*CGI->creh)[creature->stacks.begin()->second->getCreatureID()].get();
-	creatureImage = std::make_shared<CAnimImage>(graphics->getAnimation(AnimationPath::builtin("TWCRPORT")), creatureData->getIconIndex());
+	auto creatureID = creature->getCreature();
+	int32_t creatureIconIndex = CGI->creatures()->getById(creatureID)->getIconIndex();
+
+	creatureImage = std::make_shared<CAnimImage>(graphics->getAnimation(AnimationPath::builtin("TWCRPORT")), creatureIconIndex);
 	creatureImage->center(Point(parent->pos.x + parent->pos.w / 2, parent->pos.y + creatureImage->pos.h / 2 + 11));
 
 	bool isHeroSelected = LOCPLINT->localState->getCurrentHero() != nullptr;
 	std::string textContent = isHeroSelected
-			? creature->getHoverText(LOCPLINT->localState->getCurrentHero())
-			: creature->getHoverText(LOCPLINT->playerID);
+			? creature->getPopupText(LOCPLINT->localState->getCurrentHero())
+			: creature->getPopupText(LOCPLINT->playerID);
 
 	//TODO: window is bigger than OH3
 	//TODO: vertical alignment does not match H3. Commented below example that matches H3 for creatures count but supports only 1 line:

+ 51 - 24
lib/mapObjects/CGCreature.cpp

@@ -32,7 +32,6 @@ std::string CGCreature::getHoverText(PlayerColor player) const
 		return "INVALID_STACK";
 	}
 
-	std::string hoverName;
 	MetaString ms;
 	CCreature::CreatureQuantityId monsterQuantityId = stacks.begin()->second->getQuantityID();
 	int quantityTextIndex = 172 + 3 * (int)monsterQuantityId;
@@ -42,20 +41,33 @@ std::string CGCreature::getHoverText(PlayerColor player) const
 		ms.appendLocalString(EMetaText::ARRAY_TXT, quantityTextIndex);
 	ms.appendRawString(" ");
 	ms.appendLocalString(EMetaText::CRE_PL_NAMES, getCreature());
-	hoverName = ms.toString();
-	return hoverName;
+
+	return ms.toString();
 }
 
 std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
 {
-	std::string hoverName;
 	if(hero->hasVisions(this, BonusCustomSubtype::visionsMonsters))
 	{
 		MetaString ms;
 		ms.appendNumber(stacks.begin()->second->count);
 		ms.appendRawString(" ");
 		ms.appendLocalString(EMetaText::CRE_PL_NAMES, getCreature());
+		return ms.toString();
+	}
+	else
+	{
+		return getHoverText(hero->tempOwner);
+	}
+}
 
+std::string CGCreature::getPopupText(const CGHeroInstance * hero) const
+{
+	std::string hoverName;
+	if(hero->hasVisions(this, BonusCustomSubtype::visionsMonsters))
+	{
+		MetaString ms;
+		ms.appendRawString(getHoverText(hero));
 		ms.appendRawString("\n\n");
 
 		int decision = takenAction(hero, true);
@@ -72,10 +84,10 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
 			ms.appendLocalString(EMetaText::GENERAL_TXT,243);
 			break;
 		default: //decision = cost in gold
-			ms.appendRawString(boost::str(boost::format(VLC->generaltexth->allTexts[244]) % decision));
+			ms.appendLocalString(EMetaText::GENERAL_TXT,244);
+			ms.replaceNumber(decision);
 			break;
 		}
-
 		hoverName = ms.toString();
 	}
 	else
@@ -83,27 +95,42 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
 		hoverName = getHoverText(hero->tempOwner);
 	}
 
-	hoverName += VLC->generaltexth->translate("vcmi.adventureMap.monsterThreat.title");
-
-	int choice;
-	double ratio = (static_cast<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 += VLC->generaltexth->translate("vcmi.adventureMap.monsterThreat.levels." + std::to_string(choice));
+	if (settings["general"]["enableUiEnhancements"].Bool())
+	{
+		hoverName += VLC->generaltexth->translate("vcmi.adventureMap.monsterThreat.title");
+
+		int choice;
+		double ratio = (static_cast<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 += VLC->generaltexth->translate("vcmi.adventureMap.monsterThreat.levels." + std::to_string(choice));
+	}
 	return hoverName;
 }
 
+std::string CGCreature::getPopupText(PlayerColor player) const
+{
+	return getHoverText(player);
+}
+
+std::vector<Component> CGCreature::getPopupComponents(PlayerColor player) const
+{
+	return {
+		Component(ComponentType::CREATURE, getCreature())
+	};
+}
+
 void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
 {
 	//show message

+ 3 - 0
lib/mapObjects/CGCreature.h

@@ -40,6 +40,9 @@ public:
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	std::string getHoverText(PlayerColor player) const override;
 	std::string getHoverText(const CGHeroInstance * hero) const override;
+	std::string getPopupText(PlayerColor player) const override;
+	std::string getPopupText(const CGHeroInstance * hero) const override;
+	std::vector<Component> getPopupComponents(PlayerColor player) const override;
 	void initObj(CRandomGenerator & rand) override;
 	void pickRandomObject(CRandomGenerator & rand) override;
 	void newTurn(CRandomGenerator & rand) const override;

+ 24 - 0
lib/mapObjects/CGDwelling.cpp

@@ -335,6 +335,30 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const
 	updateGuards();
 }
 
+std::vector<Component> CGDwelling::getPopupComponents(PlayerColor player) const
+{
+	if (getOwner() != player)
+		return {};
+
+	std::vector<Component> result;
+
+	if (ID == Obj::CREATURE_GENERATOR1 && !creatures.empty())
+	{
+		for (auto const & creature : creatures.front().second)
+			result.emplace_back(ComponentType::CREATURE, creature, creatures.front().first);
+	}
+
+	if (ID == Obj::CREATURE_GENERATOR4)
+	{
+		for (auto const & creatureLevel : creatures)
+		{
+			if (!creatureLevel.second.empty())
+				result.emplace_back(ComponentType::CREATURE, creatureLevel.second.back(), creatureLevel.first);
+		}
+	}
+	return result;
+}
+
 void CGDwelling::updateGuards() const
 {
 	//TODO: store custom guard config and use it

+ 1 - 0
lib/mapObjects/CGDwelling.h

@@ -55,6 +55,7 @@ private:
 	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;
+	std::vector<Component> getPopupComponents(PlayerColor player) const override;
 
 	void updateGuards() const;
 	void heroAcceptsCreatures(const CGHeroInstance *h) const;

+ 31 - 0
lib/mapObjects/CQuest.cpp

@@ -513,6 +513,37 @@ std::string CGSeerHut::getHoverText(PlayerColor player) const
 	return hoverName;
 }
 
+std::string CGSeerHut::getHoverText(const CGHeroInstance * hero) const
+{
+	return getHoverText(hero->getOwner());
+}
+
+std::string CGSeerHut::getPopupText(PlayerColor player) const
+{
+	return getHoverText(player);
+}
+
+std::string CGSeerHut::getPopupText(const CGHeroInstance * hero) const
+{
+	return getHoverText(hero->getOwner());
+}
+
+std::vector<Component> CGSeerHut::getPopupComponents(PlayerColor player) const
+{
+	std::vector<Component> result;
+	if (quest->activeForPlayers.count(player))
+		quest->mission.loadComponents(result, nullptr);
+	return result;
+}
+
+std::vector<Component> CGSeerHut::getPopupComponents(const CGHeroInstance * hero) const
+{
+	std::vector<Component> result;
+	if (quest->activeForPlayers.count(hero->getOwner()))
+		quest->mission.loadComponents(result, hero);
+	return result;
+}
+
 void CGSeerHut::setPropertyDer(ui8 what, ui32 val)
 {
 	switch(what)

+ 5 - 0
lib/mapObjects/CQuest.h

@@ -119,6 +119,11 @@ public:
 
 	void initObj(CRandomGenerator & rand) override;
 	std::string getHoverText(PlayerColor player) const override;
+	std::string getHoverText(const CGHeroInstance * hero) const override;
+	std::string getPopupText(PlayerColor player) const override;
+	std::string getPopupText(const CGHeroInstance * hero) const override;
+	std::vector<Component> getPopupComponents(PlayerColor player) const override;
+	std::vector<Component> getPopupComponents(const CGHeroInstance * hero) const override;
 	void newTurn(CRandomGenerator & rand) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;

+ 26 - 0
lib/mapObjects/MiscObjects.cpp

@@ -11,7 +11,9 @@
 #include "StdInc.h"
 #include "MiscObjects.h"
 
+#include "../ArtifactUtils.h"
 #include "../constants/StringConstants.h"
+#include "../CConfigHandler.h"
 #include "../CGeneralTextHandler.h"
 #include "../CSoundBase.h"
 #include "../CSkillHandler.h"
@@ -776,6 +778,30 @@ std::string CGArtifact::getObjectName() const
 	return VLC->artifacts()->getById(getArtifact())->getNameTranslated();
 }
 
+std::string CGArtifact::getPopupText(PlayerColor player) const
+{
+	if (settings["general"]["enableUiEnhancements"].Bool())
+	{
+		std::string description = VLC->artifacts()->getById(getArtifact())->getDescriptionTranslated();
+		ArtifactUtils::insertScrrollSpellName(description, SpellID::NONE); // erase text placeholder
+		return description;
+	}
+	else
+		return getObjectName();
+}
+
+std::string CGArtifact::getPopupText(const CGHeroInstance * hero) const
+{
+	return getPopupText(hero->getOwner());
+}
+
+std::vector<Component> CGArtifact::getPopupComponents(PlayerColor player) const
+{
+	return {
+		Component(ComponentType::ARTIFACT, getArtifact())
+	};
+}
+
 void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
 {
 	if(!stacksCount())

+ 3 - 0
lib/mapObjects/MiscObjects.h

@@ -86,6 +86,9 @@ public:
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 
 	std::string getObjectName() const override;
+	std::string getPopupText(PlayerColor player) const override;
+	std::string getPopupText(const CGHeroInstance * hero) const override;
+	std::vector<Component> getPopupComponents(PlayerColor player) const override;
 
 	void pick( const CGHeroInstance * h ) const;
 	void initObj(CRandomGenerator & rand) override;

+ 2 - 2
lib/rewardable/Limiter.cpp

@@ -187,14 +187,14 @@ void Rewardable::Limiter::loadComponents(std::vector<Component> & comps,
 								 const CGHeroInstance * h) const
 {
 	if (heroExperience)
-		comps.emplace_back(ComponentType::EXPERIENCE, static_cast<si32>(h->calculateXp(heroExperience)));
+		comps.emplace_back(ComponentType::EXPERIENCE, static_cast<si32>(h ? h->calculateXp(heroExperience) : heroExperience));
 
 	if (heroLevel > 0)
 		comps.emplace_back(ComponentType::EXPERIENCE, heroLevel);
 
 	if (manaPoints || manaPercentage > 0)
 	{
-		int absoluteMana = h->manaLimit() ? (manaPercentage * h->mana / h->manaLimit() / 100) : 0;
+		int absoluteMana = (h && h->manaLimit()) ? (manaPercentage * h->mana / h->manaLimit() / 100) : 0;
 		comps.emplace_back(ComponentType::MANA, absoluteMana + manaPoints);
 	}