Răsfoiți Sursa

Hero portraits in campaign bonus selection.

Michał W. Urbańczyk 12 ani în urmă
părinte
comite
2f39db2375

+ 1 - 0
Global.h

@@ -79,6 +79,7 @@
 #include <boost/program_options.hpp>
 #include <boost/optional.hpp>
 #include <boost/range/algorithm.hpp>
+#include <boost/range/adaptor/filtered.hpp>
 #include <boost/thread.hpp>
 #include <boost/unordered_map.hpp>
 #include <boost/unordered_set.hpp>

+ 8 - 5
client/CPreGame.cpp

@@ -3409,7 +3409,7 @@ void CBonusSelection::updateBonusSelection()
 	bonuses->buttons.clear();
 
 		static const char *bonusPics[] = {"SPELLBON.DEF", "TWCRPORT.DEF", "", "ARTIFBON.DEF", "SPELLBON.DEF",
-			"PSKILBON.DEF", "SSKILBON.DEF", "BORES.DEF", "CREST58.DEF", "PORTRAITSLARGE"};
+			"PSKILBON.DEF", "SSKILBON.DEF", "BORES.DEF", "PORTRAITSLARGE", "PORTRAITSLARGE"};
 
 		for(int i = 0; i < bonDescs.size(); i++)
 		{
@@ -3531,11 +3531,14 @@ void CBonusSelection::updateBonusSelection()
 				}
 				break;
 			case CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO:
-				picNumber = bonDescs[i].info1;
-				desc = CGI->generaltexth->allTexts[718];
+				{
+					auto superhero = ourCampaign->camp->scenarios[bonDescs[i].info2].strongestHero(bonDescs[i].info1);
+					if (!superhero) tlog5 << "No superhero! How could it be transfered?\n";
+					picNumber = superhero ? superhero->portrait : 0;
+					desc = CGI->generaltexth->allTexts[719];
 
-				boost::algorithm::replace_first(desc, "%s", CGI->generaltexth->capColors[bonDescs[i].info1]); //player color
-				boost::algorithm::replace_first(desc, "%s", ourCampaign->camp->scenarios[bonDescs[i].info2].mapName); //scenario
+					boost::algorithm::replace_first(desc, "%s", ourCampaign->camp->scenarios[bonDescs[i].info2].scenarioName); //scenario
+				}
 
 				break;
 			case CScenarioTravel::STravelBonus::HERO:

+ 14 - 0
lib/Mapping/CCampaignHandler.cpp

@@ -10,6 +10,8 @@
 #include "../CArtHandler.h" //for hero crossover
 #include "../CObjectHandler.h" //for hero crossover
 #include "../CHeroHandler.h"
+#include "CMapService.h"
+#include "CMap.h"
 
 namespace fs = boost::filesystem;
 
@@ -64,6 +66,7 @@ unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
 
 		//set map piece appropriately, convert vector to string
 		ret->mapPieces[scenarioID].assign(reinterpret_cast< const char* >(file[g].data()), file[g].size());
+		ret->scenarios[scenarioID].scenarioName = CMapService::loadMapHeader((const ui8*)ret->mapPieces[scenarioID].c_str(), ret->mapPieces[scenarioID].size())->name;
 		scenarioID++;
 	}
 
@@ -397,6 +400,17 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
 	}
 }
 
+const CGHeroInstance * CCampaignScenario::strongestHero( TPlayerColor owner ) const
+{
+	using boost::adaptors::filtered;
+	std::function<bool(CGHeroInstance*)> isOwned =  [=](const CGHeroInstance *h){ return h->tempOwner == owner; };
+	auto ownedHeroes = crossoverHeroes | filtered(isOwned);
+
+	auto i = vstd::maxElementByFun(ownedHeroes,
+									[](const CGHeroInstance * h) {return h->getTotalStrength();});
+	return i == ownedHeroes.end() ? nullptr : *i;
+}
+
 bool CScenarioTravel::STravelBonus::isBonusForHero() const
 {
 	return type == SPELL || type == MONSTER || type == ARTIFACT || type == SPELL_SCROLL || type == PRIMARY_SKILL

+ 5 - 2
lib/Mapping/CCampaignHandler.h

@@ -83,7 +83,8 @@ public:
 class DLL_LINKAGE CCampaignScenario
 {
 public:
-	std::string mapName;
+	std::string mapName; //*.h3m
+	std::string scenarioName; //from header. human-readble
 	ui32 packedMapSize; //generally not used
 	std::set<ui8> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
 	ui8 regionColor;
@@ -111,6 +112,8 @@ public:
 
 	std::vector<CGHeroInstance *> crossoverHeroes;
 
+	const CGHeroInstance * strongestHero(TPlayerColor owner) const;
+
 	void loadPreconditionRegions(ui32 regions);
 	void prepareCrossoverHeroes(std::vector<CGHeroInstance *> heroes);
 
@@ -118,7 +121,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int formatVersion)
 	{
-		h & mapName & packedMapSize & preconditionRegions & regionColor & difficulty & conquered & regionText & 
+		h & mapName & scenarioName & packedMapSize & preconditionRegions & regionColor & difficulty & conquered & regionText & 
 			prolog & epilog & travelOptions & crossoverHeroes;
 	}
 };

+ 1 - 2
lib/Mapping/MapFormatH3M.cpp

@@ -1329,8 +1329,7 @@ void CMapLoaderH3M::readObjects()
 				CGHeroPlaceholder * hp = new CGHeroPlaceholder();
 				nobj = hp;
 
-				int a = reader.readUInt8();//unknown byte, seems to be always 0 (if not - scream!)
-				tlog2 << "Unhandled Hero Placeholder detected: " << a << std::endl;
+				hp->setOwner(reader.readUInt8());
 
 				int htid = reader.readUInt8();; //hero type id
 				nobj->subID = htid;