Browse Source

Bugfixing, game can finally load to main menu without crash

Ivan Savenko 11 năm trước cách đây
mục cha
commit
7e057b6df8

+ 1 - 1
config/schemas/object.json

@@ -19,7 +19,7 @@
 		},
 
 		"base": {
-			"$ref" : "vcmi:objectType"
+			"type" : "object"
 		},
 		"types": {
 			"type":"object",

+ 1 - 1
config/schemas/objectType.json

@@ -15,7 +15,7 @@
 		},
 
 		"base": {
-			"$ref" : "vcmi:objectTemplate"
+			"type" : "object"
 		},
 		"types": {
 			"type":"object",

+ 5 - 6
lib/CArtHandler.cpp

@@ -647,19 +647,18 @@ void CArtHandler::afterLoadFinalization()
 		}
 	}
 
-	//Note: "10" is used here because H3 text files don't define any template for art with ID 0
-	ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, 10)->getTemplates().front();
 	for (CArtifact * art : artifacts)
 	{
+		VLC->objtypeh->createObject(art->Name(), JsonNode(), Obj::ARTIFACT, art->id.num);
+
 		if (!art->advMapDef.empty())
 		{
-			base.animationFile = art->advMapDef;
-			base.subid = art->id;
+			JsonNode templ;
+			templ["animation"].String() = art->advMapDef;
 
 			// add new template.
 			// Necessary for objects added via mods that don't have any templates in H3
-			VLC->objtypeh->createObject(art->Name(), JsonNode(), Obj::ARTIFACT, art->id.num);
-			VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, art->id)->addTemplate(base);
+			VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, art->id)->addTemplate(templ);
 		}
 	}
 }

+ 4 - 7
lib/CCreatureHandler.cpp

@@ -1114,17 +1114,14 @@ void CCreatureHandler::buildBonusTreeForTiers()
 
 void CCreatureHandler::afterLoadFinalization()
 {
-	ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::MONSTER, 0)->getTemplates().front();
 	for (CCreature * crea : creatures)
 	{
+		VLC->objtypeh->createObject(crea->nameSing, JsonNode(), Obj::MONSTER, crea->idNumber.num);
 		if (!crea->advMapDef.empty())
 		{
-			base.animationFile = crea->advMapDef;
-			base.subid = crea->idNumber;
-
-			// replace existing (if any) and add new template.
-			// Necessary for objects added via mods that don't have any templates in H3
-			VLC->objtypeh->getHandlerFor(Obj::MONSTER, crea->idNumber)->addTemplate(base);
+			JsonNode templ;
+			templ["animation"].String() = crea->advMapDef;
+			VLC->objtypeh->getHandlerFor(Obj::MONSTER, crea->idNumber)->addTemplate(templ);
 		}
 	}
 }

+ 7 - 7
lib/CHeroHandler.cpp

@@ -231,15 +231,15 @@ void CHeroClassHandler::afterLoadFinalization()
 		}
 	}
 
-	ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::HERO, 0)->getTemplates().front();
 	for (CHeroClass * hc : heroClasses)
 	{
-		base.animationFile = hc->imageMapMale;
-		base.subid = hc->id;
-
-		// replace existing (if any) and add new template.
-		// Necessary for objects added via mods that don't have any templates in H3
-		VLC->objtypeh->getHandlerFor(Obj::HERO, base.subid)->addTemplate(base);
+		VLC->objtypeh->createObject(hc->identifier, JsonNode(), Obj::HERO, hc->id);
+		if (!hc->imageMapMale.empty())
+		{
+			JsonNode templ;
+			templ["animation"].String() = hc->imageMapMale;
+			VLC->objtypeh->getHandlerFor(Obj::HERO, hc->id)->addTemplate(templ);
+		}
 	}
 }
 

+ 27 - 2
lib/CObjectClassesHandler.cpp

@@ -444,7 +444,7 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai
 	auto handler = handlerConstructors.at(obj->handlerName)();
 	handler->init(entry);
 
-	si32 id = selectNextID(entry["index"], obj->objects, 256);
+	si32 id = selectNextID(entry["index"], obj->objects, 1000);
 	handler->setType(obj->id, id);
 
 	if (handler->getTemplates().empty())
@@ -517,6 +517,18 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(si32 type, si32 subtype)
 	return nullptr;
 }
 
