Pārlūkot izejas kodu

- Fixed GCC compiler warnings
- Implemented move heroes to next scenario partially

beegee1 12 gadi atpakaļ
vecāks
revīzija
68bdf71db6

+ 2 - 2
AI/VCAI/Fuzzy.cpp

@@ -301,7 +301,7 @@ FuzzyHelper::TacticalAdvantage::~TacticalAdvantage()
 }
 
 //shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec)
-Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec & vec)
+Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
 {
 	if (vec.empty()) //no possibilities found
 		return sptr(Goals::Invalid());
@@ -455,4 +455,4 @@ float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
 {
 	logAi->debugStream() << boost::format("Cannot evaluate goal %s") % g.name();
 	return -1e10;
-}
+}

+ 1 - 1
AI/VCAI/Fuzzy.h

@@ -74,6 +74,6 @@ public:
 	ui64 estimateBankDanger (int ID);
 	float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
 
-	Goals::TSubgoal chooseSolution (Goals::TGoalVec & vec);
+	Goals::TSubgoal chooseSolution (Goals::TGoalVec vec);
 	//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec);
 };

+ 1 - 1
AI/VCAI/Goals.cpp

@@ -503,7 +503,7 @@ std::string VisitTile::completeMessage() const
 
 TSubgoal VisitTile::whatToDoToAchieve()
 {
-	auto ret = fh->chooseSolution (getAllPossibleSubgoals());
+	auto ret = fh->chooseSolution(getAllPossibleSubgoals());
 
 	if (ret->hero)
 	{

+ 1 - 1
CCallback.cpp

@@ -311,7 +311,7 @@ const CGPathNode * CCallback::getPathInfo( int3 tile )
 	return &cl->pathInfo->nodes[tile.x][tile.y][tile.z];
 }
 
-const int CCallback::getDistance( int3 tile )
+int CCallback::getDistance( int3 tile )
 {
 	CGPath ret;
 	if (getPath2 (tile, ret))

+ 1 - 1
CCallback.h

@@ -108,7 +108,7 @@ public:
 
 	//client-specific functionalities (pathfinding)
 	virtual const CGPathNode *getPathInfo(int3 tile); //uses main, client pathfinder info
-	virtual const int getDistance(int3 tile);
+	virtual int getDistance(int3 tile);
 	virtual bool getPath2(int3 dest, CGPath &ret); //uses main, client pathfinder info
 
 	virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1);

+ 1 - 1
client/CPreGame.cpp

@@ -3557,7 +3557,7 @@ void CBonusSelection::updateBonusSelection()
 				boost::algorithm::replace_first(desc, "%s", replacement);
 			}
 			break;
-		case CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO:
+		case CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO:
 			{
 				auto superhero = ourCampaign->camp->scenarios[bonDescs[i].info2].strongestHero(PlayerColor(bonDescs[i].info1));
 				if (!superhero) logGlobal->warnStream() << "No superhero! How could it be transfered?";

+ 1 - 13
client/mapHandler.cpp

@@ -171,20 +171,8 @@ void CMapHandler::roadsRiverTerrainInit()
 		for (int j=0-frameH;j<(int)sizes.y+frameH;j++)
 			ttiles[i][j].resize(sizes.z, 0, 0);
 	}
-/*
-	//FIXME: unused?
-	// prepare the map
-	for (int i=0; i<sizes.x; i++) //by width
-	{
-		for (int j=0; j<sizes.y;j++) //by height
-		{
-			for (int k=0; k<sizes.z; ++k) //by levels
-			{
-				TerrainTile2 &pom(ttiles[i][j][k]);
-			}
-		}
-	}*/
 }
