1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Bugfixing, game can finally load to main menu without crash

This commit is contained in:
Ivan Savenko
2014-06-04 11:25:13 +03:00
parent 32b6568b65
commit 7e057b6df8
8 changed files with 68 additions and 45 deletions

View File

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

View File

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

View File

@@ -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) for (CArtifact * art : artifacts)
{ {
VLC->objtypeh->createObject(art->Name(), JsonNode(), Obj::ARTIFACT, art->id.num);
if (!art->advMapDef.empty()) if (!art->advMapDef.empty())
{ {
base.animationFile = art->advMapDef; JsonNode templ;
base.subid = art->id; templ["animation"].String() = art->advMapDef;
// add new template. // add new template.
// Necessary for objects added via mods that don't have any templates in H3 // 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(templ);
VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, art->id)->addTemplate(base);
} }
} }
} }

View File

@@ -1114,17 +1114,14 @@ void CCreatureHandler::buildBonusTreeForTiers()
void CCreatureHandler::afterLoadFinalization() void CCreatureHandler::afterLoadFinalization()
{ {
ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::MONSTER, 0)->getTemplates().front();
for (CCreature * crea : creatures) for (CCreature * crea : creatures)
{ {
VLC->objtypeh->createObject(crea->nameSing, JsonNode(), Obj::MONSTER, crea->idNumber.num);
if (!crea->advMapDef.empty()) if (!crea->advMapDef.empty())
{ {
base.animationFile = crea->advMapDef; JsonNode templ;
base.subid = crea->idNumber; templ["animation"].String() = crea->advMapDef;
VLC->objtypeh->getHandlerFor(Obj::MONSTER, crea->idNumber)->addTemplate(templ);
// 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);
} }
} }
} }

View File

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

View File

@@ -444,7 +444,7 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai
auto handler = handlerConstructors.at(obj->handlerName)(); auto handler = handlerConstructors.at(obj->handlerName)();
handler->init(entry); handler->init(entry);
si32 id = selectNextID(entry["index"], obj->objects, 256); si32 id = selectNextID(entry["index"], obj->objects, 1000);
handler->setType(obj->id, id); handler->setType(obj->id, id);
if (handler->getTemplates().empty()) if (handler->getTemplates().empty())
@@ -517,6 +517,18 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(si32 type, si32 subtype)
return nullptr; 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() void CObjectClassesHandler::afterLoadFinalization()
{ {
legacyTemplates.clear(); // whatever left there is no longer needed 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. 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); 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 std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const
{ {
return templates; return templates;

View File

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

View File

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