Browse Source

Fixed possible crash on having selectable reward with no visual image

Ivan Savenko 1 year ago
parent
commit
1dc962804e
3 changed files with 16 additions and 5 deletions
  1. 1 0
      client/adventureMap/CInfoBar.cpp
  2. 6 3
      client/widgets/CComponent.cpp
  3. 9 2
      lib/rewardable/Reward.cpp

+ 1 - 0
client/adventureMap/CInfoBar.cpp

@@ -386,6 +386,7 @@ void CInfoBar::pushComponents(const std::vector<Component> & components, std::st
 					reward_map.at(0).first.push_back(c);
 					reward_map.at(0).second = 8; //At most 8, cannot be more
 					break;
+				case ComponentType::NONE:
 				case ComponentType::SEC_SKILL:
 					reward_map.at(1).first.push_back(c);
 					reward_map.at(1).second = 4; //At most 4

+ 6 - 3
client/widgets/CComponent.cpp

@@ -133,6 +133,7 @@ std::vector<AnimationPath> CComponent::getFileName() const
 		case ComponentType::MANA:
 		case ComponentType::LEVEL:
 			return gen(primSkillsArr);
+		case ComponentType::NONE:
 		case ComponentType::SEC_SKILL:
 			return gen(secSkillsArr);
 		case ComponentType::RESOURCE:
@@ -165,6 +166,8 @@ size_t CComponent::getIndex() const
 {
 	switch(data.type)
 	{
+		case ComponentType::NONE:
+			return 0;
 		case ComponentType::PRIM_SKILL:
 			return data.subType.getNum();
 		case ComponentType::EXPERIENCE:
@@ -216,6 +219,7 @@ std::string CComponent::getDescription() const
 		case ComponentType::RESOURCE:
 		case ComponentType::RESOURCE_PER_DAY:
 			return CGI->generaltexth->allTexts[242];
+		case ComponentType::NONE:
 		case ComponentType::CREATURE:
 			return "";
 		case ComponentType::ARTIFACT:
@@ -288,9 +292,10 @@ std::string CComponent::getSubtitle() const
 		case ComponentType::SPELL_SCROLL:
 		case ComponentType::SPELL:
 			return CGI->spells()->getById(data.subType.as<SpellID>())->getNameTranslated();
+		case ComponentType::NONE:
 		case ComponentType::MORALE:
-			return "";
 		case ComponentType::LUCK:
+		case ComponentType::HERO_PORTRAIT:
 			return "";
 		case ComponentType::BUILDING:
 			{
@@ -303,8 +308,6 @@ std::string CComponent::getSubtitle() const
 				}
 				return building->getNameTranslated();
 			}
-		case ComponentType::HERO_PORTRAIT:
-			return "";
 		case ComponentType::FLAG:
 			return CGI->generaltexth->capColors[data.subType.as<PlayerColor>().getNum()];
 		default:

+ 9 - 2
lib/rewardable/Reward.cpp

@@ -63,8 +63,15 @@ Component Rewardable::Reward::getDisplayedComponent(const CGHeroInstance * h) co
 {
 	std::vector<Component> comps;
 	loadComponents(comps, h);
-	assert(!comps.empty());
-	return comps.front();
+
+	if (!comps.empty())
+		return comps.front();
+
+	// Rewardable requested component that represent such rewards, to be used as button in UI selection dialog, e.g. Chest with its experience / money pick
+	// However reward is either completely empty OR has no rewards that target hero can receive OR these rewards have no visible component (e.g. movement)
+	// Such cases are unreachable in H3, however can be reached by mods
+	logMod->warn("Failed to find displayed component for reward!");
+	return Component(ComponentType::NONE, 0);
 }
 
 void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CGHeroInstance * h) const