+
 void CMapHandler::borderAndTerrainBitmapInit()
 {
 	CDefHandler * bord = CDefHandler::giveDef("EDG.DEF");

+ 6 - 5
client/mapHandler.h

@@ -36,13 +36,10 @@ struct TerrainTile2
 template <typename T> class PseudoV
 {
 public:
-	int offset;
-	std::vector<T> inver;
-	PseudoV(){};
-	PseudoV(std::vector<T> &src, int rest, int before, int after, const T& fill)
+	PseudoV() : offset(0) { }
+	PseudoV(std::vector<T> &src, int rest, int before, int after, const T& fill) : offset(before)
 	{
 		inver.resize(before + rest + after);
-		offset=before;
 		for(int i=0; i<before;i++)
 			inver[i] = fill;
 		for(int i=0;i<src.size();i++)
@@ -67,6 +64,10 @@ public:
 	{
 		return inver.size();
 	}
+
+private:
+	int offset;
+	std::vector<T> inver;
 };
 
 class CMapHandler

+ 177 - 71
lib/CGameState.cpp

@@ -1099,12 +1099,125 @@ void CGameState::initHeroPlaceholders()
 {
 	if (scenarioOps->campState)
 	{
-		logGlobal->debugStream() << "\tReplacing hero placeholders";
-		std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campHeroReplacements = campaignHeroesToReplace();
-		//Replace placeholders with heroes from previous missions
-		logGlobal->debugStream() << "\tSetting up heroes";
-		placeCampaignHeroes(campHeroReplacements);
+		auto campaignScenario = getCampaignScenarioForCrossoverHeroes();
+
+		if(campaignScenario)
+		{
+			logGlobal->debugStream() << "\tPrepare crossover heroes";
+			auto crossoverHeroes = prepareCrossoverHeroes(campaignScenario);
+
+			logGlobal->debugStream() << "\tGenerate list of hero placeholders";
+			auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
+
+			logGlobal->debugStream() << "\tReplace placeholders with heroes";
+			placeCampaignHeroes(campaignHeroReplacements);
+		}
+	}
+}
+
+const CCampaignScenario * CGameState::getCampaignScenarioForCrossoverHeroes() const
+{
+	const CCampaignScenario * campaignScenario = nullptr;
+
+	auto campaignState = scenarioOps->campState;
+	auto bonus = campaignState->getBonusForCurrentMap();
+	if (bonus->type == CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO)
+	{
+		campaignScenario = &campaignState->camp->scenarios[bonus->info2];
+	}
+	else
+	{
+		if(!campaignState->mapsConquered.empty())
+		{
+			campaignScenario = &campaignState->camp->scenarios[campaignState->mapsConquered.back()];
+		}
+	}
+
+	return campaignScenario;
+}
+
+std::vector<CGHeroInstance *> CGameState::prepareCrossoverHeroes(const CCampaignScenario * campaignScenario)
+{
+	auto crossoverHeroes = campaignScenario->crossoverHeroes; //TODO check if hero instances need to be copied
+	const auto & travelOptions = campaignScenario->travelOptions;
+
+	if (!(travelOptions.whatHeroKeeps & 1))
+	{
+		//trimming experience
+		for(CGHeroInstance * cgh : crossoverHeroes)
+		{
+			cgh->initExp();
+		}
+	}
+	if (!(travelOptions.whatHeroKeeps & 2))
+	{
+		//trimming prim skills
+		for(CGHeroInstance * cgh : crossoverHeroes)
+		{
+			for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
+			{
+				auto sel = Selector::type(Bonus::PRIMARY_SKILL)
+					.And(Selector::subtype(g))
+					.And(Selector::sourceType(Bonus::HERO_BASE_SKILL));
+
+				cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g];
+			}
+		}
+	}
+	if (!(travelOptions.whatHeroKeeps & 4))
+	{
+		//trimming sec skills
+		for(CGHeroInstance * cgh : crossoverHeroes)
+		{
+			cgh->secSkills = cgh->type->secSkillsInit;
+		}
+	}
+	if (!(travelOptions.whatHeroKeeps & 8))
+	{
+		//trimming spells
+		for(CGHeroInstance * cgh : crossoverHeroes)
+		{
+			cgh->spells.clear();
+			cgh->eraseArtSlot(ArtifactPosition(ArtifactPosition::SPELLBOOK)); // spellbook will also be removed
+		}
+	}
+	if (!(travelOptions.whatHeroKeeps & 16))
+	{
+		//trimming artifacts
+		for(CGHeroInstance * hero : crossoverHeroes)
+		{
+			size_t totalArts = GameConstants::BACKPACK_START + hero->artifactsInBackpack.size();
+			for (size_t i=0; i<totalArts; i++ )
+			{
+				auto artifactPosition = ArtifactPosition(i);
+				if(artifactPosition == ArtifactPosition::SPELLBOOK) continue; // do not handle spellbook this way
+
+				const ArtSlotInfo *info = hero->getSlot(artifactPosition);
+				if(!info) continue;
+
+				const CArtifactInstance *art = info->artifact;
+				if(!art) continue;
+
+				int id  = art->artType->id;
+				assert( 8*18 > id );//number of arts that fits into h3m format
+				bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
+
+				if(!takeable) hero->eraseArtSlot(ArtifactPosition(i));
+			}
+		}
+	}
+
+	//trimming creatures
+	for(CGHeroInstance * cgh : crossoverHeroes)
+	{
+		vstd::erase_if(cgh->stacks, [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
+		{
+			CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
+			return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)) );
+		});
 	}
