1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

Merge pull request #5301 from IvanSavenko/map_loading_fix

Map loading fixes
This commit is contained in:
Ivan Savenko 2025-01-25 17:23:54 +02:00 committed by GitHub
commit df99645eca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 289 additions and 180 deletions

View File

@ -15,7 +15,7 @@
#include "../Goals/RecruitHero.h" #include "../Goals/RecruitHero.h"
#include "../Goals/ExecuteHeroChain.h" #include "../Goals/ExecuteHeroChain.h"
#include "../Goals/ExchangeSwapTownHeroes.h" #include "../Goals/ExchangeSwapTownHeroes.h"
#include "lib/mapObjects/MapObjects.h" //for victory conditions #include "../../../lib/mapObjects/CGResource.h"
#include "../Engine/Nullkiller.h" #include "../Engine/Nullkiller.h"
namespace NKAI namespace NKAI

View File

@ -14,7 +14,7 @@
#include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h" #include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h" #include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h" #include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h"
#include "../../../lib/mapObjects/MapObjects.h" #include "../../../lib/mapObjects/CGResource.h"
#include "../../../lib/mapping/CMapDefines.h" #include "../../../lib/mapping/CMapDefines.h"
#include "../../../lib/RoadHandler.h" #include "../../../lib/RoadHandler.h"
#include "../../../lib/CCreatureHandler.h" #include "../../../lib/CCreatureHandler.h"
@ -508,7 +508,7 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target, cons
{ {
auto resource = dynamic_cast<const CGResource *>(target); auto resource = dynamic_cast<const CGResource *>(target);
TResources res; TResources res;
res[resource->resourceID()] = resource->amount; res[resource->resourceID()] = resource->getAmount();
return getResourceRequirementStrength(res); return getResourceRequirementStrength(res);
} }

View File

@ -16,6 +16,7 @@
#include "../ResourceManager.h" #include "../ResourceManager.h"
#include "../BuildingManager.h" #include "../BuildingManager.h"
#include "../../../lib/mapObjects/CGMarket.h" #include "../../../lib/mapObjects/CGMarket.h"
#include "../../../lib/mapObjects/CGResource.h"
#include "../../../lib/constants/StringConstants.h" #include "../../../lib/constants/StringConstants.h"
using namespace Goals; using namespace Goals;

View File

@ -96,13 +96,15 @@
} }
}, },
"types" : { "types" : {
"wood" : { "index" : 0, "aiValue" : 1400, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTwood0.def" } } }, "wood" : { "index" : 0, "aiValue" : 1400, "resource" : "wood", "amounts" : [ 6,7,8,9,10], "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, "resource" : "ore", "amounts" : [ 6,7,8,9,10], "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTore0.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" } } }, "mercury" : { "index" : 1, "aiValue" : 2000, "resource" : "mercury", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } },
"crystal" : { "index" : 4, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } }, "sulfur" : { "index" : 3, "aiValue" : 2000, "resource" : "sulfur", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } },
"gems" : { "index" : 5, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgems0.def" } } }, "crystal" : { "index" : 4, "aiValue" : 2000, "resource" : "crystal", "amounts" : [ 3,4,5], "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } },
"gold" : { "index" : 6, "aiValue" : 750, "rmg" : { "value" : 750, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgold0.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" } } }
} }
}, },

View File

