Przeglądaj źródła

Improvements to rewardable objects popups

Ivan Savenko 2 lat temu
rodzic
commit
927ce4e60e

+ 12 - 2
client/windows/InfoWindows.cpp

@@ -351,10 +351,20 @@ void CRClickPopup::createAndPush(const CGObjectInstance * obj, const Point & p,
 	}
 	else
 	{
+		std::vector<Component> components;
 		if(LOCPLINT->localState->getCurrentHero())
-			CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->localState->getCurrentHero()));
+			components = obj->getPopupComponents(LOCPLINT->localState->getCurrentHero());
 		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);
 	}
 }
 

+ 10 - 0
lib/mapObjects/CGObjectInstance.cpp

@@ -271,6 +271,16 @@ std::string CGObjectInstance::getHoverText(const CGHeroInstance * hero) const
 	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
 {
 	switch(ID)

+ 3 - 0
lib/mapObjects/CGObjectInstance.h

@@ -112,6 +112,9 @@ public:
 	/// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name
 	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 **/
 
 	void initObj(CRandomGenerator & rand) override;

+ 58 - 9
lib/mapObjects/CRewardableObject.cpp

@@ -47,15 +47,22 @@ void CRewardableObject::selectRewardWthMessage(const CGHeroInstance * contextHer
 	BlockingDialog sd(configuration.canRefuse, rewardIndices.size() > 1);
 	sd.player = contextHero->tempOwner;
 	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)
 		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)
-		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
@@ -233,26 +240,68 @@ bool CRewardableObject::wasVisited(const CGHeroInstance * h) 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 (wasVisited(player))
-			return getObjectName() + "\n" + configuration.visitedTooltip.toString() + "\n\n" + configuration.description.toString();
+			result += "\n\n" + configuration.visitedTooltip.toString();
 		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 result = getObjectName();
+
+	if (!configuration.description.empty())
+		result += "\n" + configuration.description.toString();
+
 	if(configuration.visitMode != Rewardable::VISIT_UNLIMITED)
 	{
 		if (wasVisited(hero))
-			return getObjectName() + "\n" + configuration.visitedTooltip.toString() + "\n\n" + configuration.description.toString();
+			result += "\n\n" + configuration.visitedTooltip.toString();
 		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)

+ 5 - 0
lib/mapObjects/CRewardableObject.h

@@ -37,6 +37,8 @@ protected:
 	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;
 
+	std::vector<Component> loadComponents(const CGHeroInstance * contextHero, const std::vector<ui32> & rewardIndices) const;
+
 public:
 	/// 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;
@@ -66,6 +68,9 @@ public:
 	std::string getHoverText(PlayerColor player) 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)
 	{
 		h & static_cast<CArmedInstance&>(*this);

+ 4 - 6
lib/rewardable/Reward.cpp

@@ -61,8 +61,7 @@ Component Rewardable::Reward::getDisplayedComponent(const CGHeroInstance * h) co
 	return comps.front();
 }
 
-void Rewardable::Reward::loadComponents(std::vector<Component> & comps,
-								 const CGHeroInstance * h) const
+void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CGHeroInstance * h) const
 {
 	for (auto comp : extraComponents)
 		comps.push_back(comp);
@@ -76,14 +75,13 @@ void Rewardable::Reward::loadComponents(std::vector<Component> & comps,
 	}
 	
 	if (heroExperience)
-	{
-		comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h->calculateXp(heroExperience)), 0);
-	}
+		comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h ? h->calculateXp(heroExperience) : heroExperience), 0);
+
 	if (heroLevel)
 		comps.emplace_back(Component::EComponentType::EXPERIENCE, 1, heroLevel, 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++)
 	{

+ 2 - 2
lib/rewardable/Reward.h

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