Forráskód Böngészése

Merge pull request #1765 from vcmi/fix_horde_buildings_load

Fix loading horde buildings predefined in editor
Ivan Savenko 2 éve
szülő
commit
a64f35c933
3 módosított fájl, 37 hozzáadás és 23 törlés
  1. 18 14
      lib/CGameState.cpp
  2. 9 0
      lib/GameConstants.h
  3. 10 9
      lib/mapping/MapFormatH3M.cpp

+ 18 - 14
lib/CGameState.cpp

@@ -1761,33 +1761,37 @@ void CGameState::initTowns()
 			}
 		}
 
-		//#1444 - remove entries that don't have buildings defined (like some unused extra town hall buildings)
-		vstd::erase_if(vti->builtBuildings, [vti](const BuildingID & bid)
-		{
-			return !vti->town->buildings.count(bid) || !vti->town->buildings.at(bid);
-		});
-
-		if (vstd::contains(vti->builtBuildings, BuildingID::SHIPYARD) && vti->shipyardStatus()==IBoatGenerator::TILE_BLOCKED)
-			vti->builtBuildings.erase(BuildingID::SHIPYARD);//if we have harbor without water - erase it (this is H3 behaviour)
-
 		//init hordes
-		for (int i = 0; i<GameConstants::CREATURES_PER_TOWN; i++)
-			if (vstd::contains(vti->builtBuildings,(-31-i))) //if we have horde for this level
+		for (int i = 0; i < GameConstants::CREATURES_PER_TOWN; i++)
+		{
+			if (vstd::contains(vti->builtBuildings, (BuildingID::HORDE_PLACEHOLDER1 - i))) //if we have horde for this level
 			{
-				vti->builtBuildings.erase(BuildingID(-31-i));//remove old ID
+				vti->builtBuildings.erase(BuildingID(BuildingID::HORDE_PLACEHOLDER1 - i));//remove old ID
 				if (vti->town->hordeLvl.at(0) == i)//if town first horde is this one
 				{
 					vti->builtBuildings.insert(BuildingID::HORDE_1);//add it
-					if (vstd::contains(vti->builtBuildings,(BuildingID::DWELL_UP_FIRST+i)))//if we have upgraded dwelling as well
+					//if we have upgraded dwelling as well
+					if (vstd::contains(vti->builtBuildings, (BuildingID::DWELL_UP_FIRST + i)))
 						vti->builtBuildings.insert(BuildingID::HORDE_1_UPGR);//add it as well
 				}
 				if (vti->town->hordeLvl.at(1) == i)//if town second horde is this one
 				{
 					vti->builtBuildings.insert(BuildingID::HORDE_2);
-					if (vstd::contains(vti->builtBuildings,(BuildingID::DWELL_UP_FIRST+i)))
+					if (vstd::contains(vti->builtBuildings, (BuildingID::DWELL_UP_FIRST + i)))
 						vti->builtBuildings.insert(BuildingID::HORDE_2_UPGR);
 				}
 			}
+		}
+
+		//#1444 - remove entries that don't have buildings defined (like some unused extra town hall buildings)
+		//But DO NOT remove horde placeholders before they are replaced
+		vstd::erase_if(vti->builtBuildings, [vti](const BuildingID & bid)
+			{
+				return !vti->town->buildings.count(bid) || !vti->town->buildings.at(bid);
+			});
+
+		if (vstd::contains(vti->builtBuildings, BuildingID::SHIPYARD) && vti->shipyardStatus()==IBoatGenerator::TILE_BLOCKED)
+			vti->builtBuildings.erase(BuildingID::SHIPYARD);//if we have harbor without water - erase it (this is H3 behaviour)
 
 		//Early check for #1444-like problems
 		for(const auto & building : vti->builtBuildings)

+ 9 - 0
lib/GameConstants.h

@@ -473,7 +473,16 @@ public:
 	enum EBuildingID
 	{
 		DEFAULT = -50,
+		HORDE_PLACEHOLDER7 = -36,
+		HORDE_PLACEHOLDER6 = -35,
+		HORDE_PLACEHOLDER5 = -34,
+		HORDE_PLACEHOLDER4 = -33,
+		HORDE_PLACEHOLDER3 = -32,
+		HORDE_PLACEHOLDER2 = -31,
+		HORDE_PLACEHOLDER1 = -30,
+		HORDE_BUILDING_CONVERTER = -29, //-1 => -30
 		NONE = -1,
+		FIRST_REGULAR_ID = 0,
 		MAGES_GUILD_1 = 0,  MAGES_GUILD_2, MAGES_GUILD_3,     MAGES_GUILD_4,   MAGES_GUILD_5,
 		TAVERN,         SHIPYARD,      FORT,              CITADEL,         CASTLE,
 		VILLAGE_HALL,   TOWN_HALL,     CITY_HALL,         CAPITOL,         MARKETPLACE,

+ 10 - 9
lib/mapping/MapFormatH3M.cpp

@@ -2086,7 +2086,7 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID, const int3 & position)
 
 std::set<BuildingID> CMapLoaderH3M::convertBuildings(const std::set<BuildingID> & h3m, int castleID, bool addAuxiliary) const
 {
-	std::map<int, BuildingID> mapa;
+	std::map<int, BuildingID> helperMap;
 	std::set<BuildingID> ret;
 
 	// Note: this file is parsed many times.
@@ -2098,23 +2098,24 @@ std::set<BuildingID> CMapLoaderH3M::convertBuildings(const std::set<BuildingID>
 
 		if (town == castleID || town == -1)
 		{
-			mapa[static_cast<int>(entry["h3"].Float())] = BuildingID(static_cast<si32>(entry["vcmi"].Float()));
+			helperMap[static_cast<int>(entry["h3"].Float())] = BuildingID(static_cast<si32>(entry["vcmi"].Float()));
 		}
 	}
 
 	for(const auto & elem : h3m)
 	{
-		if(mapa[elem] >= 0)
+		if(helperMap[elem] >= BuildingID::FIRST_REGULAR_ID)
 		{
-			ret.insert(mapa[elem]);
+			ret.insert(helperMap[elem]);
 		}
-		// horde buildings
-		else if(mapa[elem] >= (-GameConstants::CREATURES_PER_TOWN))
+		// horde buildings use indexes from -1 to -5, where creature level is 1 to 5
+		else if(helperMap[elem] >= (-GameConstants::CREATURES_PER_TOWN))
 		{
-			int level = (mapa[elem]);
+			int level = (helperMap[elem]);
 
-			//(-30)..(-36) - horde buildings (for game loading only), don't see other way to handle hordes in random towns
-			ret.insert(BuildingID(level - 30));
+			//(-30)..(-36) - horde buildings (for game loading only)
+			//They will be replaced in CGameState::initTowns()
+			ret.insert(BuildingID(level + BuildingID::HORDE_BUILDING_CONVERTER)); //-1 => -30
 		}
 		else
 		{