diff --git a/AI/Nullkiller/Behaviors/StartupBehavior.cpp b/AI/Nullkiller/Behaviors/StartupBehavior.cpp index 9d0a12b18..f41a2df88 100644 --- a/AI/Nullkiller/Behaviors/StartupBehavior.cpp +++ b/AI/Nullkiller/Behaviors/StartupBehavior.cpp @@ -15,7 +15,7 @@ #include "../Goals/RecruitHero.h" #include "../Goals/ExecuteHeroChain.h" #include "../Goals/ExchangeSwapTownHeroes.h" -#include "lib/mapObjects/MapObjects.h" //for victory conditions +#include "../../../lib/mapObjects/CGResource.h" #include "../Engine/Nullkiller.h" namespace NKAI diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index ce42b684c..d8858c8fb 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -14,7 +14,7 @@ #include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h" #include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h" #include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h" -#include "../../../lib/mapObjects/MapObjects.h" +#include "../../../lib/mapObjects/CGResource.h" #include "../../../lib/mapping/CMapDefines.h" #include "../../../lib/RoadHandler.h" #include "../../../lib/CCreatureHandler.h" @@ -508,7 +508,7 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target, cons { auto resource = dynamic_cast(target); TResources res; - res[resource->resourceID()] = resource->amount; + res[resource->resourceID()] = resource->getAmount(); return getResourceRequirementStrength(res); } diff --git a/AI/VCAI/Goals/CollectRes.cpp b/AI/VCAI/Goals/CollectRes.cpp index 0750250e4..07b047424 100644 --- a/AI/VCAI/Goals/CollectRes.cpp +++ b/AI/VCAI/Goals/CollectRes.cpp @@ -16,6 +16,7 @@ #include "../ResourceManager.h" #include "../BuildingManager.h" #include "../../../lib/mapObjects/CGMarket.h" +#include "../../../lib/mapObjects/CGResource.h" #include "../../../lib/constants/StringConstants.h" using namespace Goals; diff --git a/config/objects/moddables.json b/config/objects/moddables.json index 422fe3532..a61bc43ce 100644 --- a/config/objects/moddables.json +++ b/config/objects/moddables.json @@ -96,13 +96,15 @@ } }, "types" : { - "wood" : { "index" : 0, "aiValue" : 1400, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTwood0.def" } } }, - "mercury" : { "index" : 1, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } }, - "ore" : { "index" : 2, "aiValue" : 1400, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTore0.def" } } }, - "sulfur" : { "index" : 3, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } }, - "crystal" : { "index" : 4, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } }, - "gems" : { "index" : 5, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgems0.def" } } }, - "gold" : { "index" : 6, "aiValue" : 750, "rmg" : { "value" : 750, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgold0.def" } } } + "wood" : { "index" : 0, "aiValue" : 1400, "resource" : "wood", "amounts" : [ 6,7,8,9,10], "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTwood0.def" } } }, + "ore" : { "index" : 2, "aiValue" : 1400, "resource" : "ore", "amounts" : [ 6,7,8,9,10], "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTore0.def" } } }, + + "mercury" : { "index" : 1, "aiValue" : 2000, "resource" : "mercury", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } }, + "sulfur" : { "index" : 3, "aiValue" : 2000, "resource" : "sulfur", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } }, + "crystal" : { "index" : 4, "aiValue" : 2000, "resource" : "crystal", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } }, + "gems" : { "index" : 5, "aiValue" : 2000, "resource" : "gems", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgems0.def" } } }, + + "gold" : { "index" : 6, "aiValue" : 750, "resource" : "gold", "amounts" : [ 5,6,7,8,9,10], "amountMultiplier" : 100, "rmg" : { "value" : 750, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgold0.def" } } } } }, diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 2f0740163..c829e3f7b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -130,6 +130,7 @@ set(lib_MAIN_SRCS mapObjects/CGMarket.cpp mapObjects/CGObjectInstance.cpp mapObjects/CGPandoraBox.cpp + mapObjects/CGResource.cpp mapObjects/TownBuildingInstance.cpp mapObjects/CGTownInstance.cpp mapObjects/CObjectHandler.cpp @@ -519,6 +520,7 @@ set(lib_MAIN_HEADERS mapObjects/CGObjectInstance.h mapObjects/CGPandoraBox.h mapObjects/TownBuildingInstance.h + mapObjects/CGResource.h mapObjects/CGTownInstance.h mapObjects/CObjectHandler.h mapObjects/CQuest.h diff --git a/lib/constants/EntityIdentifiers.h b/lib/constants/EntityIdentifiers.h index 8b329a98a..b1adc4354 100644 --- a/lib/constants/EntityIdentifiers.h +++ b/lib/constants/EntityIdentifiers.h @@ -405,6 +405,8 @@ public: enum Type { NO_OBJ = -1, + + NOTHING = 0, ALTAR_OF_SACRIFICE [[deprecated]] = 2, ANCHOR_POINT = 3, ARENA = 4, diff --git a/lib/mapObjectConstructors/CommonConstructors.cpp b/lib/mapObjectConstructors/CommonConstructors.cpp index a3986304a..d82682b54 100644 --- a/lib/mapObjectConstructors/CommonConstructors.cpp +++ b/lib/mapObjectConstructors/CommonConstructors.cpp @@ -48,6 +48,17 @@ std::string CreatureInstanceConstructor::getNameTextID() const return VLC->creatures()->getByIndex(getSubIndex())->getNamePluralTextID(); } +void ResourceInstanceConstructor::initTypeData(const JsonNode & input) +{ + config = input; + + resourceType = GameResID::GOLD; //set up fallback + VLC->identifiers()->requestIdentifierOptional("resource", input["resource"], [&](si32 index) + { + resourceType = GameResID(index); + }); +} + bool ResourceInstanceConstructor::hasNameTextID() const { return true; @@ -55,7 +66,33 @@ bool ResourceInstanceConstructor::hasNameTextID() const std::string ResourceInstanceConstructor::getNameTextID() const { - return TextIdentifier("core", "restypes", getSubIndex()).get(); + return TextIdentifier("core", "restypes", resourceType.getNum()).get(); +} + +GameResID ResourceInstanceConstructor::getResourceType() const +{ + return resourceType; +} + +int ResourceInstanceConstructor::getAmountMultiplier() const +{ + if (config["amountMultiplier"].isNull()) + return 1; + return config["amountMultiplier"].Integer(); +} + +void ResourceInstanceConstructor::randomizeObject(CGResource * object, vstd::RNG & rng) const +{ + if (object->amount != CGResource::RANDOM_AMOUNT) + return; + + JsonRandom randomizer(object->cb); + JsonRandom::Variables dummy; + + if (!config["amounts"].isNull()) + object->amount = randomizer.loadValue(config["amounts"], rng, dummy, 0) * getAmountMultiplier(); + else + object->amount = 5 * getAmountMultiplier(); } void CTownInstanceConstructor::initTypeData(const JsonNode & input) diff --git a/lib/mapObjectConstructors/CommonConstructors.h b/lib/mapObjectConstructors/CommonConstructors.h index 73ba43874..0b9cc98c0 100644 --- a/lib/mapObjectConstructors/CommonConstructors.h +++ b/lib/mapObjectConstructors/CommonConstructors.h @@ -15,6 +15,9 @@ #include "../mapObjects/MiscObjects.h" #include "../mapObjects/CGCreature.h" #include "../mapObjects/CGHeroInstance.h" +#include "../mapObjects/CGMarket.h" +#include "../mapObjects/CGResource.h" +#include "../mapObjects/CGTownInstance.h" #include "../mapObjects/ObstacleSetHandler.h" VCMI_LIB_NAMESPACE_BEGIN @@ -46,9 +49,19 @@ public: class ResourceInstanceConstructor : public CDefaultObjectTypeHandler { + JsonNode config; + GameResID resourceType; public: + void initTypeData(const JsonNode & input) override; + bool hasNameTextID() const override; std::string getNameTextID() const override; + + GameResID getResourceType() const; + int getAmountMultiplier() const; + int getBaseAmount(vstd::RNG & rng) const; + + void randomizeObject(CGResource * object, vstd::RNG & rng) const override; }; class CTownInstanceConstructor : public CDefaultObjectTypeHandler diff --git a/lib/mapObjects/CGResource.cpp b/lib/mapObjects/CGResource.cpp new file mode 100644 index 000000000..45f428d3d --- /dev/null +++ b/lib/mapObjects/CGResource.cpp @@ -0,0 +1,138 @@ +/* + * MiscObjects.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 "CGResource.h" + +#include "../mapObjectConstructors/CommonConstructors.h" +#include "../texts/CGeneralTextHandler.h" +#include "../networkPacks/PacksForClient.h" +#include "../networkPacks/PacksForClientBattle.h" +#include "../IGameCallback.h" +#include "../gameState/CGameState.h" +#include "../serializer/JsonSerializeFormat.h" +#include "../CSoundBase.h" + +#include + +VCMI_LIB_NAMESPACE_BEGIN + +std::shared_ptr CGResource::getResourceHandler() const +{ + const auto & baseHandler = getObjectHandler(); + const auto & ourHandler = std::dynamic_pointer_cast(baseHandler); + return ourHandler; +} + +int CGResource::getAmountMultiplier() const +{ + return getResourceHandler()->getAmountMultiplier(); +} + +uint32_t CGResource::getAmount() const +{ + return amount; +} + +GameResID CGResource::resourceID() const +{ + return getResourceHandler()->getResourceType(); +} + +std::string CGResource::getHoverText(PlayerColor player) const +{ + return VLC->generaltexth->restypes[resourceID().getNum()]; +} + +void CGResource::pickRandomObject(vstd::RNG & rand) +{ + assert(ID == Obj::RESOURCE || ID == Obj::RANDOM_RESOURCE); + + if (ID == Obj::RANDOM_RESOURCE) + { + ID = Obj::RESOURCE; + subID = rand.nextInt(EGameResID::WOOD, EGameResID::GOLD); + setType(ID, subID); + + amount *= getAmountMultiplier(); + } +} + +void CGResource::initObj(vstd::RNG & rand) +{ + blockVisit = true; + getResourceHandler()->randomizeObject(this, rand); +} + +void CGResource::onHeroVisit( const CGHeroInstance * h ) const +{ + if(stacksCount()) + { + if(!message.empty()) + { + BlockingDialog ynd(true,false); + ynd.player = h->getOwner(); + ynd.text = message; + cb->showBlockingDialog(this, &ynd); + } + else + { + blockingDialogAnswered(h, true); //behave as if player accepted battle + } + } + else + collectRes(h->getOwner()); +} + +void CGResource::collectRes(const PlayerColor & player) const +{ + cb->giveResource(player, resourceID(), amount); + InfoWindow sii; + sii.player = player; + if(!message.empty()) + { + sii.type = EInfoWindowMode::AUTO; + sii.text = message; + } + else + { + sii.type = EInfoWindowMode::INFO; + sii.text.appendLocalString(EMetaText::ADVOB_TXT,113); + sii.text.replaceName(resourceID()); + } + sii.components.emplace_back(ComponentType::RESOURCE, resourceID(), amount); + sii.soundID = soundBase::pickup01 + cb->gameState()->getRandomGenerator().nextInt(6); + cb->showInfoDialog(&sii); + cb->removeObject(this, player); +} + +void CGResource::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const +{ + if(result.winner == BattleSide::ATTACKER) //attacker won + collectRes(hero->getOwner()); +} + +void CGResource::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const +{ + if(answer) + cb->startBattle(hero, this); +} + +void CGResource::serializeJsonOptions(JsonSerializeFormat & handler) +{ + CArmedInstance::serializeJsonOptions(handler); + if(!handler.saving && !handler.getCurrent()["guards"].Vector().empty()) + CCreatureSet::serializeJson(handler, "guards", 7); + handler.serializeInt("amount", amount, 0); + handler.serializeStruct("guardMessage", message); +} + + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/CGResource.h b/lib/mapObjects/CGResource.h new file mode 100644 index 000000000..e6413c38a --- /dev/null +++ b/lib/mapObjects/CGResource.h @@ -0,0 +1,55 @@ +/* + * CGResource.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 "CArmedInstance.h" + +VCMI_LIB_NAMESPACE_BEGIN + +class ResourceInstanceConstructor; + +class DLL_LINKAGE CGResource : public CArmedInstance +{ + friend class Inspector; + friend class CMapLoaderH3M; + friend class ResourceInstanceConstructor; + + MetaString message; + + static constexpr uint32_t RANDOM_AMOUNT = 0; + uint32_t amount = RANDOM_AMOUNT; //0 if random + + std::shared_ptr getResourceHandler() const; + int getAmountMultiplier() const; + void collectRes(const PlayerColor & player) const; + void serializeJsonOptions(JsonSerializeFormat & handler) override; + +public: + using CArmedInstance::CArmedInstance; + + void onHeroVisit(const CGHeroInstance * h) const override; + void initObj(vstd::RNG & rand) override; + void pickRandomObject(vstd::RNG & rand) override; + void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; + void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override; + std::string getHoverText(PlayerColor player) const override; + + GameResID resourceID() const; + uint32_t getAmount() const; + + template void serialize(Handler &h) + { + h & static_cast(*this); + h & amount; + h & message; + } +}; + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 2aba32c78..17a54d288 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -256,115 +256,6 @@ void CGMine::serializeJsonOptions(JsonSerializeFormat & handler) } } -GameResID CGResource::resourceID() const -{ - return getObjTypeIndex().getNum(); -} - -std::string CGResource::getHoverText(PlayerColor player) const -{ - return VLC->generaltexth->restypes[resourceID().getNum()]; -} - -void CGResource::pickRandomObject(vstd::RNG & rand) -{ - assert(ID == Obj::RESOURCE || ID == Obj::RANDOM_RESOURCE); - - if (ID == Obj::RANDOM_RESOURCE) - { - ID = Obj::RESOURCE; - subID = rand.nextInt(EGameResID::WOOD, EGameResID::GOLD); - setType(ID, subID); - - if (subID == EGameResID::GOLD && amount != CGResource::RANDOM_AMOUNT) - amount *= CGResource::GOLD_AMOUNT_MULTIPLIER; - } -} - -void CGResource::initObj(vstd::RNG & rand) -{ - blockVisit = true; - - if(amount == CGResource::RANDOM_AMOUNT) - { - switch(resourceID().toEnum()) - { - case EGameResID::GOLD: - amount = rand.nextInt(5, 10) * CGResource::GOLD_AMOUNT_MULTIPLIER; - break; - case EGameResID::WOOD: case EGameResID::ORE: - amount = rand.nextInt(6, 10); - break; - default: - amount = rand.nextInt(3, 5); - break; - } - } -} - -void CGResource::onHeroVisit( const CGHeroInstance * h ) const -{ - if(stacksCount()) - { - if(!message.empty()) - { - BlockingDialog ynd(true,false); - ynd.player = h->getOwner(); - ynd.text = message; - cb->showBlockingDialog(this, &ynd); - } - else - { - blockingDialogAnswered(h, true); //behave as if player accepted battle - } - } - else - collectRes(h->getOwner()); -} - -void CGResource::collectRes(const PlayerColor & player) const -{ - cb->giveResource(player, resourceID(), amount); - InfoWindow sii; - sii.player = player; - if(!message.empty()) - { - sii.type = EInfoWindowMode::AUTO; - sii.text = message; - } - else - { - sii.type = EInfoWindowMode::INFO; - sii.text.appendLocalString(EMetaText::ADVOB_TXT,113); - sii.text.replaceName(resourceID()); - } - sii.components.emplace_back(ComponentType::RESOURCE, resourceID(), amount); - sii.soundID = soundBase::pickup01 + cb->gameState()->getRandomGenerator().nextInt(6); - cb->showInfoDialog(&sii); - cb->removeObject(this, player); -} - -void CGResource::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const -{ - if(result.winner == BattleSide::ATTACKER) //attacker won - collectRes(hero->getOwner()); -} - -void CGResource::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const -{ - if(answer) - cb->startBattle(hero, this); -} - -void CGResource::serializeJsonOptions(JsonSerializeFormat & handler) -{ - CArmedInstance::serializeJsonOptions(handler); - if(!handler.saving && !handler.getCurrent()["guards"].Vector().empty()) - CCreatureSet::serializeJson(handler, "guards", 7); - handler.serializeInt("amount", amount, 0); - handler.serializeStruct("guardMessage", message); -} - bool CGTeleport::isEntrance() const { return type == BOTH || type == ENTRANCE; diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index c3427880b..607771451 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -124,37 +124,6 @@ protected: void serializeJsonOptions(JsonSerializeFormat & handler) override; }; -class DLL_LINKAGE CGResource : public CArmedInstance -{ -public: - using CArmedInstance::CArmedInstance; - - static constexpr uint32_t RANDOM_AMOUNT = 0; - static constexpr uint32_t GOLD_AMOUNT_MULTIPLIER = 100; - uint32_t amount = RANDOM_AMOUNT; //0 if random - - MetaString message; - - void onHeroVisit(const CGHeroInstance * h) const override; - void initObj(vstd::RNG & rand) override; - void pickRandomObject(vstd::RNG & rand) override; - void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; - void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override; - std::string getHoverText(PlayerColor player) const override; - - void collectRes(const PlayerColor & player) const; - GameResID resourceID() const; - - template void serialize(Handler &h) - { - h & static_cast(*this); - h & amount; - h & message; - } -protected: - void serializeJsonOptions(JsonSerializeFormat & handler) override; -}; - class DLL_LINKAGE CGMine : public CArmedInstance, public IOwnableObject { public: diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index ba7dbf72f..eb7615b19 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -178,7 +178,6 @@ EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const CMap::CMap(IGameCallback * cb) : GameCallbackHolder(cb) - , checksum(0) , grailPos(-1, -1, -1) , grailRadius(0) , waterMap(false) diff --git a/lib/mapping/CMap.h b/lib/mapping/CMap.h index 4fa4c2744..ceae15b36 100644 --- a/lib/mapping/CMap.h +++ b/lib/mapping/CMap.h @@ -137,7 +137,6 @@ public: void reindexObjects(); - ui32 checksum; std::vector rumors; std::vector disposedHeroes; std::vector > predefinedHeroes; diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 969e168b2..b835450c2 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -31,7 +31,9 @@ #include "../filesystem/Filesystem.h" #include "../mapObjectConstructors/AObjectTypeHandler.h" #include "../mapObjectConstructors/CObjectClassesHandler.h" +#include "../mapObjectConstructors/CommonConstructors.h" #include "../mapObjects/CGCreature.h" +#include "../mapObjects/CGResource.h" #include "../mapObjects/MapObjects.h" #include "../mapObjects/ObjectTemplate.h" #include "../modding/ModScope.h" @@ -40,8 +42,6 @@ #include "../spells/CSpellHandler.h" #include "../texts/TextOperations.h" -#include - VCMI_LIB_NAMESPACE_BEGIN static std::string convertMapName(std::string input) @@ -92,19 +92,6 @@ std::unique_ptr CMapLoaderH3M::loadMapHeader() void CMapLoaderH3M::init() { - //TODO: get rid of double input process - si64 temp_size = inputStream->getSize(); - inputStream->seek(0); - - auto * temp_buffer = new ui8[temp_size]; - inputStream->read(temp_buffer, temp_size); - - // Compute checksum - boost::crc_32_type result; - result.process_bytes(temp_buffer, temp_size); - map->checksum = result.checksum(); - - delete[] temp_buffer; inputStream->seek(0); readHeader(); @@ -1315,11 +1302,15 @@ CGObjectInstance * CMapLoaderH3M::readResource(const int3 & mapPosition, std::sh readMessageAndGuards(object->message, object, mapPosition); object->amount = reader->readUInt32(); - if(GameResID(objectTemplate->subid) == GameResID(EGameResID::GOLD)) + + if (objectTemplate->id != Obj::RANDOM_RESOURCE) { - // Gold is multiplied by 100. - object->amount *= CGResource::GOLD_AMOUNT_MULTIPLIER; + const auto & baseHandler = VLC->objtypeh->getHandlerFor(objectTemplate->id, objectTemplate->subid); + const auto & ourHandler = std::dynamic_pointer_cast(baseHandler); + + object->amount *= ourHandler->getAmountMultiplier(); } + reader->skipZero(4); return object; } diff --git a/lib/mapping/MapIdentifiersH3M.cpp b/lib/mapping/MapIdentifiersH3M.cpp index e75e58235..5e9f4f95b 100644 --- a/lib/mapping/MapIdentifiersH3M.cpp +++ b/lib/mapping/MapIdentifiersH3M.cpp @@ -116,6 +116,22 @@ void MapIdentifiersH3M::remapTemplate(ObjectTemplate & objectTemplate) objectTemplate.subid = mappedType.subID; } + if (VLC->objtypeh->knownObjects().count(objectTemplate.id) == 0) + { + logGlobal->warn("Unknown object found: %d | %d", objectTemplate.id, objectTemplate.subid); + + objectTemplate.id = Obj::NOTHING; + objectTemplate.subid = {}; + } + else + { + if (VLC->objtypeh->knownSubObjects(objectTemplate.id).count(objectTemplate.subid) == 0) + { + logGlobal->warn("Unknown subobject found: %d | %d", objectTemplate.id, objectTemplate.subid); + objectTemplate.subid = {}; + } + } + if (objectTemplate.id == Obj::TOWN || objectTemplate.id == Obj::RANDOM_DWELLING_FACTION) objectTemplate.subid = remap(FactionID(objectTemplate.subid)); diff --git a/lib/rmg/modificators/MinePlacer.cpp b/lib/rmg/modificators/MinePlacer.cpp index 4dcc2b41a..5a6de2454 100644 --- a/lib/rmg/modificators/MinePlacer.cpp +++ b/lib/rmg/modificators/MinePlacer.cpp @@ -12,6 +12,7 @@ #include "../RmgMap.h" #include "../../mapObjectConstructors/AObjectTypeHandler.h" #include "../../mapObjectConstructors/CObjectClassesHandler.h" +#include "../../mapObjects/CGResource.h" #include "../../mapObjects/MiscObjects.h" #include "../../mapping/CMapEditManager.h" #include "../RmgPath.h" @@ -91,7 +92,6 @@ bool MinePlacer::placeMines(ObjectManager & manager) for(int rc = zone.getRand().nextInt(1, extraRes); rc > 0; --rc) { auto * resource = dynamic_cast(VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(map.mapInstance->cb, nullptr)); - resource->amount = CGResource::RANDOM_AMOUNT; RequiredObjectInfo roi; roi.obj = resource; diff --git a/lib/serializer/RegisterTypes.h b/lib/serializer/RegisterTypes.h index c3dab0559..471e37620 100644 --- a/lib/serializer/RegisterTypes.h +++ b/lib/serializer/RegisterTypes.h @@ -23,6 +23,7 @@ #include "../mapObjects/CGCreature.h" #include "../mapObjects/CGDwelling.h" +#include "../mapObjects/CGResource.h" #include "../mapObjects/CGMarket.h" #include "../mapObjects/CGPandoraBox.h" #include "../mapObjects/CGTownInstance.h" diff --git a/mapeditor/inspector/inspector.cpp b/mapeditor/inspector/inspector.cpp index 74848c5e3..96984191f 100644 --- a/mapeditor/inspector/inspector.cpp +++ b/mapeditor/inspector/inspector.cpp @@ -225,13 +225,6 @@ void Initializer::initialize(CGMine * o) } } -void Initializer::initialize(CGResource * o) -{ - if(!o) return; - - o->amount = CGResource::RANDOM_AMOUNT; -} - //===============IMPLEMENT PROPERTIES SETUP=============================== void Inspector::updateProperties(CArmedInstance * o) { diff --git a/mapeditor/inspector/inspector.h b/mapeditor/inspector/inspector.h index 66c6a768a..7f78fea81 100644 --- a/mapeditor/inspector/inspector.h +++ b/mapeditor/inspector/inspector.h @@ -17,6 +17,7 @@ #include "../lib/int3.h" #include "../lib/GameConstants.h" #include "../lib/mapObjects/CGCreature.h" +#include "../lib/mapObjects/CGResource.h" #include "../lib/mapObjects/MapObjects.h" #include "../lib/mapObjects/FlaggableMapObject.h" #include "../lib/mapObjects/CRewardableObject.h" @@ -43,7 +44,6 @@ public: DECLARE_OBJ_TYPE(CGTownInstance); DECLARE_OBJ_TYPE(CGArtifact); DECLARE_OBJ_TYPE(CGMine); - DECLARE_OBJ_TYPE(CGResource); DECLARE_OBJ_TYPE(CGDwelling); DECLARE_OBJ_TYPE(CGGarrison); DECLARE_OBJ_TYPE(CGHeroPlaceholder);