+
+	return std::move(crossoverHeroes);
 }
 
 void CGameState::placeStartingHeroes()
@@ -2587,92 +2700,85 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
 	return ret;
 }
 
-std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::campaignHeroesToReplace()
+std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes)
 {
-	std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > ret;
-	auto replaceHero = [&](ObjectInstanceID objId, CGHeroInstance * ghi)
-	{
-		ret.push_back(std::make_pair(ghi, objId));
-		// 			ghi->tempOwner = getHumanPlayerInfo()[0]->color;
-		// 			ghi->id = objId;
-		// 			gs->map->objects[objId] = ghi;
-		// 			gs->map->heroes.push_back(ghi);
-	};
+	std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroReplacements;
 
-	auto campaign = scenarioOps->campState;
-	if(auto bonus = campaign->getBonusForCurrentMap())
+	//selecting heroes by type
+	for(int g = 0; g < map->objects.size(); ++g)
 	{
-		std::vector<CGHeroInstance*> Xheroes;
-		if (bonus->type == CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO)
+		CGObjectInstance * obj = map->objects[g];
+		if (obj->ID == Obj::HERO_PLACEHOLDER)
 		{
-			Xheroes = campaign->camp->scenarios[bonus->info2].crossoverHeroes;
-		}
+			CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
 
-		//selecting heroes by type
-		for(int g=0; g<map->objects.size(); ++g)
-		{
-			CGObjectInstance * obj = map->objects[g];
-			if (obj->ID == Obj::HERO_PLACEHOLDER)
+			const ObjectInstanceID gid = ObjectInstanceID(g);
+			if(hp->subID != 0xFF) //select by type
 			{
-				CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
-
-				const ObjectInstanceID gid = ObjectInstanceID(g);
-				if(hp->subID != 0xFF) //select by type
+				bool found = false;
+				for(auto ghi : crossoverHeroes)
 				{
-					bool found = false;
-					for(auto ghi : Xheroes)
+					if (ghi->subID == hp->subID)
 					{
-						if (ghi->subID == hp->subID)
-						{
-							found = true;
-							replaceHero(gid, ghi);
-							Xheroes -= ghi;
-							break;
-						}
-					}
-					if (!found)
-					{
-						auto  nh = new CGHeroInstance();
-						nh->initHero(HeroTypeID(hp->subID));
-						replaceHero(gid, nh);
+						found = true;
+						campaignHeroReplacements.push_back(std::make_pair(ghi, gid));
+						crossoverHeroes -= ghi;
+						break;
 					}
 				}
+				if(!found)
+				{
+					auto nh = new CGHeroInstance();
+					nh->initHero(HeroTypeID(hp->subID));
+					campaignHeroReplacements.push_back(std::make_pair(nh, gid));
+				}
+
+				//TODO delete hero placeholder
 			}
 		}
+	}
 
-		//selecting heroes by power
-
-		std::sort(Xheroes.begin(), Xheroes.end(), [](const CGHeroInstance * a, const CGHeroInstance * b)
-		{
-			return a->getHeroStrength() > b->getHeroStrength();
-		}); //sort, descending strength
+	//selecting heroes by power
+	std::sort(crossoverHeroes.begin(), crossoverHeroes.end(), [](const CGHeroInstance * a, const CGHeroInstance * b)
+	{
+		return a->getHeroStrength() > b->getHeroStrength();
+	}); //sort, descending strength
 
-		for(int g=0; g<map->objects.size(); ++g)
+	// sort hero placeholders descending power
+	std::vector<CGHeroPlaceholder *> heroPlaceholders;
+	for(int g = 0; g < map->objects.size(); ++g)
+	{
+		CGObjectInstance * obj = map->objects[g];
+		if(obj->ID == Obj::HERO_PLACEHOLDER)
 		{
-			CGObjectInstance * obj = map->objects[g];
-			if (obj->ID == Obj::HERO_PLACEHOLDER)
+			CGHeroPlaceholder * hp = dynamic_cast<CGHeroPlaceholder*>(obj);
+			if(hp->subID == 0xFF) //select by power
 			{
-				CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
-
-				const ObjectInstanceID gid = ObjectInstanceID(g);
-				if (hp->subID == 0xFF) //select by power
-				{
-					if(Xheroes.size() > hp->power - 1)
-						replaceHero(gid, Xheroes[hp->power - 1]);
-					else
-					{
-						logGlobal->warnStream() << "Warning, no hero to replace!";
-						map->removeBlockVisTiles(hp, true);
-						delete hp;
-						map->objects[g] = nullptr;
-					}
-					//we don't have to remove hero from Xheroes because it would destroy the order and duplicates shouldn't happen
-				}
+				heroPlaceholders.push_back(hp);
 			}
 		}
 	}
+	std::sort(heroPlaceholders.begin(), heroPlaceholders.end(), [](const CGHeroPlaceholder * a, const CGHeroPlaceholder * b)
+	{
+		return a->power > b->power;
+	});
 
-	return ret;
+	for(int i = 0; i < heroPlaceholders.size(); ++i)
+	{
+		auto heroPlaceholder = heroPlaceholders[i];
+		if(crossoverHeroes.size() > i)
+		{
+			campaignHeroReplacements.push_back(std::make_pair(crossoverHeroes[i], heroPlaceholder->id));
+		}
+		else
+		{
+			map->removeBlockVisTiles(heroPlaceholder, true);
+			delete heroPlaceholder;
+			map->objects[heroPlaceholder->id.getNum()] = nullptr;
+		}
+	}
+
+	return campaignHeroReplacements;
 }
 
 void CGameState::placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements)

