Explorar o código

bugfixing:
- fixed parsing of campaign bonuses (conversion to building ID)
- CONTROL event condition can be also fulfilled by allies
- fix for crash on opening exchange window in Russian version

Ivan Savenko %!s(int64=11) %!d(string=hai) anos
pai
achega
78609871ae
Modificáronse 3 ficheiros con 38 adicións e 29 borrados
  1. 12 10
      client/GUIClasses.cpp
  2. 20 17
      lib/CBuildingHandler.cpp
  3. 6 2
      lib/CGameState.cpp

+ 12 - 10
client/GUIClasses.cpp

@@ -5147,7 +5147,6 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
     CWindowObject(PLAYER_COLORED | BORDERED, "TRADE2")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
-	char bufor[400];
 	heroInst[0] = LOCPLINT->cb->getHero(hero1);
 	heroInst[1] = LOCPLINT->cb->getHero(hero2);
 
@@ -5175,8 +5174,8 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 		primSkillAreas[g]->type = g;
 		primSkillAreas[g]->bonusValue = -1;
 		primSkillAreas[g]->baseType = 0;
-		sprintf(bufor, CGI->generaltexth->heroscrn[1].c_str(), CGI->generaltexth->primarySkillNames[g].c_str());
-		primSkillAreas[g]->hoverText = std::string(bufor);
+		primSkillAreas[g]->hoverText = CGI->generaltexth->heroscrn[1];
+		boost::replace_first(primSkillAreas[g]->hoverText, "%s", CGI->generaltexth->primarySkillNames[g]);
 	}
 
 	//heroes related thing
@@ -5195,8 +5194,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 			secSkillAreas[b][g]->bonusValue = level;
 			secSkillAreas[b][g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1];
 
-			sprintf(bufor, CGI->generaltexth->heroscrn[21].c_str(), CGI->generaltexth->levels[level - 1].c_str(), CGI->generaltexth->skillName[skill].c_str());
-			secSkillAreas[b][g]->hoverText = std::string(bufor);
+			secSkillAreas[b][g]->hoverText = CGI->generaltexth->heroscrn[21];
+			boost::algorithm::replace_first(secSkillAreas[b][g]->hoverText, "%s", CGI->generaltexth->levels[level - 1]);
+			boost::algorithm::replace_first(secSkillAreas[b][g]->hoverText, "%s", CGI->generaltexth->skillName[skill]);
 		}
 
 		portrait[b] = new CHeroArea(257 + 228*b, 13, heroInst[b]);
@@ -5210,15 +5210,17 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 		experience[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + 45);
 		experience[b]->hoverText = CGI->generaltexth->heroscrn[9];
 		experience[b]->text = CGI->generaltexth->allTexts[2].c_str();
-		boost::replace_first(experience[b]->text, "%d", boost::lexical_cast<std::string>(heroInst[b]->level));
-		boost::replace_first(experience[b]->text, "%d", boost::lexical_cast<std::string>(CGI->heroh->reqExp(heroInst[b]->level+1)));
-		boost::replace_first(experience[b]->text, "%d", boost::lexical_cast<std::string>(heroInst[b]->exp));
+		boost::algorithm::replace_first(experience[b]->text, "%d", boost::lexical_cast<std::string>(heroInst[b]->level));
+		boost::algorithm::replace_first(experience[b]->text, "%d", boost::lexical_cast<std::string>(CGI->heroh->reqExp(heroInst[b]->level+1)));
+		boost::algorithm::replace_first(experience[b]->text, "%d", boost::lexical_cast<std::string>(heroInst[b]->exp));
 
 		spellPoints[b] = new LRClickableAreaWText();
 		spellPoints[b]->pos = genRect(32, 32, pos.x + 141 + 490*b, pos.y + 45);
 		spellPoints[b]->hoverText = CGI->generaltexth->heroscrn[22];
