mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Merge pull request #5301 from IvanSavenko/map_loading_fix
Map loading fixes
This commit is contained in:
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
|
||||
{
|
||||
return type == BOTH || type == ENTRANCE;
|
||||
|
@ -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 <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
|
||||
{
|
||||
public:
|
||||
|
Reference in New Issue
Block a user