+ 15 - 4
lib/CGameState.h

@@ -59,6 +59,7 @@ class CGGarrison;
 class CGameInfo;
 struct QuestInfo;
 class CQuest;
+class CCampaignScenario;
 
 namespace boost
 {
@@ -445,7 +446,8 @@ public:
 	}
 
 private:
-	// Init game state
+	// ----- initialization -----
+
 	void initNewGame();
 	void initCampaign();
 	void initDuel();
@@ -456,6 +458,12 @@ private:
 	void randomizeObject(CGObjectInstance *cur);
 	void initPlayerStates();
 	void initHeroPlaceholders();
+	const CCampaignScenario * getCampaignScenarioForCrossoverHeroes() const;
+	std::vector<CGHeroInstance *> prepareCrossoverHeroes(const CCampaignScenario * campaignScenario);
+
+	// returns heroes and placeholders in where heroes will be put
+	std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes);
+
 	void placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
 	void placeStartingHeroes();
 	void initStartingResources();
@@ -467,20 +475,23 @@ private:
 	void initMapObjects();
 	void initVisitingAndGarrisonedHeroes();
 
-	// Victory / Loss condition checks
+	// ----- victory, loss condition checks -----
+
 	EVictoryLossCheckResult checkForVictory(PlayerColor player) const; //checks if given player is winner
 	EVictoryLossCheckResult checkForLoss(PlayerColor player) const; //checks if given player is loser
 	PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
 	bool checkForStandardLoss(PlayerColor player) const; //checks if given player lost the game
 
