diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index 0e8d8c353..d2b879a01 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/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(graphics->getAnimation(AnimationPath::builtin("TWCRPORT")), creatureData->getIconIndex()); + auto creatureID = creature->getCreature(); + int32_t creatureIconIndex = CGI->creatures()->getById(creatureID)->getIconIndex(); + + creatureImage = std::make_shared(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: diff --git a/lib/mapObjects/CGCreature.cpp b/lib/mapObjects/CGCreature.cpp index 04af6f8ad..cd5d90e82 100644 --- a/lib/mapObjects/CGCreature.cpp +++ b/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"); + if (settings["general"]["enableUiEnhancements"].Bool()) + { + hoverName += VLC->generaltexth->translate("vcmi.adventureMap.monsterThreat.title"); - int choice; - double ratio = (static_cast(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; + int choice; + double ratio = (static_cast(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)); + 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 CGCreature::getPopupComponents(PlayerColor player) const +{ + return { + Component(ComponentType::CREATURE, getCreature()) + }; +} + void CGCreature::onHeroVisit( const CGHeroInstance * h ) const { //show message diff --git a/lib/mapObjects/CGCreature.h b/lib/mapObjects/CGCreature.h index 13ff02f30..f2101d3b0 100644 --- a/lib/mapObjects/CGCreature.h +++ b/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 getPopupComponents(PlayerColor player) const override; void initObj(CRandomGenerator & rand) override; void pickRandomObject(CRandomGenerator & rand) override; void newTurn(CRandomGenerator & rand) const override; diff --git a/lib/mapObjects/CGDwelling.cpp b/lib/mapObjects/CGDwelling.cpp index e379901d7..ea0138a67 100644 --- a/lib/mapObjects/CGDwelling.cpp +++ b/lib/mapObjects/CGDwelling.cpp @@ -335,6 +335,30 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const updateGuards(); } +std::vector CGDwelling::getPopupComponents(PlayerColor player) const +{ + if (getOwner() != player) + return {}; + + std::vector 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 diff --git a/lib/mapObjects/CGDwelling.h b/lib/mapObjects/CGDwelling.h index bc63dcd85..7bed887db 100644 --- a/lib/mapObjects/CGDwelling.h +++ b/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 getPopupComponents(PlayerColor player) const override; void updateGuards() const; void heroAcceptsCreatures(const CGHeroInstance *h) const; diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index 761be1090..5739c71c2 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/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 CGSeerHut::getPopupComponents(PlayerColor player) const +{ + std::vector result; + if (quest->activeForPlayers.count(player)) + quest->mission.loadComponents(result, nullptr); + return result; +} + +std::vector CGSeerHut::getPopupComponents(const CGHeroInstance * hero) const +{ + std::vector result; + if (quest->activeForPlayers.count(hero->getOwner())) + quest->mission.loadComponents(result, hero); + return result; +} + void CGSeerHut::setPropertyDer(ui8 what, ui32 val) { switch(what) diff --git a/lib/mapObjects/CQuest.h b/lib/mapObjects/CQuest.h index bb4980611..6f9dbd017 100644 --- a/lib/mapObjects/CQuest.h +++ b/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 getPopupComponents(PlayerColor player) const override; + std::vector 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; diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index ca5ac7b73..40e12e03c 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/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 CGArtifact::getPopupComponents(PlayerColor player) const +{ + return { + Component(ComponentType::ARTIFACT, getArtifact()) + }; +} + void CGArtifact::onHeroVisit(const CGHeroInstance * h) const { if(!stacksCount()) diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index f89876ffc..6851888fa 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/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 getPopupComponents(PlayerColor player) const override; void pick( const CGHeroInstance * h ) const; void initObj(CRandomGenerator & rand) override; diff --git a/lib/rewardable/Limiter.cpp b/lib/rewardable/Limiter.cpp index 05c77909a..e6fd3b361 100644 --- a/lib/rewardable/Limiter.cpp +++ b/lib/rewardable/Limiter.cpp @@ -187,14 +187,14 @@ void Rewardable::Limiter::loadComponents(std::vector & comps, const CGHeroInstance * h) const { if (heroExperience) - comps.emplace_back(ComponentType::EXPERIENCE, static_cast(h->calculateXp(heroExperience))); + comps.emplace_back(ComponentType::EXPERIENCE, static_cast(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); }