-		sprintf(bufor, CGI->generaltexth->allTexts[205].c_str(), heroInst[b]->name.c_str(), heroInst[b]->mana, heroInst[b]->manaLimit());
-		spellPoints[b]->text = std::string(bufor);
+		spellPoints[b]->text = CGI->generaltexth->allTexts[205];
+		boost::algorithm::replace_first(spellPoints[b]->text, "%s", heroInst[b]->name);
+		boost::algorithm::replace_first(spellPoints[b]->text, "%d", boost::lexical_cast<std::string>(heroInst[b]->mana));
+		boost::algorithm::replace_first(spellPoints[b]->text, "%d", boost::lexical_cast<std::string>(heroInst[b]->manaLimit()));
 
 		//setting morale
 		morale[b] = new MoraleLuckBox(true, genRect(32, 32, 176 + 490*b, 39), true);

+ 20 - 17
lib/CBuildingHandler.cpp

@@ -32,7 +32,7 @@ BuildingID CBuildingHandler::campToERMU( int camp, int townType, std::set<Buildi
 		list_of(0), list_of(0), list_of(0), list_of(0), list_of(0)};
 
 	int curPos = campToERMU.size();
-	for (int i=0; i<7; ++i)
+	for (int i=0; i<GameConstants::CREATURES_PER_TOWN; ++i)
 	{
 		if(camp == curPos) //non-upgraded
 			return BuildingID(30 + i);
@@ -40,31 +40,34 @@ BuildingID CBuildingHandler::campToERMU( int camp, int townType, std::set<Buildi
 		if(camp == curPos) //upgraded
 			return BuildingID(37 + i);
 		curPos++;
-		//horde building
-		if (vstd::contains(hordeLvlsPerTType[townType], i))
+
+		if (i < 5) // last two levels don't have reserved horde ID. Yet another H3C weirdeness
 		{
-			if (camp == curPos)
+			if (vstd::contains(hordeLvlsPerTType[townType], i))
 			{
-				if (hordeLvlsPerTType[townType][0] == i)
-				{
-					if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][0])) //if upgraded dwelling is built
-						return BuildingID::HORDE_1_UPGR;
-					else //upgraded dwelling not presents
-						return BuildingID::HORDE_1;
-				}
-				else
+				if (camp == curPos)
 				{
-					if(hordeLvlsPerTType[townType].size() > 1)
+					if (hordeLvlsPerTType[townType][0] == i)
 					{
-						if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][1])) //if upgraded dwelling is built
-							return BuildingID::HORDE_2_UPGR;
+						if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][0])) //if upgraded dwelling is built
+							return BuildingID::HORDE_1_UPGR;
 						else //upgraded dwelling not presents
-							return BuildingID::HORDE_2;
+							return BuildingID::HORDE_1;
+					}
+					else
+					{
+						if(hordeLvlsPerTType[townType].size() > 1)
+						{
+							if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][1])) //if upgraded dwelling is built
+								return BuildingID::HORDE_2_UPGR;
+							else //upgraded dwelling not presents
+								return BuildingID::HORDE_2;
+						}
 					}
 				}
 			}
+			curPos++;
 		}
-		curPos++;
 	}
 	assert(0);
 	return BuildingID::NONE; //not found

+ 6 - 2
lib/CGameState.cpp

@@ -2438,16 +2438,20 @@ bool CGameState::checkForVictory( PlayerColor player, const EventCondition & con
 		}
 		case EventCondition::CONTROL:
 		{
+			// list of players that need to control object to fulfull condition
+			// NOTE: cgameinfocallback specified explicitly in order to get const version
+			auto & team = CGameInfoCallback::getPlayerTeam(player)->players;
+
 			if (condition.object) // mode A - flag one specific object, like town
 			{
-				return condition.object->tempOwner == player;
+				return team.count(condition.object->tempOwner) != 0;
 			}
 			else
 			{
 				for(auto & elem : map->objects) // mode B - flag all objects of this type
 				{
 					 //check not flagged objs
-					if(elem && elem->tempOwner != player && elem->ID == condition.objectType)
+					if ( elem && elem->ID == condition.objectType && team.count(elem->tempOwner) == 0 )
 						return false;
 				}
 				return true;