-	// Bonus system handling
+	// ----- bonus system handling -----
+
 	void buildBonusSystemTree();
 	void attachArmedObjects();
 	void buildGlobalTeamPlayerTree();
 	void deserializationFix();
 
+	// ---- misc helpers -----
+
 	bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
-	std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroesToReplace(); //returns heroes and placeholders in where heroes will be put; may remove some placeholders
 	std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
 	std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
 	int pickHero(PlayerColor owner);

+ 2 - 0
lib/Connection.cpp

@@ -265,6 +265,8 @@ void CConnection::prepareForSendingHeroes()
 	savedPointers.clear();
 	disableSmartVectorMemberSerialization();
 	enableSmartPointerSerializatoin();
+	//disableSmartPointerSerializatoin();
+	disableStackSendingByID();
 }
 
 void CConnection::enterPregameConnectionMode()

+ 3 - 84
lib/mapping/CCampaignHandler.cpp

@@ -242,7 +242,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
 			for (int g=0; g<numOfBonuses; ++g)
 			{
 				CScenarioTravel::STravelBonus bonus;
-				bonus.type = CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO;
+				bonus.type = CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO;
 				bonus.info1 = buffer[outIt++]; //player color
 				bonus.info2 = buffer[outIt++]; //from what scenario
 
@@ -322,87 +322,6 @@ bool CCampaignScenario::isNotVoid() const
 	return mapName.size() > 0;
 }
 
