1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-23 22:37:55 +02:00

Improvements to rewardable objects popups

This commit is contained in:
Ivan Savenko
2023-10-16 23:55:37 +03:00
parent 850d0ff8eb
commit 927ce4e60e
7 changed files with 94 additions and 19 deletions

View File

@@ -351,10 +351,20 @@ void CRClickPopup::createAndPush(const CGObjectInstance * obj, const Point & p,
} }
else else
{ {
std::vector<Component> components;
if(LOCPLINT->localState->getCurrentHero()) if(LOCPLINT->localState->getCurrentHero())
CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->localState->getCurrentHero())); components = obj->getPopupComponents(LOCPLINT->localState->getCurrentHero());
else else
CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID)); components = obj->getPopupComponents(LOCPLINT->playerID);
std::vector<std::shared_ptr<CComponent>> guiComponents;
for (auto & component : components)
guiComponents.push_back(std::make_shared<CComponent>(component));
if(LOCPLINT->localState->getCurrentHero())
CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->localState->getCurrentHero()), guiComponents);
else
CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID), guiComponents);
} }
} }

View File

@@ -271,6 +271,16 @@ std::string CGObjectInstance::getHoverText(const CGHeroInstance * hero) const
return getHoverText(hero->tempOwner); return getHoverText(hero->tempOwner);
} }
std::vector<Component> CGObjectInstance::getPopupComponents(PlayerColor player) const
{
return {};
}
std::vector<Component> CGObjectInstance::getPopupComponents(const CGHeroInstance * hero) const
{
return {};
}
void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
{ {
switch(ID) switch(ID)

View File

@@ -112,6 +112,9 @@ public:
/// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name /// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name
virtual std::string getHoverText(const CGHeroInstance * hero) const; virtual std::string getHoverText(const CGHeroInstance * hero) const;
virtual std::vector<Component> getPopupComponents(PlayerColor player) const;
virtual std::vector<Component> getPopupComponents(const CGHeroInstance * hero) const;
/** OVERRIDES OF IObjectInterface **/ /** OVERRIDES OF IObjectInterface **/
void initObj(CRandomGenerator & rand) override; void initObj(CRandomGenerator & rand) override;

View File

@@ -47,15 +47,22 @@ void CRewardableObject::selectRewardWthMessage(const CGHeroInstance * contextHer
BlockingDialog sd(configuration.canRefuse, rewardIndices.size() > 1); BlockingDialog sd(configuration.canRefuse, rewardIndices.size() > 1);
sd.player = contextHero->tempOwner; sd.player = contextHero->tempOwner;
sd.text = dialog; sd.text = dialog;
sd.components = loadComponents(contextHero, rewardIndices);
cb->showBlockingDialog(&sd);
}
std::vector<Component> CRewardableObject::loadComponents(const CGHeroInstance * contextHero, const std::vector<ui32> & rewardIndices) const
{
std::vector<Component> result;
if (rewardIndices.size() > 1) if (rewardIndices.size() > 1)
for (auto index : rewardIndices) for (auto index : rewardIndices)
sd.components.push_back(configuration.info.at(index).reward.getDisplayedComponent(contextHero)); result.push_back(configuration.info.at(index).reward.getDisplayedComponent(contextHero));
if (rewardIndices.size() == 1) if (rewardIndices.size() == 1)
configuration.info.at(rewardIndices.front()).reward.loadComponents(sd.components, contextHero); configuration.info.at(rewardIndices.front()).reward.loadComponents(result, contextHero);
cb->showBlockingDialog(&sd); return result;
} }
void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const
@@ -233,26 +240,68 @@ bool CRewardableObject::wasVisited(const CGHeroInstance * h) const
std::string CRewardableObject::getHoverText(PlayerColor player) const std::string CRewardableObject::getHoverText(PlayerColor player) const
{ {
std::string result = getObjectName();
if (!configuration.description.empty())
result += "\n" + configuration.description.toString();
if(configuration.visitMode == Rewardable::VISIT_PLAYER || configuration.visitMode == Rewardable::VISIT_ONCE) if(configuration.visitMode == Rewardable::VISIT_PLAYER || configuration.visitMode == Rewardable::VISIT_ONCE)
{ {
if (wasVisited(player)) if (wasVisited(player))
return getObjectName() + "\n" + configuration.visitedTooltip.toString() + "\n\n" + configuration.description.toString(); result += "\n\n" + configuration.visitedTooltip.toString();
else else
return getObjectName() + "\n" + configuration.notVisitedTooltip.toString() + "\n\n" + configuration.description.toString(); result += "\n\n" + configuration.notVisitedTooltip.toString();
} }
return getObjectName() + "\n\n" + configuration.description.toString(); return result;
} }
std::string CRewardableObject::getHoverText(const CGHeroInstance * hero) const std::string CRewardableObject::getHoverText(const CGHeroInstance * hero) const
{ {
std::string result = getObjectName();
if (!configuration.description.empty())
result += "\n" + configuration.description.toString();
if(configuration.visitMode != Rewardable::VISIT_UNLIMITED) if(configuration.visitMode != Rewardable::VISIT_UNLIMITED)
{ {
if (wasVisited(hero)) if (wasVisited(hero))
return getObjectName() + "\n" + configuration.visitedTooltip.toString() + "\n\n" + configuration.description.toString(); result += "\n\n" + configuration.visitedTooltip.toString();
else else
return getObjectName() + "\n" + configuration.notVisitedTooltip.toString() + "\n\n" + configuration.description.toString(); result += "\n\n" + configuration.notVisitedTooltip.toString();
} }
return getObjectName() + "\n\n" + configuration.description.toString(); return result;
}
std::vector<Component> CRewardableObject::getPopupComponents(PlayerColor player) const
{
if (!wasScouted(player))
return {};
auto rewardIndices = getAvailableRewards(nullptr, Rewardable::EEventType::EVENT_FIRST_VISIT);
if (rewardIndices.empty() && !configuration.info.empty())
rewardIndices.push_back(0);
if (rewardIndices.empty())
return {};
return loadComponents(nullptr, rewardIndices);
}
std::vector<Component> CRewardableObject::getPopupComponents(const CGHeroInstance * hero) const
{
if (!wasScouted(hero->getOwner()))
return {};
auto rewardIndices = getAvailableRewards(hero, Rewardable::EEventType::EVENT_FIRST_VISIT);
if (rewardIndices.empty() && !configuration.info.empty())
rewardIndices.push_back(0);
if (rewardIndices.empty())
return {};
return loadComponents(nullptr, rewardIndices);
} }
void CRewardableObject::setPropertyDer(ui8 what, ui32 val) void CRewardableObject::setPropertyDer(ui8 what, ui32 val)

View File

@@ -37,6 +37,8 @@ protected:
virtual void grantRewardWithMessage(const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const; virtual void grantRewardWithMessage(const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const;
virtual void selectRewardWthMessage(const CGHeroInstance * contextHero, const std::vector<ui32> & rewardIndices, const MetaString & dialog) const; virtual void selectRewardWthMessage(const CGHeroInstance * contextHero, const std::vector<ui32> & rewardIndices, const MetaString & dialog) const;
std::vector<Component> loadComponents(const CGHeroInstance * contextHero, const std::vector<ui32> & rewardIndices) const;
public: public:
/// Visitability checks. Note that hero check includes check for hero owner (returns true if object was visited by player) /// 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; bool wasVisited(PlayerColor player) const override;
@@ -66,6 +68,9 @@ public:
std::string getHoverText(PlayerColor player) const override; std::string getHoverText(PlayerColor player) const override;
std::string getHoverText(const CGHeroInstance * hero) const override; std::string getHoverText(const CGHeroInstance * hero) const override;
std::vector<Component> getPopupComponents(PlayerColor player) const override;
std::vector<Component> getPopupComponents(const CGHeroInstance * hero) const override;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CArmedInstance&>(*this); h & static_cast<CArmedInstance&>(*this);

View File

@@ -61,8 +61,7 @@ Component Rewardable::Reward::getDisplayedComponent(const CGHeroInstance * h) co
return comps.front(); return comps.front();
} }
void Rewardable::Reward::loadComponents(std::vector<Component> & comps, void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CGHeroInstance * h) const
const CGHeroInstance * h) const
{ {
for (auto comp : extraComponents) for (auto comp : extraComponents)
comps.push_back(comp); comps.push_back(comp);
@@ -76,14 +75,13 @@ void Rewardable::Reward::loadComponents(std::vector<Component> & comps,
} }
if (heroExperience) if (heroExperience)
{ comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h ? h->calculateXp(heroExperience) : heroExperience), 0);
comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h->calculateXp(heroExperience)), 0);
}
if (heroLevel) if (heroLevel)
comps.emplace_back(Component::EComponentType::EXPERIENCE, 1, heroLevel, 0); comps.emplace_back(Component::EComponentType::EXPERIENCE, 1, heroLevel, 0);
if (manaDiff || manaPercentage >= 0) if (manaDiff || manaPercentage >= 0)
comps.emplace_back(Component::EComponentType::PRIM_SKILL, 5, calculateManaPoints(h) - h->mana, 0); comps.emplace_back(Component::EComponentType::PRIM_SKILL, 5, h ? (calculateManaPoints(h) - h->mana) : manaDiff, 0);
for (size_t i=0; i<primary.size(); i++) for (size_t i=0; i<primary.size(); i++)
{ {

View File

@@ -108,8 +108,8 @@ struct DLL_LINKAGE Reward final
bool removeObject; bool removeObject;
/// Generates list of components that describes reward for a specific hero /// Generates list of components that describes reward for a specific hero
void loadComponents(std::vector<Component> & comps, /// If hero is nullptr, then rewards will be generated without accounting for hero
const CGHeroInstance * h) const; void loadComponents(std::vector<Component> & comps, const CGHeroInstance * h) const;
Component getDisplayedComponent(const CGHeroInstance * h) const; Component getDisplayedComponent(const CGHeroInstance * h) const;