@ -130,6 +130,7 @@ set(lib_MAIN_SRCS
mapObjects/CGMarket.cpp mapObjects/CGMarket.cpp
mapObjects/CGObjectInstance.cpp mapObjects/CGObjectInstance.cpp
mapObjects/CGPandoraBox.cpp mapObjects/CGPandoraBox.cpp
mapObjects/CGResource.cpp
mapObjects/TownBuildingInstance.cpp mapObjects/TownBuildingInstance.cpp
mapObjects/CGTownInstance.cpp mapObjects/CGTownInstance.cpp
mapObjects/CObjectHandler.cpp mapObjects/CObjectHandler.cpp
@ -519,6 +520,7 @@ set(lib_MAIN_HEADERS
mapObjects/CGObjectInstance.h mapObjects/CGObjectInstance.h
mapObjects/CGPandoraBox.h mapObjects/CGPandoraBox.h
mapObjects/TownBuildingInstance.h mapObjects/TownBuildingInstance.h
mapObjects/CGResource.h
mapObjects/CGTownInstance.h mapObjects/CGTownInstance.h
mapObjects/CObjectHandler.h mapObjects/CObjectHandler.h
mapObjects/CQuest.h mapObjects/CQuest.h

View File

@ -405,6 +405,8 @@ public:
enum Type enum Type
{ {
NO_OBJ = -1, NO_OBJ = -1,
NOTHING = 0,
ALTAR_OF_SACRIFICE [[deprecated]] = 2, ALTAR_OF_SACRIFICE [[deprecated]] = 2,
ANCHOR_POINT = 3, ANCHOR_POINT = 3,
ARENA = 4, ARENA = 4,

View File

@ -48,6 +48,17 @@ std::string CreatureInstanceConstructor::getNameTextID() const
return VLC->creatures()->getByIndex(getSubIndex())->getNamePluralTextID(); 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 bool ResourceInstanceConstructor::hasNameTextID() const
{ {
return true; return true;
@ -55,7 +66,33 @@ bool ResourceInstanceConstructor::hasNameTextID() const
std::string ResourceInstanceConstructor::getNameTextID() 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) void CTownInstanceConstructor::initTypeData(const JsonNode & input)

View File

@ -15,6 +15,9 @@
#include "../mapObjects/MiscObjects.h" #include "../mapObjects/MiscObjects.h"
#include "../mapObjects/CGCreature.h" #include "../mapObjects/CGCreature.h"
#include "../mapObjects/CGHeroInstance.h" #include "../mapObjects/CGHeroInstance.h"
#include "../mapObjects/CGMarket.h"
#include "../mapObjects/CGResource.h"
#include "../mapObjects/CGTownInstance.h"
#include "../mapObjects/ObstacleSetHandler.h" #include "../mapObjects/ObstacleSetHandler.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@ -46,9 +49,19 @@ public:
class ResourceInstanceConstructor : public CDefaultObjectTypeHandler<CGResource> class ResourceInstanceConstructor : public CDefaultObjectTypeHandler<CGResource>
{ {
JsonNode config;
GameResID resourceType;
public: public:
void initTypeData(const JsonNode & input) override;
bool hasNameTextID() const override; bool hasNameTextID() const override;
std::string getNameTextID() 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<CGTownInstance> class CTownInstanceConstructor : public CDefaultObjectTypeHandler<CGTownInstance>

View File

@ -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 <vstd/RNG.h>
VCMI_LIB_NAMESPACE_BEGIN
std::shared_ptr<ResourceInstanceConstructor> CGResource::getResourceHandler() const
{
const auto & baseHandler = getObjectHandler();
const auto & ourHandler = std::dynamic_pointer_cast<ResourceInstanceConstructor>(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

View File

@ -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<ResourceInstanceConstructor> 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 <typename Handler> void serialize(Handler &h)
{
h & static_cast<CArmedInstance&>(*this);
h & amount;
h & message;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -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 bool CGTeleport::isEntrance() const
{ {
return type == BOTH || type == ENTRANCE; return type == BOTH || type == ENTRANCE;

View File

@ -124,37 +124,6 @@ protected:
void serializeJsonOptions(JsonSerializeFormat & handler) override; 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 <typename Handler> void serialize(Handler &h)
{
h & static_cast<CArmedInstance&>(*this);
h & amount;
h & message;
}
protected:
void serializeJsonOptions(JsonSerializeFormat & handler) override;
};
class DLL_LINKAGE CGMine : public CArmedInstance, public IOwnableObject class DLL_LINKAGE CGMine : public CArmedInstance, public IOwnableObject
{ {
public: public:

View File

@ -178,7 +178,6 @@ EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
CMap::CMap(IGameCallback * cb) CMap::CMap(IGameCallback * cb)
: GameCallbackHolder(cb) : GameCallbackHolder(cb)
, checksum(0)
, grailPos(-1, -1, -1) , grailPos(-1, -1, -1)
, grailRadius(0) , grailRadius(0)
, waterMap(false) , waterMap(false)

View File

@ -137,7 +137,6 @@ public:
void reindexObjects(); void reindexObjects();
ui32 checksum;
std::vector<Rumor> rumors; std::vector<Rumor> rumors;
std::vector<DisposedHero> disposedHeroes; std::vector<DisposedHero> disposedHeroes;
std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes; std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;

View File

@ -31,7 +31,9 @@
#include "../filesystem/Filesystem.h" #include "../filesystem/Filesystem.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h" #include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h" #include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjectConstructors/CommonConstructors.h"
#include "../mapObjects/CGCreature.h" #include "../mapObjects/CGCreature.h"
#include "../mapObjects/CGResource.h"
#include "../mapObjects/MapObjects.h" #include "../mapObjects/MapObjects.h"
#include "../mapObjects/ObjectTemplate.h" #include "../mapObjects/ObjectTemplate.h"
#include "../modding/ModScope.h" #include "../modding/ModScope.h"
@ -40,8 +42,6 @@
#include "../spells/CSpellHandler.h" #include "../spells/CSpellHandler.h"
#include "../texts/TextOperations.h" #include "../texts/TextOperations.h"
#include <boost/crc.hpp>
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
static std::string convertMapName(std::string input) static std::string convertMapName(std::string input)
@ -92,19 +92,6 @@ std::unique_ptr<CMapHeader> CMapLoaderH3M::loadMapHeader()
void CMapLoaderH3M::init() 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); inputStream->seek(0);
readHeader(); readHeader();
@ -1315,11 +1302,15 @@ CGObjectInstance * CMapLoaderH3M::readResource(const int3 & mapPosition, std::sh
readMessageAndGuards(object->message, object, mapPosition); readMessageAndGuards(object->message, object, mapPosition);
object->amount = reader->readUInt32(); object->amount = reader->readUInt32();
if(GameResID(objectTemplate->subid) == GameResID(EGameResID::GOLD))
if (objectTemplate->id != Obj::RANDOM_RESOURCE)
{ {
// Gold is multiplied by 100. const auto & baseHandler = VLC->objtypeh->getHandlerFor(objectTemplate->id, objectTemplate->subid);
object->amount *= CGResource::GOLD_AMOUNT_MULTIPLIER; const auto & ourHandler = std::dynamic_pointer_cast<ResourceInstanceConstructor>(baseHandler);
object->amount *= ourHandler->getAmountMultiplier();
} }
reader->skipZero(4); reader->skipZero(4);
return object; return object;
} }

View File

@ -116,6 +116,22 @@ void MapIdentifiersH3M::remapTemplate(ObjectTemplate & objectTemplate)
objectTemplate.subid = mappedType.subID; 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) if (objectTemplate.id == Obj::TOWN || objectTemplate.id == Obj::RANDOM_DWELLING_FACTION)
objectTemplate.subid = remap(FactionID(objectTemplate.subid)); objectTemplate.subid = remap(FactionID(objectTemplate.subid));

View File

@ -12,6 +12,7 @@
#include "../RmgMap.h" #include "../RmgMap.h"
#include "../../mapObjectConstructors/AObjectTypeHandler.h" #include "../../mapObjectConstructors/AObjectTypeHandler.h"
#include "../../mapObjectConstructors/CObjectClassesHandler.h" #include "../../mapObjectConstructors/CObjectClassesHandler.h"
#include "../../mapObjects/CGResource.h"
#include "../../mapObjects/MiscObjects.h" #include "../../mapObjects/MiscObjects.h"
#include "../../mapping/CMapEditManager.h" #include "../../mapping/CMapEditManager.h"
#include "../RmgPath.h" #include "../RmgPath.h"
@ -91,7 +92,6 @@ bool MinePlacer::placeMines(ObjectManager & manager)
for(int rc = zone.getRand().nextInt(1, extraRes); rc > 0; --rc) for(int rc = zone.getRand().nextInt(1, extraRes); rc > 0; --rc)
{ {
auto * resource = dynamic_cast<CGResource *>(VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(map.mapInstance->cb, nullptr)); auto * resource = dynamic_cast<CGResource *>(VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(map.mapInstance->cb, nullptr));
resource->amount = CGResource::RANDOM_AMOUNT;
RequiredObjectInfo roi; RequiredObjectInfo roi;
roi.obj = resource; roi.obj = resource;

View File

@ -23,6 +23,7 @@
#include "../mapObjects/CGCreature.h" #include "../mapObjects/CGCreature.h"
#include "../mapObjects/CGDwelling.h" #include "../mapObjects/CGDwelling.h"
#include "../mapObjects/CGResource.h"
#include "../mapObjects/CGMarket.h" #include "../mapObjects/CGMarket.h"
#include "../mapObjects/CGPandoraBox.h" #include "../mapObjects/CGPandoraBox.h"
#include "../mapObjects/CGTownInstance.h" #include "../mapObjects/CGTownInstance.h"

View File

@ -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=============================== //===============IMPLEMENT PROPERTIES SETUP===============================
void Inspector::updateProperties(CArmedInstance * o) void Inspector::updateProperties(CArmedInstance * o)
{ {

View File

@ -17,6 +17,7 @@
#include "../lib/int3.h" #include "../lib/int3.h"
#include "../lib/GameConstants.h" #include "../lib/GameConstants.h"
#include "../lib/mapObjects/CGCreature.h" #include "../lib/mapObjects/CGCreature.h"
#include "../lib/mapObjects/CGResource.h"
#include "../lib/mapObjects/MapObjects.h" #include "../lib/mapObjects/MapObjects.h"
#include "../lib/mapObjects/FlaggableMapObject.h" #include "../lib/mapObjects/FlaggableMapObject.h"
#include "../lib/mapObjects/CRewardableObject.h" #include "../lib/mapObjects/CRewardableObject.h"
@ -43,7 +44,6 @@ public:
DECLARE_OBJ_TYPE(CGTownInstance); DECLARE_OBJ_TYPE(CGTownInstance);
DECLARE_OBJ_TYPE(CGArtifact); DECLARE_OBJ_TYPE(CGArtifact);
DECLARE_OBJ_TYPE(CGMine); DECLARE_OBJ_TYPE(CGMine);
DECLARE_OBJ_TYPE(CGResource);
DECLARE_OBJ_TYPE(CGDwelling); DECLARE_OBJ_TYPE(CGDwelling);
DECLARE_OBJ_TYPE(CGGarrison); DECLARE_OBJ_TYPE(CGGarrison);
DECLARE_OBJ_TYPE(CGHeroPlaceholder); DECLARE_OBJ_TYPE(CGHeroPlaceholder);