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:
commit
df99645eca
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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" } } }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
138
lib/mapObjects/CGResource.cpp
Normal file
138
lib/mapObjects/CGResource.cpp
Normal 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
|
55
lib/mapObjects/CGResource.h
Normal file
55
lib/mapObjects/CGResource.h
Normal 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
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user