Browse Source

Restore save compatibility

Ivan Savenko 1 year ago
parent
commit
f765f212bb

+ 18 - 2
lib/mapObjects/CGMarket.h

@@ -35,6 +35,19 @@ public:
 		h & static_cast<CGObjectInstance&>(*this);
 		h & static_cast<IMarket&>(*this);
 		h & marketEfficiency;
+		if (h.version < Handler::Version::NEW_MARKETS)
+		{
+			std::string speech;
+			std::string title;
+			h & speech;
+			h & title;
+		}
+	}
+
+	template <typename Handler> void serializeArtifactsAltar(Handler &h)
+	{
+		serialize(h);
+		IMarket::serializeArtifactsAltar(h);
 	}
 };
 
@@ -71,8 +84,11 @@ public:
 	{
 		h & static_cast<CGMarket&>(*this);
 		h & skills;
-		h & speech;
-		h & title;
+		if (h.version >= Handler::Version::NEW_MARKETS)
+		{
+			h & speech;
+			h & title;
+		}
 	}
 };
 

+ 8 - 0
lib/mapObjects/CGTownInstance.cpp

@@ -946,6 +946,14 @@ void CGTownInstance::addBuilding(const BuildingID & buildingID)
 	}
 }
 
+void CGTownInstance::postDeserializeMarketFix()
+{
+	// re-add all buildings to recreate existing market modes
+	auto buildingsBak = builtBuildings;
+	for (auto building : buildingsBak)
+		addBuilding(building);
+}
+
 void CGTownInstance::removeBuilding(const BuildingID & buildingID)
 {
 	if(!vstd::contains(builtBuildings, buildingID))

+ 7 - 1
lib/mapObjects/CGTownInstance.h

@@ -77,7 +77,9 @@ public:
 	template <typename Handler> void serialize(Handler &h)
 	{
 		h & static_cast<CGDwelling&>(*this);
-		h & static_cast<IMarket&>(*this);
+		if (h.version >= Handler::Version::NEW_MARKETS)
+			h & static_cast<IMarket&>(*this);
+
 		h & nameTextId;
 		h & built;
 		h & destroyed;
@@ -116,6 +118,9 @@ public:
 			town = faction ? faction->town : nullptr;
 		}
 
+		if (!h.saving && h.version < Handler::Version::NEW_MARKETS)
+			postDeserializeMarketFix();
+
 		h & townAndVis;
 		BONUS_TREE_DESERIALIZATION_FIX
 
@@ -135,6 +140,7 @@ public:
 	void updateMoraleBonusFromArmy() override;
 	void deserializationFix();
 	void postDeserialize();
+	void postDeserializeMarketFix();
 	void recreateBuildingsBonuses();
 	void setVisitingHero(CGHeroInstance *h);
 	void setGarrisonedHero(CGHeroInstance *h);

+ 12 - 2
lib/mapObjects/IMarket.h

@@ -42,8 +42,18 @@ public:
 	{
 		h & marketModes;
 
-		if(h.loadingGamestate && vstd::contains(marketModes, EMarketMode::ARTIFACT_EXP))
-			altarArtifactsStorage = std::make_shared<CArtifactSetAltar>();
+		if(vstd::contains(marketModes, EMarketMode::ARTIFACT_EXP))
+		{
+			if (!h.saving)
+				altarArtifactsStorage = std::make_shared<CArtifactSetAltar>();
+
+			h & *altarArtifactsStorage;
+		}
+	}
+
+	template <typename Handler> void serializeArtifactsAltar(Handler & h)
+	{
+		h & *altarArtifactsStorage;
 	}
 
 private:

+ 2 - 1
lib/serializer/ESerializationVersion.h

@@ -65,6 +65,7 @@ enum class ESerializationVersion : int32_t
 	EVENTS_PLAYER_SET, // 854 - map & town events use std::set instead of bitmask to store player list
 	NEW_TOWN_BUILDINGS, // 855 - old bonusing buildings have been removed
 	STATISTICS_SCREEN, // 856 - extent statistic functions
+	NEW_MARKETS, // 857 - reworked market classes
 
-	CURRENT = STATISTICS_SCREEN
+	CURRENT = NEW_MARKETS
 };

+ 0 - 1
lib/serializer/RegisterTypes.h

@@ -139,7 +139,6 @@ void registerTypes(Serializer &s)
 	s.template registerType<CArtifactInstance>(78);
 	s.template registerType<CObstacleInstance>(79);
 	s.template registerType<SpellCreatedObstacle>(80);
-	//s.template registerType<CGArtifactsAltar>(81);
 	s.template registerType<CPack>(82);
 	s.template registerType<PackageApplied>(84);
 	s.template registerType<SystemMessage>(85);

+ 10 - 0
lib/serializer/SerializerReflection.cpp

@@ -63,6 +63,15 @@ class SerializerCompatibilityBonusingBuilding final : public SerializerCompatibi
 	}
 };
 
+class SerializerCompatibilityArtifactsAltar final : public SerializerCompatibility<CGMarket, ESerializationVersion::NEW_MARKETS>
+{
+	void loadPtr(BinaryDeserializer &ar, IGameCallback * cb, Serializeable * data) const override
+	{
+		auto * realPtr = dynamic_cast<CGMarket *>(data);
+		realPtr->serializeArtifactsAltar(ar);
+	}
+};
+
 template<typename Type>
 void CSerializationApplier::registerType(uint16_t ID)
 {
@@ -76,6 +85,7 @@ CSerializationApplier::CSerializationApplier()
 
 	apps[54].reset(new SerializerCompatibilityBonusingBuilding);
 	apps[55].reset(new SerializerCompatibilityBonusingBuilding);
+	apps[81].reset(new SerializerCompatibilityArtifactsAltar);
 }
 
 CSerializationApplier & CSerializationApplier::getInstance()