From b5160acbac2f531a6f1bc8a93c5c27a4e0a6c3ee Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 16 May 2014 23:50:02 +0300 Subject: [PATCH] Finalization of object type handler interface - updated code to use new interface - removed old DefObjHandler (todo - rename file) Summary: - most code but loading is now in place - type names may deserve improvements (some of them are too similar) - still barely compiles and not tested --- client/CGameInfo.cpp | 2 +- client/CGameInfo.h | 5 +- lib/CArtHandler.cpp | 7 ++- lib/CCreatureHandler.cpp | 5 +- lib/CDefObjInfoHandler.cpp | 106 +++++++++++++++++++------------------ lib/CDefObjInfoHandler.h | 84 ++++++++++++----------------- lib/CGameState.cpp | 24 +++++---- lib/CHeroHandler.cpp | 5 +- lib/CObjectConstructor.cpp | 92 ++++++++++++++++++-------------- lib/CObjectConstructor.h | 14 +---- lib/CObjectHandler.cpp | 8 +-- lib/CTownHandler.cpp | 9 ++-- lib/NetPacksLib.cpp | 4 +- lib/VCMI_Lib.cpp | 6 +-- lib/VCMI_Lib.h | 6 +-- lib/rmg/CMapGenerator.cpp | 2 +- 16 files changed, 184 insertions(+), 195 deletions(-) diff --git a/client/CGameInfo.cpp b/client/CGameInfo.cpp index 06786663f..cf2f596f0 100644 --- a/client/CGameInfo.cpp +++ b/client/CGameInfo.cpp @@ -31,5 +31,5 @@ void CGameInfo::setFromLib() heroh = VLC->heroh; objh = VLC->objh; spellh = VLC->spellh; - dobjinfo = VLC->dobjinfo; + objtypeh = VLC->objtypeh; } diff --git a/client/CGameInfo.h b/client/CGameInfo.h index 4ea111a62..f56429555 100644 --- a/client/CGameInfo.h +++ b/client/CGameInfo.h @@ -23,7 +23,7 @@ class CBuildingHandler; class CObjectHandler; class CSoundHandler; class CMusicHandler; -class CDefObjInfoHandler; +class CObjectTypesHandler; class CTownHandler; class CGeneralTextHandler; class CConsoleHandler; @@ -57,11 +57,10 @@ public: ConstTransitivePtr creh; ConstTransitivePtr spellh; ConstTransitivePtr objh; - ConstTransitivePtr dobjinfo; + ConstTransitivePtr objtypeh; CGeneralTextHandler * generaltexth; CMapHandler * mh; CTownHandler * townh; - //CTownHandler * townh; void setFromLib(); diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index f7c5393f8..e3008a582 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -648,7 +648,7 @@ 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->dobjinfo->pickCandidates(Obj::ARTIFACT, 10).front(); + ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, 10)->getTemplates().front(); for (CArtifact * art : artifacts) { if (!art->advMapDef.empty()) @@ -656,10 +656,9 @@ void CArtHandler::afterLoadFinalization() base.animationFile = art->advMapDef; base.subid = art->id; - // replace existing (if any) and add new template. + // add new template. // Necessary for objects added via mods that don't have any templates in H3 - VLC->dobjinfo->eraseAll(Obj::ARTIFACT, art->id); - VLC->dobjinfo->registerTemplate(base); + VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, art->id)->addTemplate(base); } } } diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index dfba235b8..3f8bd9397 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -1114,7 +1114,7 @@ void CCreatureHandler::buildBonusTreeForTiers() void CCreatureHandler::afterLoadFinalization() { - ObjectTemplate base = VLC->dobjinfo->pickCandidates(Obj::MONSTER, 0).front(); + ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::MONSTER, 0)->getTemplates().front(); for (CCreature * crea : creatures) { if (!crea->advMapDef.empty()) @@ -1124,8 +1124,7 @@ void CCreatureHandler::afterLoadFinalization() // replace existing (if any) and add new template. // Necessary for objects added via mods that don't have any templates in H3 - VLC->dobjinfo->eraseAll(Obj::MONSTER, crea->idNumber); - VLC->dobjinfo->registerTemplate(base); + VLC->objtypeh->getHandlerFor(Obj::MONSTER, crea->idNumber)->addTemplate(base); } } } diff --git a/lib/CDefObjInfoHandler.cpp b/lib/CDefObjInfoHandler.cpp index 04dbe3f75..b75ba812d 100644 --- a/lib/CDefObjInfoHandler.cpp +++ b/lib/CDefObjInfoHandler.cpp @@ -7,6 +7,7 @@ #include "GameConstants.h" #include "StringConstants.h" #include "CGeneralTextHandler.h" +#include "CObjectHandler.h" #include "CModHandler.h" #include "JsonNode.h" @@ -327,7 +328,7 @@ bool ObjectTemplate::canBePlacedAt(ETerrainType terrain) const { return allowedTerrains.count(terrain) != 0; } - +/* void CDefObjInfoHandler::readTextFile(std::string path) { CLegacyConfigParser parser(path); @@ -347,81 +348,82 @@ CDefObjInfoHandler::CDefObjInfoHandler() { readTextFile("Data/Objects.txt"); readTextFile("Data/Heroes.txt"); -/* - // TODO: merge into modding system - JsonNode node = JsonUtils::assembleFromFiles("config/objectTemplates.json"); - node.setMeta("core"); - std::vector newTemplates; - newTemplates.reserve(node.Struct().size()); - - // load all new templates - for (auto & entry : node.Struct()) - { - JsonUtils::validate(entry.second, "vcmi:objectTemplate", entry.first); - - ObjectTemplate templ; - templ.stringID = entry.first; - templ.readJson(entry.second); - newTemplates.push_back(templ); - } - - // erase old ones to avoid conflicts - for (auto & entry : newTemplates) - eraseAll(entry.id, entry.subid); - - // merge new templates into storage - objects.insert(objects.end(), newTemplates.begin(), newTemplates.end()); +} */ +void CObjectTypesHandler::init() +{ + } -void CDefObjInfoHandler::eraseAll(Obj type, si32 subtype) +TObjectTypeHandler CObjectTypesHandler::getHandlerFor(si32 type, si32 subtype) const { - auto it = std::remove_if(objects.begin(), objects.end(), [&](const ObjectTemplate & obj) + if (objectTypes.count(type)) { - return obj.id == type && obj.subid == subtype; - }); - objects.erase(it, objects.end()); + if (objectTypes.at(type).count(subtype)) + return objectTypes.at(type).at(subtype); + } + assert(0); // FIXME: throw error? + return nullptr; } -void CDefObjInfoHandler::registerTemplate(ObjectTemplate obj) +void AObjectTypeHandler::init(si32 type, si32 subtype) { - objects.push_back(obj); + this->type = type; + this->subtype = subtype; } -std::vector CDefObjInfoHandler::pickCandidates(Obj type, si32 subtype) const +void AObjectTypeHandler::load(const JsonNode & input) { - std::vector ret; - - std::copy_if(objects.begin(), objects.end(), std::back_inserter(ret), [&](const ObjectTemplate & obj) + for (auto entry : input["templates"].Struct()) { - return obj.id == type && obj.subid == subtype; - }); - if (ret.empty()) - logGlobal->errorStream() << "Failed to find template for " << type << ":" << subtype; + JsonNode data = input["base"]; + JsonUtils::merge(data, entry.second); - assert(!ret.empty()); // Can't create object of this type/subtype - return ret; + ObjectTemplate tmpl; + tmpl.id = Obj(type); + tmpl.subid = subtype; + tmpl.stringID = entry.first; // FIXME: create "fullID" - type.object.template? + tmpl.readJson(data); + templates.push_back(tmpl); + } } -std::vector CDefObjInfoHandler::pickCandidates(Obj type, si32 subtype, ETerrainType terrain) const +bool AObjectTypeHandler::objectFilter(const CGObjectInstance *, const ObjectTemplate &) const { - std::vector ret = pickCandidates(type, subtype); + return true; // by default - accept all. +} + +void AObjectTypeHandler::addTemplate(const ObjectTemplate & templ) +{ + templates.push_back(templ); +} + +std::vector AObjectTypeHandler::getTemplates() const +{ + return templates; +} + +std::vector AObjectTypeHandler::getTemplates(si32 terrainType) const// FIXME: replace with ETerrainType +{ + std::vector ret = getTemplates(); std::vector filtered; std::copy_if(ret.begin(), ret.end(), std::back_inserter(filtered), [&](const ObjectTemplate & obj) { - return obj.canBePlacedAt(terrain); + return obj.canBePlacedAt(ETerrainType(terrainType)); }); // it is possible that there are no templates usable on specific terrain. In this case - return list before filtering return filtered.empty() ? ret : filtered; } -std::vector CDefObjInfoHandler::pickCandidates(Obj type, si32 subtype, ETerrainType terrain, std::function filter) const +ObjectTemplate AObjectTypeHandler::selectTemplate(si32 terrainType, CGObjectInstance * object) const { - std::vector ret = pickCandidates(type, subtype, terrain); - std::vector filtered; - - std::copy_if(ret.begin(), ret.end(), std::back_inserter(filtered), filter); - // it is possible that there are no templates usable on specific terrain. In this case - return list before filtering - return filtered.empty() ? ret : filtered; + std::vector ret = getTemplates(terrainType); + for (auto & tmpl : ret) + { + if (objectFilter(object, tmpl)) + return tmpl; + } + // FIXME: no matches found. Warn? Ask for torches? Die? + return ret.front(); } diff --git a/lib/CDefObjInfoHandler.h b/lib/CDefObjInfoHandler.h index d5c05de48..f32486a11 100644 --- a/lib/CDefObjInfoHandler.h +++ b/lib/CDefObjInfoHandler.h @@ -78,37 +78,6 @@ public: } }; -class DLL_LINKAGE CDefObjInfoHandler -{ - /// list of all object templates loaded from text files - /// actual object have ObjectTemplate as member "appearance" - std::vector objects; - - /// reads one of H3 text files that contain object templates description - void readTextFile(std::string path); -public: - - CDefObjInfoHandler(); - - /// Erases all templates with given type/subtype - void eraseAll(Obj type, si32 subtype); - - /// Add new template into the list - void registerTemplate(ObjectTemplate obj); - - /// picks all possible candidates for specific pair - std::vector pickCandidates(Obj type, si32 subtype) const; - /// picks all candidates for and of possible - also filters them by terrain - std::vector pickCandidates(Obj type, si32 subtype, ETerrainType terrain) const; - /// as above, but also filters out templates that are not applicable according to accepted test - std::vector pickCandidates(Obj type, si32 subtype, ETerrainType terrain, std::function filter) const; - - template void serialize(Handler &h, const int version) - { - h & objects; - } -}; - class IObjectInfo { public: @@ -130,40 +99,57 @@ public: class CGObjectInstance; -class IObjectTypesHandler +class AObjectTypeHandler { + si32 type; + si32 subtype; + + std::vector templates; +protected: + void init(si32 type, si32 subtype); + + /// loads templates from Json structure using fields "base" and "templates" + void load(const JsonNode & input); + + virtual bool objectFilter(const CGObjectInstance *, const ObjectTemplate &) const; public: - virtual std::vector getTemplates(si32 type, si32 subType) const = 0; + void addTemplate(const ObjectTemplate & templ); + + /// returns all templates, without any filters + std::vector getTemplates() const; + + /// returns all templates that can be placed on specific terrain type + std::vector getTemplates(si32 terrainType) const; + + /// returns template suitable for object. If returned template is not equal to current one + /// it must be replaced with this one (and properly updated on all clients) + ObjectTemplate selectTemplate(si32 terrainType, CGObjectInstance * object) const; + virtual CGObjectInstance * create(ObjectTemplate tmpl) const = 0; - virtual bool handlesID(ObjectTemplate tmpl) const = 0; - virtual void configureObject(CGObjectInstance * object) const = 0; virtual const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const = 0; }; -typedef std::shared_ptr TObjectTypeHandler; +typedef std::shared_ptr TObjectTypeHandler; -class CObjectGroupsHandler +class CObjectTypesHandler { - /// list of object handlers, each of them handles 1 or more object type - std::vector objectTypes; + /// list of object handlers, each of them handles only one type + std::map > objectTypes; public: + void init(); + /// returns handler for specified object (ID-based). ObjectHandler keeps ownership - IObjectTypesHandler * getHandlerFor(ObjectTemplate tmpl) const; + TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const; - /// creates object based on specified template - CGObjectInstance * createObject(ObjectTemplate tmpl); - - template - CObjectClass * createObjectTyped(ObjectTemplate tmpl) + template void serialize(Handler &h, const int version) { - auto objInst = createObject(tmpl); - auto objClass = dynamic_cast(objInst); - assert(objClass); - return objClass; + //h & objects; + if (!h.saving) + init(); // TODO: implement serialization } }; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 5c87ec1b6..1447c65cd 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -342,9 +342,11 @@ static CGObjectInstance * createObject(Obj id, int subid, int3 pos, PlayerColor switch(id) { case Obj::HERO: - nobj = new CGHeroInstance(); - nobj->appearance = VLC->dobjinfo->pickCandidates(id, VLC->heroh->heroes[subid]->heroClass->id).front(); - break; + { + auto handler = VLC->objtypeh->getHandlerFor(id, VLC->heroh->heroes[subid]->heroClass->id); + nobj = handler->create(handler->getTemplates().front()); + break; + } case Obj::TOWN: nobj = new CGTownInstance; break; @@ -357,7 +359,7 @@ static CGObjectInstance * createObject(Obj id, int subid, int3 pos, PlayerColor nobj->pos = pos; nobj->tempOwner = owner; if (id != Obj::HERO) - nobj->appearance = VLC->dobjinfo->pickCandidates(id, subid).front(); + nobj->appearance = VLC->objtypeh->getHandlerFor(id, subid)->getTemplates().front(); return nobj; } @@ -654,7 +656,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur) const TerrainTile &tile = map->getTile(cur->visitablePos()); CGTownInstance *t = dynamic_cast(cur); t->town = VLC->townh->factions[t->subID]->town; - t->appearance = VLC->dobjinfo->pickCandidates(Obj::TOWN, t->subID, tile.terType).front(); + t->appearance = VLC->objtypeh->getHandlerFor(Obj::TOWN, t->subID)->selectTemplate(tile.terType, t); t->updateAppearance(); } return; @@ -675,12 +677,12 @@ void CGameState::randomizeObject(CGObjectInstance *cur) { const TerrainTile &tile = map->getTile(cur->visitablePos()); CGTownInstance *t = dynamic_cast(cur); - if(!t) {logGlobal->warnStream()<<"Wrong random town at "<pos; return;} + if(!t) {logGlobal->warnStream()<<"Wrong random town at "<pos; return;} cur->ID = ran.first; cur->subID = ran.second; //FIXME: copy-pasted from above t->town = VLC->townh->factions[t->subID]->town; - t->appearance = VLC->dobjinfo->pickCandidates(Obj::TOWN,t->subID, tile.terType).front(); + t->appearance = VLC->objtypeh->getHandlerFor(Obj::TOWN, t->subID)->selectTemplate(tile.terType, t); t->updateAppearance(); t->randomizeArmy(t->subID); @@ -693,7 +695,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur) ran.second != cur->appearance.subid) { const TerrainTile &tile = map->getTile(cur->visitablePos()); - cur->appearance = VLC->dobjinfo->pickCandidates(Obj(ran.first),ran.second, tile.terType).front(); + cur->appearance = VLC->objtypeh->getHandlerFor(ran.first, ran.second)->selectTemplate(tile.terType, cur); } } //we have to replace normal random object @@ -3315,9 +3317,9 @@ void CPathfinder::calculatePaths(int3 src /*= int3(-1,-1,-1)*/, int movement /*= int maxMovePointsLand = hero->maxMovePoints(true); int maxMovePointsWater = hero->maxMovePoints(false); - auto maxMovePoints = [&](CGPathNode *cp) -> int - { - return cp->land ? maxMovePointsLand : maxMovePointsWater; + auto maxMovePoints = [&](CGPathNode *cp) -> int + { + return cp->land ? maxMovePointsLand : maxMovePointsWater; }; out.hero = hero; diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 77f990943..8e53b3ea6 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -229,7 +229,7 @@ void CHeroClassHandler::afterLoadFinalization() } } - ObjectTemplate base = VLC->dobjinfo->pickCandidates(Obj::HERO, 0).front(); + ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::HERO, 0)->getTemplates().front(); for (CHeroClass * hc : heroClasses) { base.animationFile = hc->imageMapMale; @@ -237,8 +237,7 @@ void CHeroClassHandler::afterLoadFinalization() // replace existing (if any) and add new template. // Necessary for objects added via mods that don't have any templates in H3 - VLC->dobjinfo->eraseAll(Obj::HERO, hc->id); - VLC->dobjinfo->registerTemplate(base); + VLC->objtypeh->getHandlerFor(Obj::HERO, base.subid)->addTemplate(base); } } diff --git a/lib/CObjectConstructor.cpp b/lib/CObjectConstructor.cpp index a5a5fb198..3ce38894b 100644 --- a/lib/CObjectConstructor.cpp +++ b/lib/CObjectConstructor.cpp @@ -11,64 +11,78 @@ * */ +void CRandomRewardObjectInfo::init(const JsonNode & objectConfig) +{ + parameters = objectConfig; +} + +void CRandomRewardObjectInfo::configureObject(CObjectWithReward * object) const +{ + +} + +bool CRandomRewardObjectInfo::givesResources() const +{ +} + +bool CRandomRewardObjectInfo::givesExperience() const +{ +} + +bool CRandomRewardObjectInfo::givesMana() const +{ +} + +bool CRandomRewardObjectInfo::givesMovement() const +{ +} + +bool CRandomRewardObjectInfo::givesPrimarySkills() const +{ +} + +bool CRandomRewardObjectInfo::givesSecondarySkills() const +{ +} + +bool CRandomRewardObjectInfo::givesArtifacts() const +{ +} + +bool CRandomRewardObjectInfo::givesCreatures() const +{ +} + +bool CRandomRewardObjectInfo::givesSpells() const +{ +} + +bool CRandomRewardObjectInfo::givesBonuses() const +{ +} + CObjectWithRewardConstructor::CObjectWithRewardConstructor() { } void CObjectWithRewardConstructor::init(const JsonNode & config) { - int id = config["id"].Float(); - std::string name = config["name"].String(); - for (auto & entry : config["types"].Struct()) // for each object type - { - JsonNode typeConf = entry.second; - - int subID = typeConf["id"].Float(); - - objectInfos[id][subID].info.init(typeConf["properties"]); - for (auto entry : typeConf["templates"].Struct()) - { - ObjectTemplate tmpl; - tmpl.id = Obj(id); - tmpl.subid = subID; - tmpl.readJson(entry.second); - objectInfos[id][subID].templates.push_back(tmpl); - } - } -} - -std::vector CObjectWithRewardConstructor::getTemplates(si32 type, si32 subType) const -{ - assert(handlesID(type, subtype)); - return objectInfos.at(type).at(subType).templates; + objectInfo.init(config); } CGObjectInstance * CObjectWithRewardConstructor::create(ObjectTemplate tmpl) const { - assert(handlesID(tmpl)); auto ret = new CObjectWithReward(); ret->appearance = tmpl; return ret; } -bool CObjectWithRewardConstructor::handlesID(si32 id, si32 subID) const -{ - return objectInfos.count(id) && objectInfos.at(id).count(subID); -} - -bool CObjectWithRewardConstructor::handlesID(ObjectTemplate tmpl) const -{ - return handlesID(tmpl.id, tmpl.subid); -} - void CObjectWithRewardConstructor::configureObject(CGObjectInstance * object) const { - assert(handlesID(object->appearance)); - objectInfos.at(object->ID).at(object->subID).info.configureObject(dynamic_cast(object)); + objectInfo.configureObject(dynamic_cast(object)); } const IObjectInfo * CObjectWithRewardConstructor::getObjectInfo(ObjectTemplate tmpl) const { - assert(handlesID(tmpl)); - return &objectInfos.at(tmpl.id).at(tmpl.subid).info; + return &objectInfo; } diff --git a/lib/CObjectConstructor.h b/lib/CObjectConstructor.h index ceef728b2..bec5d7208 100644 --- a/lib/CObjectConstructor.h +++ b/lib/CObjectConstructor.h @@ -41,26 +41,16 @@ public: void init(const JsonNode & objectConfig); }; -class CObjectWithRewardConstructor : public IObjectTypesHandler +class CObjectWithRewardConstructor : public AObjectTypeHandler { - struct ObjectInfo - { - CRandomRewardObjectInfo info; - std::vector templates; - }; - std::map > objectInfos; + CRandomRewardObjectInfo objectInfo; public: CObjectWithRewardConstructor(); void init(const JsonNode & config); - std::vector getTemplates(si32 type, si32 subType) const override; - CGObjectInstance * create(ObjectTemplate tmpl) const override; - bool handlesID(si32 id, si32 subID) const; - bool handlesID(ObjectTemplate tmpl) const override; - void configureObject(CGObjectInstance * object) const override; const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const override; diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 096be0312..f4c118f95 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -727,7 +727,7 @@ void CGHeroInstance::initHero() type = VLC->heroh->heroes[subID]; if (ID == Obj::HERO) - appearance = VLC->dobjinfo->pickCandidates(Obj::HERO, type->heroClass->id).front(); + appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->id)->getTemplates().front(); if(!vstd::contains(spells, SpellID::PRESET)) //hero starts with a spell { @@ -3493,7 +3493,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const if(vstd::contains(objs,Obj::MONOLITH2) && vstd::contains(objs[Obj::MONOLITH2],subID) && objs[Obj::MONOLITH2][subID].size()) destinationid = objs[Obj::MONOLITH2][subID][rand()%objs[Obj::MONOLITH2][subID].size()]; else - logGlobal->warnStream() << "Cannot find corresponding exit monolith for "<< id; + logGlobal->warnStream() << "Cannot find corresponding exit monolith for "<< id; break; case Obj::MONOLITH3://two way monolith - pick any other one case Obj::WHIRLPOOL: //Whirlpool @@ -3530,7 +3530,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const } } else - logGlobal->warnStream() << "Cannot find corresponding exit monolith for "<< id; + logGlobal->warnStream() << "Cannot find corresponding exit monolith for "<< id; break; case Obj::SUBTERRANEAN_GATE: //find nearest subterranean gate on the other level { @@ -3544,7 +3544,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const } if(destinationid == ObjectInstanceID()) { - logGlobal->warnStream() << "Cannot find exit... (obj at " << pos << ") :( "; + logGlobal->warnStream() << "Cannot find exit... (obj at " << pos << ") :( "; return; } if (ID == Obj::WHIRLPOOL) diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index 0f1d18017..0846efdd4 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -711,7 +711,7 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod void CTownHandler::afterLoadFinalization() { initializeRequirements(); - ObjectTemplate base = VLC->dobjinfo->pickCandidates(Obj::TOWN, 0).front(); + ObjectTemplate base = VLC->objtypeh->getHandlerFor(Obj::TOWN, 0)->getTemplates().front(); for (CFaction * fact : factions) { if (fact->town) @@ -721,13 +721,12 @@ void CTownHandler::afterLoadFinalization() // replace existing (if any) and add new template. // Necessary for objects added via mods that don't have any templates in H3 - VLC->dobjinfo->eraseAll(Obj::TOWN, fact->index); - VLC->dobjinfo->registerTemplate(base); + VLC->objtypeh->getHandlerFor(Obj::TOWN, fact->index)->addTemplate(base); assert(fact->town->dwellings.size() == fact->town->dwellingNames.size()); for (size_t i=0; itown->dwellings.size(); i++) { - ObjectTemplate base = VLC->dobjinfo->pickCandidates(Obj::CREATURE_GENERATOR1, 0).front(); + 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]) @@ -736,7 +735,7 @@ void CTownHandler::afterLoadFinalization() base.animationFile = fact->town->dwellings[i]; if (VLC->objh->cregens.count(cre) == 0) { - VLC->dobjinfo->registerTemplate(base); + VLC->objtypeh->getHandlerFor(Obj::CREATURE_GENERATOR1, 80 + cre)->addTemplate(base); VLC->objh->cregens[80 + cre] = cre; //map of dwelling -> creature id } } diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 339b4c913..8ee35e925 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -582,7 +582,7 @@ DLL_LINKAGE void GiveHero::applyGs( CGameState *gs ) //bonus system h->detachFrom(&gs->globalEffects); h->attachTo(gs->getPlayer(player)); - h->appearance = VLC->dobjinfo->pickCandidates(Obj::HERO, h->type->heroClass->id).front(); + h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->id)->getTemplates().front(); gs->map->removeBlockVisTiles(h,true); h->setOwner(player); @@ -623,7 +623,7 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs ) o->subID = subID; o->pos = pos; const TerrainTile &t = gs->map->getTile(pos); - o->appearance = VLC->dobjinfo->pickCandidates(o->ID, o->subID, t.terType).front(); + o->appearance = VLC->objtypeh->getHandlerFor(o->ID, o->subID)->selectTemplate(t.terType, o); id = o->id = ObjectInstanceID(gs->map->objects.size()); o->hoverName = VLC->generaltexth->names[ID]; diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index 8c6af64b3..ab644757a 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -109,7 +109,7 @@ void LibClasses::init() createHandler(objh, "Object", pomtime); - createHandler(dobjinfo, "Def information", pomtime); + createHandler(objtypeh, "Object types information", pomtime); createHandler(spellh, "Spell", pomtime); @@ -135,7 +135,7 @@ void LibClasses::clear() delete creh; delete townh; delete objh; - delete dobjinfo; + delete objtypeh; delete spellh; delete modh; delete bth; @@ -152,7 +152,7 @@ void LibClasses::makeNull() creh = nullptr; townh = nullptr; objh = nullptr; - dobjinfo = nullptr; + objtypeh = nullptr; spellh = nullptr; modh = nullptr; bth = nullptr; diff --git a/lib/VCMI_Lib.h b/lib/VCMI_Lib.h index b1b52b9bf..cf728fe55 100644 --- a/lib/VCMI_Lib.h +++ b/lib/VCMI_Lib.h @@ -16,7 +16,7 @@ class CCreatureHandler; class CSpellHandler; class CBuildingHandler; class CObjectHandler; -class CDefObjInfoHandler; +class CObjectTypesHandler; class CTownHandler; class CGeneralTextHandler; class CModHandler; @@ -42,7 +42,7 @@ public: CCreatureHandler * creh; CSpellHandler * spellh; CObjectHandler * objh; - CDefObjInfoHandler * dobjinfo; + CObjectTypesHandler * objtypeh; CTownHandler * townh; CGeneralTextHandler * generaltexth; CModHandler * modh; @@ -60,7 +60,7 @@ public: template void serialize(Handler &h, const int version) { - h & heroh & arth & creh & townh & objh & dobjinfo & spellh & modh & IS_AI_ENABLED; + h & heroh & arth & creh & townh & objh & objtypeh & spellh & modh & IS_AI_ENABLED; h & bth; if(!h.saving) { diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 810e53fe2..771887765 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -166,7 +166,7 @@ void CMapGenerator::genTowns() } town->subID = townId; town->tempOwner = owner; - town->appearance = VLC->dobjinfo->pickCandidates(town->ID, town->subID, map->getTile(townPos[side]).terType).front(); + town->appearance = VLC->objtypeh->getHandlerFor(town->ID, town->subID)->selectTemplate(map->getTile(townPos[side]).terType, town); town->builtBuildings.insert(BuildingID::FORT); town->builtBuildings.insert(BuildingID::DEFAULT); editManager->insertObject(town, int3(townPos[side].x, townPos[side].y + (i / 2) * 5, 0));