From 58661fc8ec765a40553d6cf6028c1df020e31ef1 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 8 Jun 2023 17:29:29 +0300 Subject: [PATCH] Moved DwellingInstanceConstructor to a new file --- cmake_modules/VCMI_lib.cmake | 2 + lib/CGameState.cpp | 2 +- .../CObjectClassesHandler.cpp | 3 +- .../CommonConstructors.cpp | 127 +-------------- .../CommonConstructors.h | 32 +--- .../DwellingInstanceConstructor.cpp | 146 ++++++++++++++++++ .../DwellingInstanceConstructor.h | 45 ++++++ lib/registerTypes/RegisterTypes.h | 3 +- lib/rmg/modificators/TreasurePlacer.cpp | 4 +- 9 files changed, 204 insertions(+), 160 deletions(-) create mode 100644 lib/mapObjectConstructors/DwellingInstanceConstructor.cpp create mode 100644 lib/mapObjectConstructors/DwellingInstanceConstructor.h diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index c7b52da26..01ab3c668 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/cmake_modules/VCMI_lib.cmake @@ -70,6 +70,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.cpp ${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.cpp ${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.cpp + ${MAIN_LIB_DIR}/mapObjectConstructors/DwellingInstanceConstructor.cpp ${MAIN_LIB_DIR}/mapObjectConstructors/HillFortInstanceConstructor.cpp ${MAIN_LIB_DIR}/mapObjectConstructors/ShipyardInstanceConstructor.cpp ${MAIN_LIB_DIR}/mapObjectConstructors/ShrineInstanceConstructor.cpp @@ -378,6 +379,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.h ${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.h ${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.h + ${MAIN_LIB_DIR}/mapObjectConstructors/DwellingInstanceConstructor.h ${MAIN_LIB_DIR}/mapObjectConstructors/HillFortInstanceConstructor.h ${MAIN_LIB_DIR}/mapObjectConstructors/IObjectInfo.h ${MAIN_LIB_DIR}/mapObjectConstructors/RandomMapInfo.h diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 1b810cfbe..f5fbb3f8f 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -621,7 +621,7 @@ std::pair CGameState::pickObject (CGObjectInstance *obj) auto dwellingIDs = VLC->objtypeh->knownSubObjects(primaryID); for (si32 entry : dwellingIDs) { - const auto * handler = dynamic_cast(VLC->objtypeh->getHandlerFor(primaryID, entry).get()); + const auto * handler = dynamic_cast(VLC->objtypeh->getHandlerFor(primaryID, entry).get()); if (handler->producesCreature(VLC->creh->objects[cid])) result = std::make_pair(primaryID, entry); diff --git a/lib/mapObjectConstructors/CObjectClassesHandler.cpp b/lib/mapObjectConstructors/CObjectClassesHandler.cpp index 71f47dbcd..fd24486c9 100644 --- a/lib/mapObjectConstructors/CObjectClassesHandler.cpp +++ b/lib/mapObjectConstructors/CObjectClassesHandler.cpp @@ -24,6 +24,7 @@ #include "../mapObjectConstructors/CBankInstanceConstructor.h" #include "../mapObjectConstructors/CRewardableConstructor.h" #include "../mapObjectConstructors/CommonConstructors.h" +#include "../mapObjectConstructors/DwellingInstanceConstructor.h" #include "../mapObjectConstructors/HillFortInstanceConstructor.h" #include "../mapObjectConstructors/ShipyardInstanceConstructor.h" #include "../mapObjectConstructors/ShrineInstanceConstructor.h" @@ -46,7 +47,7 @@ CObjectClassesHandler::CObjectClassesHandler() // list of all known handlers, hardcoded for now since the only way to add new objects is via C++ code //Note: should be in sync with registerTypesMapObjectTypes function SET_HANDLER_CLASS("configurable", CRewardableConstructor); - SET_HANDLER_CLASS("dwelling", CDwellingInstanceConstructor); + SET_HANDLER_CLASS("dwelling", DwellingInstanceConstructor); SET_HANDLER_CLASS("hero", CHeroInstanceConstructor); SET_HANDLER_CLASS("town", CTownInstanceConstructor); SET_HANDLER_CLASS("bank", CBankInstanceConstructor); diff --git a/lib/mapObjectConstructors/CommonConstructors.cpp b/lib/mapObjectConstructors/CommonConstructors.cpp index 8824a75bc..cef36448e 100644 --- a/lib/mapObjectConstructors/CommonConstructors.cpp +++ b/lib/mapObjectConstructors/CommonConstructors.cpp @@ -10,16 +10,16 @@ #include "StdInc.h" #include "CommonConstructors.h" -#include "../CCreatureHandler.h" #include "../CGeneralTextHandler.h" #include "../CHeroHandler.h" #include "../CModHandler.h" +#include "../CTownHandler.h" #include "../IGameCallback.h" #include "../JsonRandom.h" #include "../StringConstants.h" #include "../TerrainHandler.h" +#include "../VCMI_Lib.h" -#include "../mapObjects/CBank.h" #include "../mapObjects/CGHeroInstance.h" #include "../mapObjects/CGMarket.h" #include "../mapObjects/CGTownInstance.h" @@ -133,129 +133,6 @@ void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, CRandomG } -bool CDwellingInstanceConstructor::hasNameTextID() const -{ - return true; -} - -void CDwellingInstanceConstructor::initTypeData(const JsonNode & input) -{ - if (input.Struct().count("name") == 0) - logMod->warn("Dwelling %s missing name!", getJsonKey()); - - VLC->generaltexth->registerString( input.meta, getNameTextID(), input["name"].String()); - - const JsonVector & levels = input["creatures"].Vector(); - const auto totalLevels = levels.size(); - - availableCreatures.resize(totalLevels); - for(auto currentLevel = 0; currentLevel < totalLevels; currentLevel++) - { - const JsonVector & creaturesOnLevel = levels[currentLevel].Vector(); - const auto creaturesNumber = creaturesOnLevel.size(); - availableCreatures[currentLevel].resize(creaturesNumber); - - for(auto currentCreature = 0; currentCreature < creaturesNumber; currentCreature++) - { - VLC->modh->identifiers.requestIdentifier("creature", creaturesOnLevel[currentCreature], [=] (si32 index) - { - availableCreatures[currentLevel][currentCreature] = VLC->creh->objects[index]; - }); - } - assert(!availableCreatures[currentLevel].empty()); - } - guards = input["guards"]; -} - -bool CDwellingInstanceConstructor::objectFilter(const CGObjectInstance * obj, std::shared_ptr tmpl) const -{ - return false; -} - -void CDwellingInstanceConstructor::initializeObject(CGDwelling * obj) const -{ - obj->creatures.resize(availableCreatures.size()); - for(const auto & entry : availableCreatures) - { - for(const CCreature * cre : entry) - obj->creatures.back().second.push_back(cre->getId()); - } -} - -void CDwellingInstanceConstructor::randomizeObject(CGDwelling * object, CRandomGenerator &rng) const -{ - auto * dwelling = dynamic_cast(object); - - dwelling->creatures.clear(); - dwelling->creatures.reserve(availableCreatures.size()); - - for(const auto & entry : availableCreatures) - { - dwelling->creatures.resize(dwelling->creatures.size() + 1); - for(const CCreature * cre : entry) - dwelling->creatures.back().second.push_back(cre->getId()); - } - - bool guarded = false; //TODO: serialize for sanity - - if(guards.getType() == JsonNode::JsonType::DATA_BOOL) //simple switch - { - if(guards.Bool()) - { - guarded = true; - } - } - else if(guards.getType() == JsonNode::JsonType::DATA_VECTOR) //custom guards (eg. Elemental Conflux) - { - for(auto & stack : JsonRandom::loadCreatures(guards, rng)) - { - dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->getId(), stack.count)); - } - } - else //default condition - creatures are of level 5 or higher - { - for(auto creatureEntry : availableCreatures) - { - if(creatureEntry.at(0)->getLevel() >= 5) - { - guarded = true; - break; - } - } - } - - if(guarded) - { - for(auto creatureEntry : availableCreatures) - { - const CCreature * crea = creatureEntry.at(0); - dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(crea->getId(), crea->getGrowth() * 3)); - } - } -} - -bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) const -{ - for(const auto & entry : availableCreatures) - { - for(const CCreature * cre : entry) - if(crea == cre) - return true; - } - return false; -} - -std::vector CDwellingInstanceConstructor::getProducedCreatures() const -{ - std::vector creatures; //no idea why it's 2D, to be honest - for(const auto & entry : availableCreatures) - { - for(const CCreature * cre : entry) - creatures.push_back(cre); - } - return creatures; -} - void BoatInstanceConstructor::initTypeData(const JsonNode & input) { layer = EPathfindingLayer::SAIL; diff --git a/lib/mapObjectConstructors/CommonConstructors.h b/lib/mapObjectConstructors/CommonConstructors.h index a93f36943..7144596e6 100644 --- a/lib/mapObjectConstructors/CommonConstructors.h +++ b/lib/mapObjectConstructors/CommonConstructors.h @@ -9,18 +9,17 @@ */ #pragma once -#include "AObjectTypeHandler.h" #include "CDefaultObjectTypeHandler.h" - #include "../LogicalExpression.h" +#include "../mapObjects/MiscObjects.h" + VCMI_LIB_NAMESPACE_BEGIN class CGArtifact; class CGObjectInstance; class CGTownInstance; class CGHeroInstance; -class CGDwelling; class CGMarket; class CHeroClass; class CBank; @@ -82,33 +81,6 @@ public: } }; -class CDwellingInstanceConstructor : public CDefaultObjectTypeHandler -{ - std::vector> availableCreatures; - - JsonNode guards; - -protected: - bool objectFilter(const CGObjectInstance * obj, std::shared_ptr tmpl) const override; - void initTypeData(const JsonNode & input) override; - -public: - bool hasNameTextID() const override; - - void initializeObject(CGDwelling * object) const override; - void randomizeObject(CGDwelling * object, CRandomGenerator & rng) const override; - - bool producesCreature(const CCreature * crea) const; - std::vector getProducedCreatures() const; - - template void serialize(Handler &h, const int version) - { - h & availableCreatures; - h & guards; - h & static_cast&>(*this); - } -}; - class DLL_LINKAGE BoatInstanceConstructor : public CDefaultObjectTypeHandler { protected: diff --git a/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp b/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp new file mode 100644 index 000000000..14a28944d --- /dev/null +++ b/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp @@ -0,0 +1,146 @@ +/* +* DwellingInstanceConstructor.cpp, part of VCMI engine +* +* Authors: listed in file AUTHORS in main folder +* +* License: GNU General Public License v2.0 or later +* Full text of license available in license.txt file, in main folder +* +*/ +#include "StdInc.h" +#include "DwellingInstanceConstructor.h" + +#include "../CCreatureHandler.h" +#include "../CGeneralTextHandler.h" +#include "../CModHandler.h" +#include "../JsonRandom.h" +#include "../VCMI_Lib.h" +#include "../mapObjects/CGDwelling.h" + +VCMI_LIB_NAMESPACE_BEGIN + +bool DwellingInstanceConstructor::hasNameTextID() const +{ + return true; +} + +void DwellingInstanceConstructor::initTypeData(const JsonNode & input) +{ + if (input.Struct().count("name") == 0) + logMod->warn("Dwelling %s missing name!", getJsonKey()); + + VLC->generaltexth->registerString( input.meta, getNameTextID(), input["name"].String()); + + const JsonVector & levels = input["creatures"].Vector(); + const auto totalLevels = levels.size(); + + availableCreatures.resize(totalLevels); + for(auto currentLevel = 0; currentLevel < totalLevels; currentLevel++) + { + const JsonVector & creaturesOnLevel = levels[currentLevel].Vector(); + const auto creaturesNumber = creaturesOnLevel.size(); + availableCreatures[currentLevel].resize(creaturesNumber); + + for(auto currentCreature = 0; currentCreature < creaturesNumber; currentCreature++) + { + VLC->modh->identifiers.requestIdentifier("creature", creaturesOnLevel[currentCreature], [=] (si32 index) + { + availableCreatures[currentLevel][currentCreature] = VLC->creh->objects[index]; + }); + } + assert(!availableCreatures[currentLevel].empty()); + } + guards = input["guards"]; +} + +bool DwellingInstanceConstructor::objectFilter(const CGObjectInstance * obj, std::shared_ptr tmpl) const +{ + return false; +} + +void DwellingInstanceConstructor::initializeObject(CGDwelling * obj) const +{ + obj->creatures.resize(availableCreatures.size()); + for(const auto & entry : availableCreatures) + { + for(const CCreature * cre : entry) + obj->creatures.back().second.push_back(cre->getId()); + } +} + +void DwellingInstanceConstructor::randomizeObject(CGDwelling * object, CRandomGenerator &rng) const +{ + auto * dwelling = dynamic_cast(object); + + dwelling->creatures.clear(); + dwelling->creatures.reserve(availableCreatures.size()); + + for(const auto & entry : availableCreatures) + { + dwelling->creatures.resize(dwelling->creatures.size() + 1); + for(const CCreature * cre : entry) + dwelling->creatures.back().second.push_back(cre->getId()); + } + + bool guarded = false; //TODO: serialize for sanity + + if(guards.getType() == JsonNode::JsonType::DATA_BOOL) //simple switch + { + if(guards.Bool()) + { + guarded = true; + } + } + else if(guards.getType() == JsonNode::JsonType::DATA_VECTOR) //custom guards (eg. Elemental Conflux) + { + for(auto & stack : JsonRandom::loadCreatures(guards, rng)) + { + dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->getId(), stack.count)); + } + } + else //default condition - creatures are of level 5 or higher + { + for(auto creatureEntry : availableCreatures) + { + if(creatureEntry.at(0)->getLevel() >= 5) + { + guarded = true; + break; + } + } + } + + if(guarded) + { + for(auto creatureEntry : availableCreatures) + { + const CCreature * crea = creatureEntry.at(0); + dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(crea->getId(), crea->getGrowth() * 3)); + } + } +} + +bool DwellingInstanceConstructor::producesCreature(const CCreature * crea) const +{ + for(const auto & entry : availableCreatures) + { + for(const CCreature * cre : entry) + if(crea == cre) + return true; + } + return false; +} + +std::vector DwellingInstanceConstructor::getProducedCreatures() const +{ + std::vector creatures; //no idea why it's 2D, to be honest + for(const auto & entry : availableCreatures) + { + for(const CCreature * cre : entry) + creatures.push_back(cre); + } + return creatures; +} + + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjectConstructors/DwellingInstanceConstructor.h b/lib/mapObjectConstructors/DwellingInstanceConstructor.h new file mode 100644 index 000000000..4022be309 --- /dev/null +++ b/lib/mapObjectConstructors/DwellingInstanceConstructor.h @@ -0,0 +1,45 @@ +/* +* DwellingInstanceConstructor.h, part of VCMI engine +* +* Authors: listed in file AUTHORS in main folder +* +* License: GNU General Public License v2.0 or later +* Full text of license available in license.txt file, in main folder +* +*/ +#pragma once + +#include "CDefaultObjectTypeHandler.h" + +VCMI_LIB_NAMESPACE_BEGIN + +class CGDwelling; + +class DwellingInstanceConstructor : public CDefaultObjectTypeHandler +{ + std::vector> availableCreatures; + + JsonNode guards; + +protected: + bool objectFilter(const CGObjectInstance * obj, std::shared_ptr tmpl) const override; + void initTypeData(const JsonNode & input) override; + +public: + bool hasNameTextID() const override; + + void initializeObject(CGDwelling * object) const override; + void randomizeObject(CGDwelling * object, CRandomGenerator & rng) const override; + + bool producesCreature(const CCreature * crea) const; + std::vector getProducedCreatures() const; + + template void serialize(Handler &h, const int version) + { + h & availableCreatures; + h & guards; + h & static_cast&>(*this); + } +}; + +VCMI_LIB_NAMESPACE_END diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h index 83ee7379b..f7aa6ee30 100644 --- a/lib/registerTypes/RegisterTypes.h +++ b/lib/registerTypes/RegisterTypes.h @@ -21,6 +21,7 @@ #include "../mapObjectConstructors/CRewardableConstructor.h" #include "../mapObjectConstructors/CommonConstructors.h" #include "../mapObjectConstructors/CBankInstanceConstructor.h" +#include "../mapObjectConstructors/DwellingInstanceConstructor.h" #include "../mapObjectConstructors/HillFortInstanceConstructor.h" #include "../mapObjectConstructors/ShipyardInstanceConstructor.h" #include "../mapObjectConstructors/ShrineInstanceConstructor.h" @@ -97,7 +98,7 @@ void registerTypesMapObjectTypes(Serializer &s) s.template registerType(); s.template registerType(); s.template registerType(); - s.template registerType(); + s.template registerType(); s.template registerType(); s.template registerType(); s.template registerType(); diff --git a/lib/rmg/modificators/TreasurePlacer.cpp b/lib/rmg/modificators/TreasurePlacer.cpp index 466f712b5..bf362f23c 100644 --- a/lib/rmg/modificators/TreasurePlacer.cpp +++ b/lib/rmg/modificators/TreasurePlacer.cpp @@ -22,7 +22,7 @@ #include "../../ArtifactUtils.h" #include "../../mapObjectConstructors/AObjectTypeHandler.h" #include "../../mapObjectConstructors/CObjectClassesHandler.h" -#include "../../mapObjectConstructors/CommonConstructors.h" +#include "../../mapObjectConstructors/DwellingInstanceConstructor.h" #include "../../mapObjects/CGHeroInstance.h" #include "../../mapObjects/CGPandoraBox.h" #include "../../CCreatureHandler.h" @@ -172,7 +172,7 @@ void TreasurePlacer::addAllPossibleObjects() for(auto secondaryID : subObjects) { - const auto * dwellingHandler = dynamic_cast(VLC->objtypeh->getHandlerFor(dwellingType, secondaryID).get()); + const auto * dwellingHandler = dynamic_cast(VLC->objtypeh->getHandlerFor(dwellingType, secondaryID).get()); auto creatures = dwellingHandler->getProducedCreatures(); if(creatures.empty()) continue;