+void CObjectClassesHandler::beforeValidate(JsonNode & object)
+{
+	for (auto & entry : object["types"].Struct())
+	{
+		JsonUtils::inherit(entry.second, object["base"]);
+		for (auto & templ : entry.second["templates"].Struct())
+		{
+			JsonUtils::inherit(templ.second, entry.second["base"]);
+		}
+	}
+}
+
 void CObjectClassesHandler::afterLoadFinalization()
 {
 	legacyTemplates.clear(); // whatever left there is no longer needed
@@ -555,11 +567,24 @@ bool AObjectTypeHandler::objectFilter(const CGObjectInstance *, const ObjectTemp
 	return true; // by default - accept all.
 }
 
-void AObjectTypeHandler::addTemplate(const ObjectTemplate & templ)
+void AObjectTypeHandler::addTemplate(ObjectTemplate templ)
 {
+	templ.id = Obj(type);
+	templ.subid = subtype;
 	templates.push_back(templ);
 }
 
+void AObjectTypeHandler::addTemplate(JsonNode config)
+{
+	JsonUtils::inherit(config, base);
+	ObjectTemplate tmpl;
+	tmpl.id = Obj(type);
+	tmpl.subid = subtype;
+	tmpl.stringID = ""; // TODO?
+	tmpl.readJson(config);
+	addTemplate(tmpl);
+}
+
 std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const
 {
 	return templates;

+ 8 - 6
lib/CObjectClassesHandler.h

@@ -118,7 +118,8 @@ public:
 	/// loads templates from Json structure using fields "base" and "templates"
 	virtual void init(const JsonNode & input);
 
-	void addTemplate(const ObjectTemplate & templ);
+	void addTemplate(ObjectTemplate templ);
+	void addTemplate(JsonNode config);
 
 	/// returns all templates, without any filters
 	std::vector<ObjectTemplate> getTemplates() const;
@@ -207,16 +208,17 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
 public:
 	CObjectClassesHandler();
 
-	virtual std::vector<JsonNode> loadLegacyData(size_t dataSize);
+	std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
 
-	virtual void loadObject(std::string scope, std::string name, const JsonNode & data);
-	virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index);
+	void loadObject(std::string scope, std::string name, const JsonNode & data) override;
+	void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
 
 	void createObject(std::string name, JsonNode config, si32 ID, boost::optional<si32> subID = boost::optional<si32>());
 
-	virtual void afterLoadFinalization();
+	void beforeValidate(JsonNode & object) override;
+	void afterLoadFinalization() override;
 
-	virtual std::vector<bool> getDefaultAllowed() const;
+	std::vector<bool> getDefaultAllowed() const override;
 
 	/// returns handler for specified object (ID-based). ObjectHandler keeps ownership
 	TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const;

+ 15 - 15
lib/CTownHandler.cpp

@@ -759,31 +759,31 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod
 void CTownHandler::afterLoadFinalization()
 {
 	initializeRequirements();
-	ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::TOWN, 0)->getTemplates().front();
 	for (CFaction * fact : factions)
 	{
 		if (fact->town)
 		{
-			base.animationFile = fact->town->clientInfo.advMapCastle;
-			base.subid = fact->index;
-
-			// replace existing (if any) and add new template.
-			// Necessary for objects added via mods that don't have any templates in H3
-			VLC->objtypeh->getHandlerFor(Obj::TOWN, fact->index)->addTemplate(base);
+			VLC->objtypeh->createObject(fact->identifier, JsonNode(), Obj::TOWN, fact->index);
+			if (!fact->town->clientInfo.advMapCastle.empty())
+			{
+				JsonNode templ;
+				templ["animation"].String() = fact->town->clientInfo.advMapCastle;
+				VLC->objtypeh->getHandlerFor(Obj::TOWN, fact->index)->addTemplate(templ);
+			}
 
 			assert(fact->town->dwellings.size() == fact->town->dwellingNames.size());
 			for (size_t i=0; i<fact->town->dwellings.size(); i++)
 			{
-				ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::CREATURE_GENERATOR1, 0)->getTemplates().front();
-
 				//both unupgraded and upgraded get same dwelling
-				 for (auto cre : fact->town->creatures[i])
-				 {
-					base.subid = 80 + cre;
-					base.animationFile = fact->town->dwellings[i];
+				for (auto cre : fact->town->creatures[i])
+				{
 					if (VLC->objh->cregens.count(cre) == 0)
 					{
-						VLC->objtypeh->getHandlerFor(Obj::CREATURE_GENERATOR1, 80 + cre)->addTemplate(base);
+						JsonNode templ;
+						templ["animation"].String() = fact->town->dwellings[i];
+
+						VLC->objtypeh->createObject("", JsonNode(), Obj::CREATURE_GENERATOR1, 80 + cre);
+						VLC->objtypeh->getHandlerFor(Obj::CREATURE_GENERATOR1, 80 + cre)->addTemplate(templ);
 						VLC->objh->cregens[80 + cre] = cre; //map of dwelling -> creature id
 					}
 				 }
@@ -823,4 +823,4 @@ std::set<TFaction> CTownHandler::getAllowedFactions() const
 			allowedFactions.insert(i);
 
 	return allowedFactions;
-}
+}