-void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> heroes )
-{
-	crossoverHeroes = heroes;
-
-
-	if (!(travelOptions.whatHeroKeeps & 1))
-	{
-		//trimming experience
-		for(CGHeroInstance * cgh : crossoverHeroes)
-		{
-			cgh->initExp();
-		}
-	}
-	if (!(travelOptions.whatHeroKeeps & 2))
-	{
-		//trimming prim skills
-		for(CGHeroInstance * cgh : crossoverHeroes)
-		{
-			for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
-			{
-				auto sel = Selector::type(Bonus::PRIMARY_SKILL)
-					.And(Selector::subtype(g))
-					.And(Selector::sourceType(Bonus::HERO_BASE_SKILL));
-
-				cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g];
-			}
-		}
-	}
-	if (!(travelOptions.whatHeroKeeps & 4))
-	{
-		//trimming sec skills
-		for(CGHeroInstance * cgh : crossoverHeroes)
-		{
-			cgh->secSkills = cgh->type->secSkillsInit;
-		}
-	}
-	if (!(travelOptions.whatHeroKeeps & 8))
-	{
-		//trimming spells
-		for(CGHeroInstance * cgh : crossoverHeroes)
-		{
-			cgh->spells.clear();
-		}
-	}
-	if (!(travelOptions.whatHeroKeeps & 16))
-	{
-		//trimming artifacts
-		for(CGHeroInstance * hero : crossoverHeroes)
-		{
-			size_t totalArts = GameConstants::BACKPACK_START + hero->artifactsInBackpack.size();
-			for (size_t i=0; i<totalArts; i++ )
-			{
-				const ArtSlotInfo *info = hero->getSlot(ArtifactPosition(i));
-				if (!info)
-					continue;
-
-				const CArtifactInstance *art = info->artifact;
-				if (!art)//FIXME: check spellbook and catapult behaviour
-					continue;
-
-				int id  = art->artType->id;
-				assert( 8*18 > id );//number of arts that fits into h3m format
-				bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
-
-				if (!takeable)
-					hero->eraseArtSlot(ArtifactPosition(i));
-			}
-		}
-	}
-
-	//trimming creatures
-	for(CGHeroInstance * cgh : crossoverHeroes)
-	{
-		vstd::erase_if(cgh->stacks, [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
-		{
-			CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
-			return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)) );
-		});
-	}
-}
-
 const CGHeroInstance * CCampaignScenario::strongestHero( PlayerColor owner ) const
 {
 	using boost::adaptors::filtered;
@@ -431,9 +350,9 @@ bool CScenarioTravel::STravelBonus::isBonusForHero() const
 // 		mapsRemaining.push_back(i);
 // }
 
-void CCampaignState::mapConquered( const std::vector<CGHeroInstance*> & heroes )
+void CCampaignState::setCurrentMapAsConquered( const std::vector<CGHeroInstance*> & heroes )
 {
-	camp->scenarios[*currentMap].prepareCrossoverHeroes(heroes);
+	camp->scenarios[*currentMap].crossoverHeroes = heroes;
 	mapsConquered.push_back(*currentMap);
 	mapsRemaining -= *currentMap;
 	camp->scenarios[*currentMap].conquered = true;

+ 3 - 3
lib/mapping/CCampaignHandler.h

@@ -59,7 +59,7 @@ public:
 	struct DLL_LINKAGE STravelBonus
 	{
 		enum EBonusType {SPELL, MONSTER, BUILDING, ARTIFACT, SPELL_SCROLL, PRIMARY_SKILL, SECONDARY_SKILL, RESOURCE,
-			PLAYER_PREV_SCENARIO, HERO};
+			HEROES_FROM_PREVIOUS_SCENARIO, HERO};
 		EBonusType type; //uses EBonusType
 		si32 info1, info2, info3; //purpose depends on type
 
@@ -108,7 +108,7 @@ public:
 	SScenarioPrologEpilog prolog, epilog;
 
 	CScenarioTravel travelOptions;
-	std::vector<CGHeroInstance *> crossoverHeroes;
+	std::vector<CGHeroInstance *> crossoverHeroes; // contains all heroes with the same state when the camapign scenario was finished
 
 	const CGHeroInstance * strongestHero(PlayerColor owner) const;
 	void loadPreconditionRegions(ui32 regions);
@@ -150,7 +150,7 @@ public:
 	std::map<ui8, ui8> chosenCampaignBonuses;
 
 	//void initNewCampaign(const StartInfo &si);
-	void mapConquered(const std::vector<CGHeroInstance*> & heroes);
+	void setCurrentMapAsConquered(const std::vector<CGHeroInstance*> & heroes);
 	boost::optional<CScenarioTravel::STravelBonus> getBonusForCurrentMap() const;
 	const CCampaignScenario &getCurrentScenario() const;
 	ui8 currentBonusID() const;

+ 4 - 7
server/CGameHandler.cpp

@@ -5108,15 +5108,12 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
 
 				if(gs->scenarioOps->campState)
 				{
-					std::vector<CGHeroInstance *> hes;
-					for(CGHeroInstance * ghi : gs->map->heroesOnMap)
+					std::vector<CGHeroInstance *> heroesBelongingToPlayer;
+					for(CGHeroInstance * hero : gs->map->heroesOnMap)
 					{
-						if (ghi->tempOwner == player)
-						{
-							hes.push_back(ghi);
-						}
+						if(hero->tempOwner == player) heroesBelongingToPlayer.push_back(hero);
 					}
-					gs->scenarioOps->campState->mapConquered(hes);
+					gs->scenarioOps->campState->setCurrentMapAsConquered(heroesBelongingToPlayer);
 
 					//Request clients to change connection mode
 					PrepareForAdvancingCampaign pfac;