Browse Source

Implement select all option for rewardable objects

nordsoft 2 years ago
parent
commit
68c61797f8

+ 36 - 4
lib/mapObjects/CGPandoraBox.cpp

@@ -28,6 +28,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 void CGPandoraBox::init()
 {
 	blockVisit = true;
+	configuration.selectMode = Rewardable::SELECT_ALL;
 	
 	for(auto & i : configuration.info)
 		i.reward.removeObject = true;
@@ -169,33 +170,62 @@ void CGPandoraBox::serializeJsonOptions(JsonSerializeFormat & handler)
 	{
 		//backward compatibility
 		CCreatureSet::serializeJson(handler, "guards", 7);
+		Rewardable::Reward reward;
+		
+		auto addReward = [this, &reward](bool condition)
+		{
+			if(condition)
+			{
+				configuration.info.emplace_back();
+				configuration.info.back().visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
+				configuration.info.back().reward = reward;
+			}
+		};
+		
+		addReward(true);
 		
-		Rewardable::VisitInfo vinfo;
-		vinfo.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
-		auto & reward = vinfo.reward;
 		int val;
 		handler.serializeInt("experience", reward.heroExperience, 0);
+		addReward(reward.heroExperience);
+		
 		handler.serializeInt("mana", reward.manaDiff, 0);
+		addReward(reward.manaDiff);
+		
 		handler.serializeInt("morale", val, 0);
 		if(val)
 			reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, id);
+		addReward(val);
+		
 		handler.serializeInt("luck", val, 0);
 		if(val)
 			reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, id);
+		addReward(val);
 		
 		reward.resources.serializeJson(handler, "resources");
+		addReward(reward.resources.nonZero());
+		
 		{
+			bool updateReward = false;
 			auto s = handler.enterStruct("primarySkills");
 			for(int idx = 0; idx < reward.primary.size(); idx ++)
+			{
 				handler.serializeInt(NPrimarySkill::names[idx], reward.primary[idx], 0);
+				updateReward |= reward.primary[idx];
+			}
+			addReward(updateReward);
 		}
 		
 		handler.serializeIdArray("artifacts", reward.artifacts);
+		addReward(!reward.artifacts.empty());
+		
 		handler.serializeIdArray("spells", reward.spells);
+		addReward(!reward.spells.empty());
 
 		handler.enterArray("creatures").serializeStruct(reward.creatures);
+		addReward(!reward.creatures.empty());
 		
 		{
+			bool updateReward = false;
 			auto s = handler.enterStruct("secondarySkills");
 			for(const auto & p : handler.getCurrent().Struct())
 			{
@@ -217,15 +247,17 @@ void CGPandoraBox::serializeJsonOptions(JsonSerializeFormat & handler)
 				}
 				
 				reward.secondary[rawId] = level;
+				updateReward = true;
 			}
+			addReward(updateReward);
 		}
-		configuration.info.push_back(vinfo);
 	}
 }
 
 void CGEvent::init()
 {
 	blockVisit = false;
+	configuration.selectMode = Rewardable::SELECT_ALL;
 	
 	for(auto & i : configuration.info)
 		i.reward.removeObject = removeAfterVisit;

+ 3 - 0
lib/mapObjects/CRewardableObject.cpp

@@ -108,6 +108,9 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const
 					case Rewardable::SELECT_RANDOM: // give random
 						grantRewardWithMessage(*RandomGeneratorUtil::nextItem(rewards, cb->gameState()->getRandomGenerator()), true);
 						break;
+					case Rewardable::SELECT_ALL: // give all rewards
+						for(auto i : rewards)
+							grantRewardWithMessage(i, i == rewards.size() - 1);
 				}
 				break;
 			}

+ 2 - 1
lib/rewardable/Configuration.h

@@ -35,6 +35,7 @@ enum ESelectMode
 	SELECT_FIRST,  // first reward that matches limiters
 	SELECT_PLAYER, // player can select from all allowed rewards
 	SELECT_RANDOM, // one random reward from all mathing limiters
+	SELECT_ALL,    // provides all allowed rewards matching limiters
 };
 
 enum class EEventType
@@ -45,7 +46,7 @@ enum class EEventType
 	EVENT_NOT_AVAILABLE
 };
 
-const std::array<std::string, 3> SelectModeString{"selectFirst", "selectPlayer", "selectRandom"};
+const std::array<std::string, 4> SelectModeString{"selectFirst", "selectPlayer", "selectRandom", "selectAll"};
 const std::array<std::string, 5> VisitModeString{"unlimited", "once", "hero", "bonus", "player"};
 
 struct DLL_LINKAGE ResetInfo