mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Merge pull request #3473 from IvanSavenko/const_lib
[1.5] Remove non-const global variables from library
This commit is contained in:
commit
6b760089a4
@ -350,10 +350,11 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
|
||||
LOGL("Casting spells sounds like fun. Let's see...");
|
||||
//Get all spells we can cast
|
||||
std::vector<const CSpell*> possibleSpells;
|
||||
vstd::copy_if(VLC->spellh->objects, std::back_inserter(possibleSpells), [hero, this](const CSpell *s) -> bool
|
||||
{
|
||||
return s->canBeCast(cb->getBattle(battleID).get(), spells::Mode::HERO, hero);
|
||||
});
|
||||
|
||||
for (auto const & s : VLC->spellh->objects)
|
||||
if (s->canBeCast(cb->getBattle(battleID).get(), spells::Mode::HERO, hero))
|
||||
possibleSpells.push_back(s.get());
|
||||
|
||||
LOGFL("I can cast %d spells.", possibleSpells.size());
|
||||
|
||||
vstd::erase_if(possibleSpells, [](const CSpell *s)
|
||||
|
@ -276,12 +276,10 @@ creInfo infoFromDC(const dwellingContent & dc)
|
||||
ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed
|
||||
if (ci.creID != CreatureID::NONE)
|
||||
{
|
||||
ci.cre = VLC->creatures()->getById(ci.creID);
|
||||
ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.
|
||||
ci.level = ci.creID.toCreature()->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.
|
||||
}
|
||||
else
|
||||
{
|
||||
ci.cre = nullptr;
|
||||
ci.level = 0;
|
||||
}
|
||||
return ci;
|
||||
|
@ -163,7 +163,6 @@ struct creInfo
|
||||
{
|
||||
int count;
|
||||
CreatureID creID;
|
||||
const Creature * cre;
|
||||
int level;
|
||||
};
|
||||
creInfo infoFromDC(const dwellingContent & dc);
|
||||
|
@ -63,9 +63,9 @@ std::vector<SlotInfo> ArmyManager::toSlotInfo(std::vector<creInfo> army) const
|
||||
{
|
||||
SlotInfo slot;
|
||||
|
||||
slot.creature = VLC->creh->objects[i.cre->getId()];
|
||||
slot.creature = i.creID.toCreature();
|
||||
slot.count = i.count;
|
||||
slot.power = evaluateStackPower(i.cre, i.count);
|
||||
slot.power = evaluateStackPower(i.creID.toCreature(), i.count);
|
||||
|
||||
result.push_back(slot);
|
||||
}
|
||||
@ -128,7 +128,7 @@ class TemporaryArmy : public CArmedInstance
|
||||
public:
|
||||
void armyChanged() override {}
|
||||
TemporaryArmy()
|
||||
:CArmedInstance(true)
|
||||
:CArmedInstance(nullptr, true)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -259,7 +259,7 @@ std::shared_ptr<CCreatureSet> ArmyManager::getArmyAvailableToBuyAsCCreatureSet(
|
||||
if(!ci.count || ci.creID == CreatureID::NONE)
|
||||
continue;
|
||||
|
||||
vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford
|
||||
vstd::amin(ci.count, availableRes / ci.creID.toCreature()->getFullRecruitCost()); //max count we can afford
|
||||
|
||||
if(!ci.count)
|
||||
continue;
|
||||
@ -270,7 +270,7 @@ std::shared_ptr<CCreatureSet> ArmyManager::getArmyAvailableToBuyAsCCreatureSet(
|
||||
break;
|
||||
|
||||
army->setCreature(dst, ci.creID, ci.count);
|
||||
availableRes -= ci.cre->getFullRecruitCost() * ci.count;
|
||||
availableRes -= ci.creID.toCreature()->getFullRecruitCost() * ci.count;
|
||||
}
|
||||
|
||||
return army;
|
||||
@ -287,7 +287,7 @@ ui64 ArmyManager::howManyReinforcementsCanBuy(
|
||||
|
||||
for(const creInfo & ci : army)
|
||||
{
|
||||
aivalue += ci.count * ci.cre->getAIValue();
|
||||
aivalue += ci.count * ci.creID.toCreature()->getAIValue();
|
||||
}
|
||||
|
||||
return aivalue;
|
||||
@ -320,7 +320,7 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
|
||||
|
||||
if(i < GameConstants::CREATURES_PER_TOWN && countGrowth)
|
||||
{
|
||||
ci.count += town ? town->creatureGrowth(i) : ci.cre->getGrowth();
|
||||
ci.count += town ? town->creatureGrowth(i) : ci.creID.toCreature()->getGrowth();
|
||||
}
|
||||
|
||||
if(!ci.count) continue;
|
||||
@ -334,13 +334,13 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
|
||||
freeHeroSlots--; //new slot will be occupied
|
||||
}
|
||||
|
||||
vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford
|
||||
vstd::amin(ci.count, availableRes / ci.creID.toCreature()->getFullRecruitCost()); //max count we can afford
|
||||
|
||||
if(!ci.count) continue;
|
||||
|
||||
ci.level = i; //this is important for Dungeon Summoning Portal
|
||||
creaturesInDwellings.push_back(ci);
|
||||
availableRes -= ci.cre->getFullRecruitCost() * ci.count;
|
||||
availableRes -= ci.creID.toCreature()->getFullRecruitCost() * ci.count;
|
||||
}
|
||||
|
||||
return creaturesInDwellings;
|
||||
|
@ -165,7 +165,7 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
||||
|
||||
auto addTownHero = [&](const CGTownInstance * town)
|
||||
{
|
||||
auto townHero = new CGHeroInstance();
|
||||
auto townHero = new CGHeroInstance(town->cb);
|
||||
CRandomGenerator rng;
|
||||
auto visitablePos = town->visitablePos();
|
||||
|
||||
|
@ -30,7 +30,7 @@ ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
|
||||
|
||||
ui64 totalStrength = 0;
|
||||
ui8 totalChance = 0;
|
||||
for(auto config : bankInfo->getPossibleGuards())
|
||||
for(auto config : bankInfo->getPossibleGuards(bank->cb))
|
||||
{
|
||||
totalStrength += config.second.totalStrength * config.first;
|
||||
totalChance += config.first;
|
||||
|
@ -141,7 +141,7 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
|
||||
{
|
||||
auto objectInfo = target->getObjectHandler()->getObjectInfo(target->appearance);
|
||||
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
|
||||
auto creatures = bankInfo->getPossibleCreaturesReward();
|
||||
auto creatures = bankInfo->getPossibleCreaturesReward(target->cb);
|
||||
uint64_t result = 0;
|
||||
|
||||
const auto& slots = hero->Slots();
|
||||
@ -236,7 +236,7 @@ int getDwellingArmyCost(const CGObjectInstance * target)
|
||||
return cost;
|
||||
}
|
||||
|
||||
uint64_t evaluateArtifactArmyValue(CArtifactInstance * art)
|
||||
static uint64_t evaluateArtifactArmyValue(const CArtifactInstance * art)
|
||||
{
|
||||
if(art->artType->getId() == ArtifactID::SPELL_SCROLL)
|
||||
return 1500;
|
||||
|
@ -54,12 +54,12 @@ void BuyArmy::accept(AIGateway * ai)
|
||||
if(objid != CreatureID::NONE && ci.creID.getNum() != objid)
|
||||
continue;
|
||||
|
||||
vstd::amin(ci.count, res / ci.cre->getFullRecruitCost());
|
||||
vstd::amin(ci.count, res / ci.creID.toCreature()->getFullRecruitCost());
|
||||
|
||||
if(ci.count)
|
||||
{
|
||||
cb->recruitCreatures(town, town->getUpperArmy(), ci.creID, ci.count, ci.level);
|
||||
valueBought += ci.count * ci.cre->getAIValue();
|
||||
valueBought += ci.count * ci.creID.toCreature()->getAIValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ std::string CompleteQuest::questToString() const
|
||||
return "inactive quest";
|
||||
|
||||
MetaString ms;
|
||||
q.quest->getRolloverText(ms, false);
|
||||
q.quest->getRolloverText(q.obj->cb, ms, false);
|
||||
|
||||
return ms.toString();
|
||||
}
|
||||
|
@ -373,10 +373,10 @@ HeroExchangeArmy * HeroExchangeMap::tryUpgrade(
|
||||
|
||||
for(auto & creatureToBuy : buyArmy)
|
||||
{
|
||||
auto targetSlot = target->getSlotFor(dynamic_cast<const CCreature*>(creatureToBuy.cre));
|
||||
auto targetSlot = target->getSlotFor(creatureToBuy.creID.toCreature());
|
||||
|
||||
target->addToSlot(targetSlot, creatureToBuy.creID, creatureToBuy.count);
|
||||
target->armyCost += creatureToBuy.cre->getFullRecruitCost() * creatureToBuy.count;
|
||||
target->armyCost += creatureToBuy.creID.toCreature()->getFullRecruitCost() * creatureToBuy.count;
|
||||
target->requireBuyArmy = true;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
virtual bool needsLastStack() const override;
|
||||
std::shared_ptr<SpecialAction> getActorAction() const;
|
||||
|
||||
HeroExchangeArmy(): CArmedInstance(true), requireBuyArmy(false) {}
|
||||
HeroExchangeArmy(): CArmedInstance(nullptr, true), requireBuyArmy(false) {}
|
||||
};
|
||||
|
||||
struct ExchangeResult
|
||||
|
@ -72,7 +72,7 @@ ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
|
||||
|
||||
ui64 totalStrength = 0;
|
||||
ui8 totalChance = 0;
|
||||
for(auto config : bankInfo->getPossibleGuards())
|
||||
for(auto config : bankInfo->getPossibleGuards(bank->cb))
|
||||
{
|
||||
totalStrength += config.second.totalStrength * config.first;
|
||||
totalChance += config.first;
|
||||
|
@ -103,7 +103,7 @@ std::string CompleteQuest::questToString() const
|
||||
return "inactive quest";
|
||||
|
||||
MetaString ms;
|
||||
q.quest->getRolloverText(ms, false);
|
||||
q.quest->getRolloverText(q.obj->cb, ms, false);
|
||||
|
||||
return ms.toString();
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/gameState/CGameState.h"
|
||||
#include "../../lib/bonuses/CBonusSystemNode.h"
|
||||
#include "../../lib/bonuses/Limiters.h"
|
||||
#include "../../lib/bonuses/Updaters.h"
|
||||
#include "../../lib/bonuses/Propagators.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "client/Client.h"
|
||||
#include "lib/mapping/CMap.h"
|
||||
#include "lib/mapObjects/CGHeroInstance.h"
|
||||
#include "lib/mapObjects/CGTownInstance.h"
|
||||
#include "lib/CBuildingHandler.h"
|
||||
#include "lib/CGeneralTextHandler.h"
|
||||
#include "lib/CHeroHandler.h"
|
||||
|
@ -12,16 +12,13 @@
|
||||
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
|
||||
const CGameInfo * CGI;
|
||||
CGameInfo * CGI;
|
||||
CClientState * CCS = nullptr;
|
||||
CServerHandler * CSH;
|
||||
|
||||
|
||||
CGameInfo::CGameInfo()
|
||||
{
|
||||
generaltexth = nullptr;
|
||||
mh = nullptr;
|
||||
townh = nullptr;
|
||||
globalServices = nullptr;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ extern CClientState * CCS;
|
||||
|
||||
/// CGameInfo class
|
||||
/// for allowing different functions for accessing game informations
|
||||
class CGameInfo : public Services
|
||||
class CGameInfo final : public Services
|
||||
{
|
||||
public:
|
||||
const ArtifactService * artifacts() const override;
|
||||
@ -78,19 +78,20 @@ public:
|
||||
const spells::effects::Registry * spellEffects() const override;
|
||||
spells::effects::Registry * spellEffects() override;
|
||||
|
||||
ConstTransitivePtr<CModHandler> modh; //public?
|
||||
ConstTransitivePtr<BattleFieldHandler> battleFieldHandler;
|
||||
ConstTransitivePtr<CHeroHandler> heroh;
|
||||
ConstTransitivePtr<CCreatureHandler> creh;
|
||||
ConstTransitivePtr<CSpellHandler> spellh;
|
||||
ConstTransitivePtr<CSkillHandler> skillh;
|
||||
ConstTransitivePtr<CObjectHandler> objh;
|
||||
ConstTransitivePtr<TerrainTypeHandler> terrainTypeHandler;
|
||||
ConstTransitivePtr<CObjectClassesHandler> objtypeh;
|
||||
ConstTransitivePtr<ObstacleHandler> obstacleHandler;
|
||||
CGeneralTextHandler * generaltexth;
|
||||
CMapHandler * mh;
|
||||
CTownHandler * townh;
|
||||
std::shared_ptr<const CModHandler> modh;
|
||||
std::shared_ptr<const BattleFieldHandler> battleFieldHandler;
|
||||
std::shared_ptr<const CHeroHandler> heroh;
|
||||
std::shared_ptr<const CCreatureHandler> creh;
|
||||
std::shared_ptr<const CSpellHandler> spellh;
|
||||
std::shared_ptr<const CSkillHandler> skillh;
|
||||
std::shared_ptr<const CObjectHandler> objh;
|
||||
std::shared_ptr<const TerrainTypeHandler> terrainTypeHandler;
|
||||
std::shared_ptr<const CObjectClassesHandler> objtypeh;
|
||||
std::shared_ptr<const ObstacleHandler> obstacleHandler;
|
||||
std::shared_ptr<const CGeneralTextHandler> generaltexth;
|
||||
std::shared_ptr<const CTownHandler> townh;
|
||||
|
||||
std::shared_ptr<CMapHandler> mh;
|
||||
|
||||
void setFromLib();
|
||||
|
||||
@ -98,4 +99,4 @@ public:
|
||||
private:
|
||||
const Services * globalServices;
|
||||
};
|
||||
extern const CGameInfo* CGI;
|
||||
extern CGameInfo* CGI;
|
||||
|
@ -72,7 +72,7 @@ void init()
|
||||
CStopWatch tmh;
|
||||
|
||||
loadDLLClasses();
|
||||
const_cast<CGameInfo*>(CGI)->setFromLib();
|
||||
CGI->setFromLib();
|
||||
|
||||
logGlobal->info("Initializing VCMI_Lib: %d ms", tmh.getDiff());
|
||||
|
||||
|
@ -82,7 +82,6 @@
|
||||
#include "../lib/UnlockGuard.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
|
||||
#include "../lib/bonuses/CBonusSystemNode.h"
|
||||
#include "../lib/bonuses/Limiters.h"
|
||||
#include "../lib/bonuses/Propagators.h"
|
||||
#include "../lib/bonuses/Updaters.h"
|
||||
|
@ -142,6 +142,8 @@ CServerHandler::CServerHandler()
|
||||
registerTypesLobbyPacks(*applier);
|
||||
}
|
||||
|
||||
CServerHandler::~CServerHandler() = default;
|
||||
|
||||
void CServerHandler::resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names)
|
||||
{
|
||||
hostClientId = -1;
|
||||
@ -260,6 +262,9 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
|
||||
addr.size() ? addr : getHostAddress(),
|
||||
port ? port : getHostPort(),
|
||||
NAME, uuid);
|
||||
|
||||
nextClient = std::make_unique<CClient>();
|
||||
c->iser.cb = nextClient.get();
|
||||
}
|
||||
catch(std::runtime_error & error)
|
||||
{
|
||||
@ -636,7 +641,8 @@ void CServerHandler::startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameSta
|
||||
{
|
||||
if(CMM)
|
||||
CMM->disable();
|
||||
client = new CClient();
|
||||
|
||||
std::swap(client, nextClient);
|
||||
|
||||
highScoreCalc = nullptr;
|
||||
|
||||
@ -687,7 +693,7 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
||||
}
|
||||
|
||||
client->endGame();
|
||||
vstd::clear_pointer(client);
|
||||
client.reset();
|
||||
|
||||
if(!restart)
|
||||
{
|
||||
@ -704,6 +710,8 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
||||
|
||||
if(c)
|
||||
{
|
||||
nextClient = std::make_unique<CClient>();
|
||||
c->iser.cb = nextClient.get();
|
||||
c->enterLobbyConnectionMode();
|
||||
c->disableStackSendingByID();
|
||||
}
|
||||
|
@ -95,6 +95,10 @@ class CServerHandler : public IServerAPI, public LobbyInfo
|
||||
|
||||
std::shared_ptr<HighScoreCalculation> highScoreCalc;
|
||||
|
||||
/// temporary helper member that exists while game in lobby mode
|
||||
/// required to correctly deserialize gamestate using client-side game callback
|
||||
std::unique_ptr<CClient> nextClient;
|
||||
|
||||
void threadHandleConnection();
|
||||
void threadRunServer();
|
||||
void onServerFinished();
|
||||
@ -116,13 +120,14 @@ public:
|
||||
std::shared_ptr<boost::thread> threadRunLocalServer;
|
||||
|
||||
std::shared_ptr<CConnection> c;
|
||||
CClient * client;
|
||||
std::unique_ptr<CClient> client;
|
||||
|
||||
CondSh<bool> campaignServerRestartLock;
|
||||
|
||||
static const std::string localhostAddress;
|
||||
|
||||
CServerHandler();
|
||||
~CServerHandler();
|
||||
|
||||
std::string getHostAddress() const;
|
||||
ui16 getHostPort() const;
|
||||
|
@ -139,14 +139,10 @@ CClient::CClient()
|
||||
waitingRequest.clear();
|
||||
applier = std::make_shared<CApplier<CBaseForCLApply>>();
|
||||
registerTypesClientPacks(*applier);
|
||||
IObjectInterface::cb = this;
|
||||
gs = nullptr;
|
||||
}
|
||||
|
||||
CClient::~CClient()
|
||||
{
|
||||
IObjectInterface::cb = nullptr;
|
||||
}
|
||||
CClient::~CClient() = default;
|
||||
|
||||
const Services * CClient::services() const
|
||||
{
|
||||
@ -177,8 +173,9 @@ void CClient::newGame(CGameState * initializedGameState)
|
||||
{
|
||||
CSH->th->update();
|
||||
CMapService mapService;
|
||||
gs = initializedGameState ? initializedGameState : new CGameState();
|
||||
gs->preInit(VLC);
|
||||
assert(initializedGameState);
|
||||
gs = initializedGameState;
|
||||
gs->preInit(VLC, this);
|
||||
logNetwork->trace("\tCreating gamestate: %i", CSH->th->getDiff());
|
||||
if(!initializedGameState)
|
||||
{
|
||||
@ -200,7 +197,7 @@ void CClient::loadGame(CGameState * initializedGameState)
|
||||
logNetwork->info("Game state was transferred over network, loading.");
|
||||
gs = initializedGameState;
|
||||
|
||||
gs->preInit(VLC);
|
||||
gs->preInit(VLC, this);
|
||||
gs->updateOnLoad(CSH->si.get());
|
||||
logNetwork->info("Game loaded, initialize interfaces.");
|
||||
|
||||
@ -370,7 +367,7 @@ void CClient::endGame()
|
||||
logNetwork->info("Ending current game!");
|
||||
removeGUI();
|
||||
|
||||
vstd::clear_pointer(const_cast<CGameInfo *>(CGI)->mh);
|
||||
CGI->mh.reset();
|
||||
vstd::clear_pointer(gs);
|
||||
|
||||
logNetwork->info("Deleted mapHandler and gameState.");
|
||||
@ -392,7 +389,7 @@ void CClient::initMapHandler()
|
||||
// During loading CPlayerInterface from serialized state it's depend on MH
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
const_cast<CGameInfo *>(CGI)->mh = new CMapHandler(gs->map);
|
||||
CGI->mh = std::make_shared<CMapHandler>(gs->map);
|
||||
logNetwork->trace("Creating mapHandler: %d ms", CSH->th->getDiff());
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ void ClientCommandManager::handleConvertTextCommand()
|
||||
try
|
||||
{
|
||||
// load and drop loaded map - we only need loader to run over all maps
|
||||
mapService.loadMap(mapName);
|
||||
mapService.loadMap(mapName, nullptr);
|
||||
}
|
||||
catch(std::exception & e)
|
||||
{
|
||||
@ -216,7 +216,7 @@ void ClientCommandManager::handleConvertTextCommand()
|
||||
{
|
||||
auto state = CampaignHandler::getCampaign(campaignName.getName());
|
||||
for (auto const & part : state->allScenarios())
|
||||
state->getMap(part);
|
||||
state->getMap(part, nullptr);
|
||||
}
|
||||
|
||||
VLC->generaltexth->dumpAllTexts();
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "../lib/StartInfo.h"
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "../lib/mapObjects/CGMarket.h"
|
||||
#include "../lib/mapObjects/CGTownInstance.h"
|
||||
#include "../lib/gameState/CGameState.h"
|
||||
#include "../lib/CStack.h"
|
||||
#include "../lib/battle/BattleInfo.h"
|
||||
|
@ -530,7 +530,7 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
|
||||
if (hasGraphics)
|
||||
{
|
||||
//FIXME: support permanent duration
|
||||
int duration = stack->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(effect)))->turnsRemain;
|
||||
int duration = stack->getFirstBonus(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(effect)))->turnsRemain;
|
||||
|
||||
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));
|
||||
if(settings["general"]["enableUiEnhancements"].Bool())
|
||||
|
@ -601,7 +601,7 @@ void BattleWindow::bSpellf()
|
||||
{
|
||||
//TODO: move to spell mechanics, add more information to spell cast problem
|
||||
//Handle Orb of Inhibition-like effects -> we want to display dialog with info, why casting is impossible
|
||||
auto blockingBonus = owner.currentHero()->getBonusLocalFirst(Selector::type()(BonusType::BLOCK_ALL_MAGIC));
|
||||
auto blockingBonus = owner.currentHero()->getFirstBonus(Selector::type()(BonusType::BLOCK_ALL_MAGIC));
|
||||
if (!blockingBonus)
|
||||
return;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "../../lib/Point.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapObjects/MiscObjects.h"
|
||||
#include "../../lib/spells/CSpellHandler.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../../lib/pathfinder/CGPathNode.h"
|
||||
|
@ -225,7 +225,7 @@ CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int
|
||||
spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds."
|
||||
boost::replace_first(spellText, "%s", spell->getNameTranslated());
|
||||
//FIXME: support permanent duration
|
||||
int duration = battleStack->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(effect)))->turnsRemain;
|
||||
int duration = battleStack->getFirstBonus(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(effect)))->turnsRemain;
|
||||
boost::replace_first(spellText, "%d", std::to_string(duration));
|
||||
|
||||
spellIcons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));
|
||||
|
@ -104,7 +104,7 @@ std::vector<Canvas> CMapOverviewWidget::createMinimaps(ResourcePath resource) co
|
||||
std::unique_ptr<CMap> map;
|
||||
try
|
||||
{
|
||||
map = mapService.loadMap(resource);
|
||||
map = mapService.loadMap(resource, nullptr);
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
@ -169,7 +169,7 @@ CMapOverviewWidget::CMapOverviewWidget(CMapOverview& parent):
|
||||
lf >> *(mapHeader) >> startInfo;
|
||||
|
||||
if(startInfo->campState)
|
||||
campaignMap = startInfo->campState->getMap(*startInfo->campState->currentScenario());
|
||||
campaignMap = startInfo->campState->getMap(*startInfo->campState->currentScenario(), nullptr);
|
||||
res = ResourcePath(startInfo->fileURI, EResType::MAP);
|
||||
}
|
||||
if(!campaignMap)
|
||||
|
@ -160,7 +160,7 @@ void CQuestLog::recreateLabelList()
|
||||
}
|
||||
|
||||
MetaString text;
|
||||
quests[i].quest->getRolloverText (text, false);
|
||||
quests[i].quest->getRolloverText (quests[i].obj->cb, text, false);
|
||||
if (quests[i].obj)
|
||||
{
|
||||
if (auto seersHut = dynamic_cast<const CGSeerHut *>(quests[i].obj))
|
||||
@ -236,7 +236,7 @@ void CQuestLog::selectQuest(int which, int labelId)
|
||||
|
||||
MetaString text;
|
||||
std::vector<Component> components;
|
||||
currentQuest->quest->getVisitText(text, components, true);
|
||||
currentQuest->quest->getVisitText(currentQuest->obj->cb, text, components, true);
|
||||
if(description->slider)
|
||||
description->slider->scrollToMin(); // scroll text to start position
|
||||
description->setText(text.toString()); //TODO: use special log entry text
|
||||
|
@ -619,6 +619,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/CThreadHelper.h
|
||||
${MAIN_LIB_DIR}/CTownHandler.h
|
||||
${MAIN_LIB_DIR}/FunctionList.h
|
||||
${MAIN_LIB_DIR}/GameCallbackHolder.h
|
||||
${MAIN_LIB_DIR}/GameConstants.h
|
||||
${MAIN_LIB_DIR}/GameSettings.h
|
||||
${MAIN_LIB_DIR}/IBonusTypeHandler.h
|
||||
|
@ -187,14 +187,14 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
||||
|
||||
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createScroll(const SpellID & sid)
|
||||
{
|
||||
auto ret = new CArtifactInstance(VLC->arth->objects[ArtifactID::SPELL_SCROLL]);
|
||||
auto ret = new CArtifactInstance(ArtifactID(ArtifactID::SPELL_SCROLL).toArtifact());
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELL,
|
||||
BonusSource::ARTIFACT_INSTANCE, -1, BonusSourceID(ArtifactID(ArtifactID::SPELL_SCROLL)), BonusSubtypeID(sid));
|
||||
ret->addNewBonus(bonus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(CArtifact * art)
|
||||
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const CArtifact * art)
|
||||
{
|
||||
assert(art);
|
||||
|
||||
@ -216,7 +216,7 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(CArtifa
|
||||
|
||||
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const ArtifactID & aid)
|
||||
{
|
||||
return ArtifactUtils::createNewArtifactInstance((*VLC->arth)[aid]);
|
||||
return ArtifactUtils::createNewArtifactInstance(aid.toArtifact());
|
||||
}
|
||||
|
||||
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID)
|
||||
|
@ -40,7 +40,7 @@ namespace ArtifactUtils
|
||||
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
|
||||
DLL_LINKAGE std::vector<const CArtifact*> assemblyPossibilities(const CArtifactSet * artSet, const ArtifactID & aid);
|
||||
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
|
||||
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(CArtifact * art);
|
||||
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const CArtifact * art);
|
||||
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
|
||||
DLL_LINKAGE CArtifactInstance * createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID = SpellID::NONE);
|
||||
DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid);
|
||||
|
@ -49,12 +49,12 @@ bool CCombinedArtifact::isCombined() const
|
||||
return !(constituents.empty());
|
||||
}
|
||||
|
||||
const std::vector<CArtifact*> & CCombinedArtifact::getConstituents() const
|
||||
const std::vector<const CArtifact*> & CCombinedArtifact::getConstituents() const
|
||||
{
|
||||
return constituents;
|
||||
}
|
||||
|
||||
const std::vector<CArtifact*> & CCombinedArtifact::getPartOf() const
|
||||
const std::vector<const CArtifact*> & CCombinedArtifact::getPartOf() const
|
||||
{
|
||||
return partOf;
|
||||
}
|
||||
@ -328,7 +328,7 @@ std::vector<JsonNode> CArtHandler::loadLegacyData()
|
||||
const std::vector<std::string> artSlots = { ART_POS_LIST };
|
||||
#undef ART_POS
|
||||
|
||||
static std::map<char, std::string> classes =
|
||||
static const std::map<char, std::string> classes =
|
||||
{{'S',"SPECIAL"}, {'T',"TREASURE"},{'N',"MINOR"},{'J',"MAJOR"},{'R',"RELIC"},};
|
||||
|
||||
CLegacyConfigParser parser(TextPath::builtin("DATA/ARTRAITS.TXT"));
|
||||
@ -353,7 +353,7 @@ std::vector<JsonNode> CArtHandler::loadLegacyData()
|
||||
artData["slot"].Vector().back().String() = artSlot;
|
||||
}
|
||||
}
|
||||
artData["class"].String() = classes[parser.readString()[0]];
|
||||
artData["class"].String() = classes.at(parser.readString()[0]);
|
||||
artData["text"]["description"].String() = parser.readString();
|
||||
|
||||
parser.endLine();
|
||||
@ -597,7 +597,7 @@ void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node)
|
||||
{
|
||||
// when this code is called both combinational art as well as component are loaded
|
||||
// so it is safe to access any of them
|
||||
art->constituents.push_back(objects[id]);
|
||||
art->constituents.push_back(ArtifactID(id).toArtifact());
|
||||
objects[id]->partOf.push_back(art);
|
||||
});
|
||||
}
|
||||
|
@ -47,12 +47,12 @@ class DLL_LINKAGE CCombinedArtifact
|
||||
protected:
|
||||
CCombinedArtifact() = default;
|
||||
|
||||
std::vector<CArtifact*> constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
|
||||
std::vector<CArtifact*> partOf; // Reverse map of constituents - combined arts that include this art
|
||||
std::vector<const CArtifact*> constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
|
||||
std::vector<const CArtifact*> partOf; // Reverse map of constituents - combined arts that include this art
|
||||
public:
|
||||
bool isCombined() const;
|
||||
const std::vector<CArtifact*> & getConstituents() const;
|
||||
const std::vector<CArtifact*> & getPartOf() const;
|
||||
const std::vector<const CArtifact*> & getConstituents() const;
|
||||
const std::vector<const CArtifact*> & getPartOf() const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CScrollArtifact
|
||||
|
@ -62,7 +62,7 @@ void CCombinedArtifactInstance::addPlacementMap(CArtifactSet::ArtPlacementMap &
|
||||
SpellID CScrollArtifactInstance::getScrollSpellID() const
|
||||
{
|
||||
auto artInst = static_cast<const CArtifactInstance*>(this);
|
||||
const auto bonus = artInst->getBonusLocalFirst(Selector::type()(BonusType::SPELL));
|
||||
const auto bonus = artInst->getFirstBonus(Selector::type()(BonusType::SPELL));
|
||||
if(!bonus)
|
||||
return SpellID::NONE;
|
||||
return bonus->subtype.as<SpellID>();
|
||||
@ -107,7 +107,7 @@ void CArtifactInstance::init()
|
||||
setNodeType(ARTIFACT_INSTANCE);
|
||||
}
|
||||
|
||||
CArtifactInstance::CArtifactInstance(CArtifact * art)
|
||||
CArtifactInstance::CArtifactInstance(const CArtifact * art)
|
||||
{
|
||||
init();
|
||||
setType(art);
|
||||
@ -118,10 +118,10 @@ CArtifactInstance::CArtifactInstance()
|
||||
init();
|
||||
}
|
||||
|
||||
void CArtifactInstance::setType(CArtifact * art)
|
||||
void CArtifactInstance::setType(const CArtifact * art)
|
||||
{
|
||||
artType = art;
|
||||
attachTo(*art);
|
||||
attachToSource(*art);
|
||||
}
|
||||
|
||||
std::string CArtifactInstance::nodeName() const
|
||||
|
@ -73,11 +73,11 @@ protected:
|
||||
|
||||
ArtifactInstanceID id;
|
||||
public:
|
||||
ConstTransitivePtr<CArtifact> artType;
|
||||
const CArtifact * artType = nullptr;
|
||||
|
||||
CArtifactInstance(CArtifact * art);
|
||||
CArtifactInstance(const CArtifact * art);
|
||||
CArtifactInstance();
|
||||
void setType(CArtifact * art);
|
||||
void setType(const CArtifact * art);
|
||||
std::string nodeName() const override;
|
||||
std::string getDescription() const;
|
||||
ArtifactID getTypeId() const;
|
||||
|
@ -407,20 +407,9 @@ void CCreature::serializeJson(JsonSerializeFormat & handler)
|
||||
CCreatureHandler::CCreatureHandler()
|
||||
: expAfterUpgrade(0)
|
||||
{
|
||||
VLC->creh = this;
|
||||
loadCommanders();
|
||||
}
|
||||
|
||||
const CCreature * CCreatureHandler::getCreature(const std::string & scope, const std::string & identifier) const
|
||||
{
|
||||
std::optional<si32> index = VLC->identifiers()->getIdentifier(scope, "creature", identifier);
|
||||
|
||||
if(!index)
|
||||
throw std::runtime_error("Creature not found "+identifier);
|
||||
|
||||
return objects[*index];
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadCommanders()
|
||||
{
|
||||
auto configResource = JsonPath::builtin("config/commanders.json");
|
||||
@ -797,7 +786,7 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects)
|
||||
bl.clear();
|
||||
loadStackExp(b, bl, parser);
|
||||
for(const auto & b : bl)
|
||||
(*this)[sid]->addNewBonus(b); //add directly to CCreature Node
|
||||
objects[sid.getNum()]->addNewBonus(b); //add directly to CCreature Node
|
||||
}
|
||||
while (parser.endLine());
|
||||
|
||||
|
@ -222,8 +222,6 @@ public:
|
||||
std::vector< std::vector <ui8> > skillLevels; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE
|
||||
std::vector <std::pair <std::shared_ptr<Bonus>, std::pair <ui8, ui8> > > skillRequirements; // first - Bonus, second - which two skills are needed to use it
|
||||
|
||||
const CCreature * getCreature(const std::string & scope, const std::string & identifier) const;
|
||||
|
||||
CreatureID pickRandomMonster(CRandomGenerator & rand, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
|
||||
|
||||
CCreatureHandler();
|
||||
|
@ -739,11 +739,10 @@ void CStackInstance::giveStackExp(TExpType exp)
|
||||
if (!vstd::iswithin(level, 1, 7))
|
||||
level = 0;
|
||||
|
||||
CCreatureHandler * creh = VLC->creh;
|
||||
ui32 maxExp = creh->expRanks[level].back();
|
||||
ui32 maxExp = VLC->creh->expRanks[level].back();
|
||||
|
||||
vstd::amin(exp, static_cast<TExpType>(maxExp)); //prevent exp overflow due to different types
|
||||
vstd::amin(exp, (maxExp * creh->maxExpPerBattle[level])/100);
|
||||
vstd::amin(exp, (maxExp * VLC->creh->maxExpPerBattle[level])/100);
|
||||
vstd::amin(experience += exp, maxExp); //can't get more exp than this limit
|
||||
}
|
||||
|
||||
@ -759,7 +758,7 @@ void CStackInstance::setType(const CCreature *c)
|
||||
{
|
||||
if(type)
|
||||
{
|
||||
detachFrom(const_cast<CCreature&>(*type));
|
||||
detachFromSource(*type);
|
||||
if (type->isMyUpgrade(c) && VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
experience = static_cast<TExpType>(experience * VLC->creh->expAfterUpgrade / 100.0);
|
||||
}
|
||||
@ -767,7 +766,7 @@ void CStackInstance::setType(const CCreature *c)
|
||||
CStackBasicDescriptor::setType(c);
|
||||
|
||||
if(type)
|
||||
attachTo(const_cast<CCreature&>(*type));
|
||||
attachToSource(*type);
|
||||
}
|
||||
std::string CStackInstance::bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const
|
||||
{
|
||||
@ -1055,7 +1054,7 @@ void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler)
|
||||
std::string typeName;
|
||||
handler.serializeString("type", typeName);
|
||||
if(!typeName.empty())
|
||||
setType(VLC->creh->getCreature(ModScope::scopeMap(), typeName));
|
||||
setType(CreatureID(CreatureID::decode(typeName)).toCreature());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "gameState/TavernHeroesPool.h"
|
||||
#include "gameState/QuestInfo.h"
|
||||
#include "mapObjects/CGHeroInstance.h"
|
||||
#include "mapObjects/CGTownInstance.h"
|
||||
#include "mapObjects/MiscObjects.h"
|
||||
#include "networkPacks/ArtifactLocation.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "StartInfo.h" // for StartInfo
|
||||
@ -382,7 +384,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
||||
if(creature->getFaction() == factionIndex && static_cast<int>(creature->getAIValue()) > maxAIValue)
|
||||
{
|
||||
maxAIValue = creature->getAIValue();
|
||||
mostStrong = creature;
|
||||
mostStrong = creature.get();
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,7 +793,7 @@ int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool
|
||||
|
||||
int3 CPlayerSpecificInfoCallback::getGrailPos( double *outKnownRatio )
|
||||
{
|
||||
if (!getPlayerID() || CGObelisk::obeliskCount == 0)
|
||||
if (!getPlayerID() || gs->map->obeliskCount == 0)
|
||||
{
|
||||
*outKnownRatio = 0.0;
|
||||
}
|
||||
@ -799,10 +801,10 @@ int3 CPlayerSpecificInfoCallback::getGrailPos( double *outKnownRatio )
|
||||
{
|
||||
TeamID t = gs->getPlayerTeam(*getPlayerID())->id;
|
||||
double visited = 0.0;
|
||||
if(CGObelisk::visited.count(t))
|
||||
visited = static_cast<double>(CGObelisk::visited[t]);
|
||||
if(gs->map->obelisksVisited.count(t))
|
||||
visited = static_cast<double>(gs->map->obelisksVisited[t]);
|
||||
|
||||
*outKnownRatio = visited / CGObelisk::obeliskCount;
|
||||
*outKnownRatio = visited / gs->map->obeliskCount;
|
||||
}
|
||||
return gs->map->grailPos;
|
||||
}
|
||||
|
@ -155,6 +155,14 @@ bool CHeroClass::isMagicHero() const
|
||||
return affinity == MAGIC;
|
||||
}
|
||||
|
||||
int CHeroClass::tavernProbability(FactionID targetFaction) const
|
||||
{
|
||||
auto it = selectionProbability.find(targetFaction);
|
||||
if (it != selectionProbability.end())
|
||||
return it->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EAlignment CHeroClass::getAlignment() const
|
||||
{
|
||||
return VLC->factions()->getById(faction)->getAlignment();
|
||||
@ -292,7 +300,7 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js
|
||||
VLC->identifiers()->requestIdentifier ("creature", node["commander"],
|
||||
[=](si32 commanderID)
|
||||
{
|
||||
heroClass->commander = VLC->creh->objects[commanderID];
|
||||
heroClass->commander = CreatureID(commanderID).toCreature();
|
||||
});
|
||||
|
||||
heroClass->defaultTavernChance = static_cast<ui32>(node["defaultTavern"].Float());
|
||||
@ -369,9 +377,9 @@ std::vector<JsonNode> CHeroClassHandler::loadLegacyData()
|
||||
void CHeroClassHandler::afterLoadFinalization()
|
||||
{
|
||||
// for each pair <class, town> set selection probability if it was not set before in tavern entries
|
||||
for(CHeroClass * heroClass : objects)
|
||||
for(auto & heroClass : objects)
|
||||
{
|
||||
for(CFaction * faction : VLC->townh->objects)
|
||||
for(auto & faction : VLC->townh->objects)
|
||||
{
|
||||
if (!faction->town)
|
||||
continue;
|
||||
@ -394,9 +402,9 @@ void CHeroClassHandler::afterLoadFinalization()
|
||||
}
|
||||
}
|
||||
|
||||
for(CHeroClass * hc : objects)
|
||||
for(const auto & hc : objects)
|
||||
{
|
||||
if (!hc->imageMapMale.empty())
|
||||
if(!hc->imageMapMale.empty())
|
||||
{
|
||||
JsonNode templ;
|
||||
templ["animation"].String() = hc->imageMapMale;
|
||||
@ -454,7 +462,7 @@ CHero * CHeroHandler::loadFromJson(const std::string & scope, const JsonNode & n
|
||||
VLC->identifiers()->requestIdentifier("heroClass", node["class"],
|
||||
[=](si32 classID)
|
||||
{
|
||||
hero->heroClass = classes[HeroClassID(classID)];
|
||||
hero->heroClass = HeroClassID(classID).toHeroClass();
|
||||
});
|
||||
|
||||
return hero;
|
||||
@ -532,7 +540,7 @@ static std::vector<std::shared_ptr<Bonus>> createCreatureSpecialty(CreatureID ba
|
||||
{
|
||||
std::set<CreatureID> oldTargets = targets;
|
||||
|
||||
for (auto const & upgradeSourceID : oldTargets)
|
||||
for(const auto & upgradeSourceID : oldTargets)
|
||||
{
|
||||
const CCreature * upgradeSource = upgradeSourceID.toCreature();
|
||||
targets.insert(upgradeSource->upgrades.begin(), upgradeSource->upgrades.end());
|
||||
@ -544,7 +552,7 @@ static std::vector<std::shared_ptr<Bonus>> createCreatureSpecialty(CreatureID ba
|
||||
|
||||
for(CreatureID cid : targets)
|
||||
{
|
||||
auto const & specCreature = *cid.toCreature();
|
||||
const auto & specCreature = *cid.toCreature();
|
||||
int stepSize = specCreature.getLevel() ? specCreature.getLevel() : 5;
|
||||
|
||||
{
|
||||
@ -604,7 +612,7 @@ void CHeroHandler::beforeValidate(JsonNode & object)
|
||||
|
||||
void CHeroHandler::afterLoadFinalization()
|
||||
{
|
||||
for (auto const & functor : callAfterLoadFinalization)
|
||||
for(const auto & functor : callAfterLoadFinalization)
|
||||
functor();
|
||||
|
||||
callAfterLoadFinalization.clear();
|
||||
@ -790,7 +798,7 @@ std::set<HeroTypeID> CHeroHandler::getDefaultAllowed() const
|
||||
{
|
||||
std::set<HeroTypeID> result;
|
||||
|
||||
for(const CHero * hero : objects)
|
||||
for(auto & hero : objects)
|
||||
if (hero && !hero->special)
|
||||
result.insert(hero->getId());
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
|
||||
std::vector<InitialArmyStack> initialArmy;
|
||||
|
||||
CHeroClass * heroClass{};
|
||||
const CHeroClass * heroClass = nullptr;
|
||||
std::vector<std::pair<SecondarySkill, ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
|
||||
BonusList specialty;
|
||||
std::set<SpellID> spells;
|
||||
@ -121,7 +121,7 @@ public:
|
||||
// resulting chance = sqrt(town.chance * heroClass.chance)
|
||||
ui32 defaultTavernChance;
|
||||
|
||||
CCreature * commander;
|
||||
const CCreature * commander;
|
||||
|
||||
std::vector<int> primarySkillInitial; // initial primary skills
|
||||
std::vector<int> primarySkillLowLevel; // probability (%) of getting point of primary skill when getting level
|
||||
@ -154,6 +154,8 @@ public:
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
EAlignment getAlignment() const;
|
||||
|
||||
int tavernProbability(FactionID faction) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CHeroClassHandler : public CHandlerBase<HeroClassID, HeroClass, CHeroClass, HeroClassService>
|
||||
@ -189,8 +191,6 @@ class DLL_LINKAGE CHeroHandler : public CHandlerBase<HeroTypeID, HeroType, CHero
|
||||
std::vector<std::function<void()>> callAfterLoadFinalization;
|
||||
|
||||
public:
|
||||
CHeroClassHandler classes;
|
||||
|
||||
ui32 level(TExpType experience) const; //calculates level corresponding to given experience amount
|
||||
TExpType reqExp(ui32 level) const; //calculates experience required for given level
|
||||
ui32 maxSupportedLevel() const;
|
||||
|
@ -23,8 +23,6 @@ PlayerState::PlayerState()
|
||||
setNodeType(PLAYER);
|
||||
}
|
||||
|
||||
PlayerState::PlayerState(PlayerState && other) noexcept = default;
|
||||
|
||||
PlayerState::~PlayerState() = default;
|
||||
|
||||
std::string PlayerState::nodeName() const
|
||||
|
@ -67,7 +67,6 @@ public:
|
||||
TurnTimerInfo turnTimer;
|
||||
|
||||
PlayerState();
|
||||
PlayerState(PlayerState && other) noexcept;
|
||||
~PlayerState();
|
||||
|
||||
std::string nodeName() const override;
|
||||
@ -123,7 +122,6 @@ public:
|
||||
std::unique_ptr<boost::multi_array<ui8, 3>> fogOfWarMap; //[z][x][y] true - visible, false - hidden
|
||||
|
||||
TeamState();
|
||||
TeamState(TeamState && other) noexcept;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ void CStack::localInit(BattleInfo * battleInfo)
|
||||
CArmedInstance * army = battle->battleGetArmyObject(side);
|
||||
assert(army);
|
||||
attachTo(*army);
|
||||
attachTo(const_cast<CCreature&>(*type));
|
||||
attachToSource(*type);
|
||||
}
|
||||
nativeTerrain = getNativeTerrain(); //save nativeTerrain in the variable on the battle start to avoid dead lock
|
||||
CUnitState::localInit(this); //it causes execution of the CStack::isOnNativeTerrain where nativeTerrain will be considered
|
||||
|
@ -336,9 +336,9 @@ JsonNode readBuilding(CLegacyConfigParser & parser)
|
||||
return ret;
|
||||
}
|
||||
|
||||
TPropagatorPtr & CTownHandler::emptyPropagator()
|
||||
const TPropagatorPtr & CTownHandler::emptyPropagator()
|
||||
{
|
||||
static TPropagatorPtr emptyProp(nullptr);
|
||||
static const TPropagatorPtr emptyProp(nullptr);
|
||||
return emptyProp;
|
||||
}
|
||||
|
||||
@ -534,7 +534,7 @@ R CTownHandler::getMappedValue(const JsonNode & node, const R defval, const std:
|
||||
void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building) const
|
||||
{
|
||||
std::shared_ptr<Bonus> b;
|
||||
static TPropagatorPtr playerPropagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::ENodeTypes::PLAYER);
|
||||
static const TPropagatorPtr playerPropagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::ENodeTypes::PLAYER);
|
||||
|
||||
if(building->bid == BuildingID::TAVERN)
|
||||
{
|
||||
@ -578,7 +578,7 @@ std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType ty
|
||||
return createBonus(build, type, val, subtype, emptyPropagator());
|
||||
}
|
||||
|
||||
std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType type, int val, BonusSubtypeID subtype, TPropagatorPtr & prop) const
|
||||
std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType type, int val, BonusSubtypeID subtype, const TPropagatorPtr & prop) const
|
||||
{
|
||||
std::ostringstream descr;
|
||||
descr << build->getNameTranslated();
|
||||
@ -589,7 +589,7 @@ std::shared_ptr<Bonus> CTownHandler::createBonusImpl(const BuildingID & building
|
||||
const FactionID & faction,
|
||||
BonusType type,
|
||||
int val,
|
||||
TPropagatorPtr & prop,
|
||||
const TPropagatorPtr & prop,
|
||||
const std::string & description,
|
||||
BonusSubtypeID subtype) const
|
||||
{
|
||||
@ -991,7 +991,7 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source)
|
||||
|
||||
VLC->identifiers()->requestIdentifier(node.second.meta, "heroClass",node.first, [=](si32 classID)
|
||||
{
|
||||
VLC->heroh->classes[HeroClassID(classID)]->selectionProbability[town->faction->getId()] = chance;
|
||||
VLC->heroclassesh->objects[classID]->selectionProbability[town->faction->getId()] = chance;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ class DLL_LINKAGE CTownHandler : public CHandlerBase<FactionID, Faction, CFactio
|
||||
std::vector<BuildingRequirementsHelper> requirementsToLoad;
|
||||
std::vector<BuildingRequirementsHelper> overriddenBidsToLoad; //list of buildings, which bonuses should be overridden.
|
||||
|
||||
static TPropagatorPtr & emptyPropagator();
|
||||
static const TPropagatorPtr & emptyPropagator();
|
||||
|
||||
void initializeRequirements();
|
||||
void initializeOverridden();
|
||||
@ -303,12 +303,12 @@ class DLL_LINKAGE CTownHandler : public CHandlerBase<FactionID, Faction, CFactio
|
||||
|
||||
std::shared_ptr<Bonus> createBonus(CBuilding * build, BonusType type, int val) const;
|
||||
std::shared_ptr<Bonus> createBonus(CBuilding * build, BonusType type, int val, BonusSubtypeID subtype) const;
|
||||
std::shared_ptr<Bonus> createBonus(CBuilding * build, BonusType type, int val, BonusSubtypeID subtype, TPropagatorPtr & prop) const;
|
||||
std::shared_ptr<Bonus> createBonus(CBuilding * build, BonusType type, int val, BonusSubtypeID subtype, const TPropagatorPtr & prop) const;
|
||||
std::shared_ptr<Bonus> createBonusImpl(const BuildingID & building,
|
||||
const FactionID & faction,
|
||||
BonusType type,
|
||||
int val,
|
||||
TPropagatorPtr & prop,
|
||||
const TPropagatorPtr & prop,
|
||||
const std::string & description,
|
||||
BonusSubtypeID subtype) const;
|
||||
|
||||
|
26
lib/GameCallbackHolder.h
Normal file
26
lib/GameCallbackHolder.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* GameCallbackHolder.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
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class IGameCallback;
|
||||
|
||||
class DLL_LINKAGE GameCallbackHolder
|
||||
{
|
||||
public:
|
||||
IGameCallback * const cb;
|
||||
|
||||
explicit GameCallbackHolder(IGameCallback *cb):
|
||||
cb(cb)
|
||||
{}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -16,7 +16,6 @@
|
||||
#include "CBonusTypeHandler.h"
|
||||
#include "BattleFieldHandler.h"
|
||||
#include "ObstacleHandler.h"
|
||||
#include "bonuses/CBonusSystemNode.h"
|
||||
#include "bonuses/Limiters.h"
|
||||
#include "bonuses/Propagators.h"
|
||||
#include "bonuses/Updaters.h"
|
||||
@ -26,7 +25,10 @@
|
||||
#include "rmg/CMapGenOptions.h"
|
||||
#include "mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "mapObjects/CGTownInstance.h"
|
||||
#include "mapObjects/CObjectHandler.h"
|
||||
#include "mapObjects/CQuest.h"
|
||||
#include "mapObjects/MiscObjects.h"
|
||||
#include "mapObjects/ObjectTemplate.h"
|
||||
#include "campaign/CampaignState.h"
|
||||
#include "StartInfo.h"
|
||||
|
@ -44,11 +44,21 @@ public:
|
||||
/// allows handler to do post-loading step for validation or integration of loaded data
|
||||
virtual void afterLoadFinalization(){};
|
||||
|
||||
virtual ~IHandlerBase(){}
|
||||
virtual ~IHandlerBase() = default;
|
||||
};
|
||||
|
||||
template <class _ObjectID, class _ObjectBase, class _Object, class _ServiceBase> class CHandlerBase : public _ServiceBase, public IHandlerBase
|
||||
{
|
||||
const _Object * getObjectImpl(const int32_t index) const
|
||||
{
|
||||
if(index < 0 || index >= objects.size())
|
||||
{
|
||||
logMod->error("%s id %d is invalid", getTypeNames()[0], index);
|
||||
throw std::runtime_error("Attempt to access invalid index " + std::to_string(index) + " of type " + getTypeNames().front());
|
||||
}
|
||||
return objects[index].get();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~CHandlerBase()
|
||||
{
|
||||
@ -56,22 +66,21 @@ public:
|
||||
{
|
||||
o.dellNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const Entity * getBaseByIndex(const int32_t index) const override
|
||||
{
|
||||
return getByIndex(index);
|
||||
return getObjectImpl(index);
|
||||
}
|
||||
|
||||
const _ObjectBase * getById(const _ObjectID & id) const override
|
||||
{
|
||||
return (*this)[id].get();
|
||||
return getObjectImpl(id.getNum());
|
||||
}
|
||||
|
||||
const _ObjectBase * getByIndex(const int32_t index) const override
|
||||
{
|
||||
return (*this)[_ObjectID(index)].get();
|
||||
return getObjectImpl(index);
|
||||
}
|
||||
|
||||
void forEachBase(const std::function<void(const Entity * entity, bool & stop)> & cb) const override
|
||||
@ -105,21 +114,14 @@ public:
|
||||
registerObject(scope, type_name, name, object->getIndex());
|
||||
}
|
||||
|
||||
ConstTransitivePtr<_Object> operator[] (const _ObjectID id) const
|
||||
const _Object * operator[] (const _ObjectID id) const
|
||||
{
|
||||
const int32_t raw_id = id.getNum();
|
||||
return operator[](raw_id);
|
||||
return getObjectImpl(id.getNum());
|
||||
}
|
||||
|
||||
ConstTransitivePtr<_Object> operator[] (int32_t index) const
|
||||
const _Object * operator[] (int32_t index) const
|
||||
{
|
||||
if(index < 0 || index >= objects.size())
|
||||
{
|
||||
logMod->error("%s id %d is invalid", getTypeNames()[0], index);
|
||||
throw std::runtime_error("Attempt to access invalid index " + std::to_string(index) + " of type " + getTypeNames().front());
|
||||
}
|
||||
|
||||
return objects[index];
|
||||
return getObjectImpl(index);
|
||||
}
|
||||
|
||||
void updateEntity(int32_t index, const JsonNode & data)
|
||||
|
@ -690,7 +690,6 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonVector & ability_vec)
|
||||
template <typename T>
|
||||
const T parseByMap(const std::map<std::string, T> & map, const JsonNode * val, const std::string & err)
|
||||
{
|
||||
static T defaultValue = T();
|
||||
if (!val->isNull())
|
||||
{
|
||||
const std::string & type = val->String();
|
||||
@ -698,7 +697,7 @@ const T parseByMap(const std::map<std::string, T> & map, const JsonNode * val, c
|
||||
if (it == map.end())
|
||||
{
|
||||
logMod->error("Error: invalid %s%s.", err, type);
|
||||
return defaultValue;
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -706,7 +705,7 @@ const T parseByMap(const std::map<std::string, T> & map, const JsonNode * val, c
|
||||
}
|
||||
}
|
||||
else
|
||||
return defaultValue;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -31,9 +31,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
namespace JsonRandom
|
||||
{
|
||||
si32 loadVariable(std::string variableGroup, const std::string & value, const Variables & variables, si32 defaultValue)
|
||||
si32 JsonRandom::loadVariable(const std::string & variableGroup, const std::string & value, const Variables & variables, si32 defaultValue)
|
||||
{
|
||||
if (value.empty() || value[0] != '@')
|
||||
{
|
||||
@ -51,12 +49,12 @@ namespace JsonRandom
|
||||
return variables.at(variableID);
|
||||
}
|
||||
|
||||
si32 loadValue(const JsonNode & value, CRandomGenerator & rng, const Variables & variables, si32 defaultValue)
|
||||
si32 JsonRandom::loadValue(const JsonNode & value, CRandomGenerator & rng, const Variables & variables, si32 defaultValue)
|
||||
{
|
||||
if(value.isNull())
|
||||
return defaultValue;
|
||||
if(value.isNumber())
|
||||
return static_cast<si32>(value.Float());
|
||||
return value.Integer();
|
||||
if (value.isString())
|
||||
return loadVariable("number", value.String(), variables, defaultValue);
|
||||
|
||||
@ -70,16 +68,16 @@ namespace JsonRandom
|
||||
if(value.isStruct())
|
||||
{
|
||||
if (!value["amount"].isNull())
|
||||
return static_cast<si32>(loadValue(value["amount"], rng, variables, defaultValue));
|
||||
si32 min = static_cast<si32>(loadValue(value["min"], rng, variables, 0));
|
||||
si32 max = static_cast<si32>(loadValue(value["max"], rng, variables, 0));
|
||||
return loadValue(value["amount"], rng, variables, defaultValue);
|
||||
si32 min = loadValue(value["min"], rng, variables, 0);
|
||||
si32 max = loadValue(value["max"], rng, variables, 0);
|
||||
return rng.getIntRange(min, max)();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
template<typename IdentifierType>
|
||||
IdentifierType decodeKey(const std::string & modScope, const std::string & value, const Variables & variables)
|
||||
IdentifierType JsonRandom::decodeKey(const std::string & modScope, const std::string & value, const Variables & variables)
|
||||
{
|
||||
if (value.empty() || value[0] != '@')
|
||||
return IdentifierType(*VLC->identifiers()->getIdentifier(modScope, IdentifierType::entityType(), value));
|
||||
@ -88,7 +86,7 @@ namespace JsonRandom
|
||||
}
|
||||
|
||||
template<typename IdentifierType>
|
||||
IdentifierType decodeKey(const JsonNode & value, const Variables & variables)
|
||||
IdentifierType JsonRandom::decodeKey(const JsonNode & value, const Variables & variables)
|
||||
{
|
||||
if (value.String().empty() || value.String()[0] != '@')
|
||||
return IdentifierType(*VLC->identifiers()->getIdentifier(IdentifierType::entityType(), value));
|
||||
@ -97,19 +95,19 @@ namespace JsonRandom
|
||||
}
|
||||
|
||||
template<>
|
||||
PlayerColor decodeKey(const JsonNode & value, const Variables & variables)
|
||||
PlayerColor JsonRandom::decodeKey(const JsonNode & value, const Variables & variables)
|
||||
{
|
||||
return PlayerColor(*VLC->identifiers()->getIdentifier("playerColor", value));
|
||||
}
|
||||
|
||||
template<>
|
||||
PrimarySkill decodeKey(const JsonNode & value, const Variables & variables)
|
||||
PrimarySkill JsonRandom::decodeKey(const JsonNode & value, const Variables & variables)
|
||||
{
|
||||
return PrimarySkill(*VLC->identifiers()->getIdentifier("primarySkill", value));
|
||||
}
|
||||
|
||||
template<>
|
||||
PrimarySkill decodeKey(const std::string & modScope, const std::string & value, const Variables & variables)
|
||||
PrimarySkill JsonRandom::decodeKey(const std::string & modScope, const std::string & value, const Variables & variables)
|
||||
{
|
||||
if (value.empty() || value[0] != '@')
|
||||
return PrimarySkill(*VLC->identifiers()->getIdentifier(modScope, "primarySkill", value));
|
||||
@ -120,13 +118,13 @@ namespace JsonRandom
|
||||
/// Method that allows type-specific object filtering
|
||||
/// Default implementation is to accept all input objects
|
||||
template<typename IdentifierType>
|
||||
std::set<IdentifierType> filterKeysTyped(const JsonNode & value, const std::set<IdentifierType> & valuesSet)
|
||||
std::set<IdentifierType> JsonRandom::filterKeysTyped(const JsonNode & value, const std::set<IdentifierType> & valuesSet)
|
||||
{
|
||||
return valuesSet;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::set<ArtifactID> filterKeysTyped(const JsonNode & value, const std::set<ArtifactID> & valuesSet)
|
||||
std::set<ArtifactID> JsonRandom::filterKeysTyped(const JsonNode & value, const std::set<ArtifactID> & valuesSet)
|
||||
{
|
||||
assert(value.isStruct());
|
||||
|
||||
@ -164,7 +162,7 @@ namespace JsonRandom
|
||||
if(!allowedClasses.empty() && !allowedClasses.count(art->aClass))
|
||||
continue;
|
||||
|
||||
if(!IObjectInterface::cb->isAllowed(art->getId()))
|
||||
if(!cb->isAllowed(art->getId()))
|
||||
continue;
|
||||
|
||||
if(!allowedPositions.empty())
|
||||
@ -186,7 +184,7 @@ namespace JsonRandom
|
||||
}
|
||||
|
||||
template<>
|
||||
std::set<SpellID> filterKeysTyped(const JsonNode & value, const std::set<SpellID> & valuesSet)
|
||||
std::set<SpellID> JsonRandom::filterKeysTyped(const JsonNode & value, const std::set<SpellID> & valuesSet)
|
||||
{
|
||||
std::set<SpellID> result = valuesSet;
|
||||
|
||||
@ -213,7 +211,7 @@ namespace JsonRandom
|
||||
}
|
||||
|
||||
template<typename IdentifierType>
|
||||
std::set<IdentifierType> filterKeys(const JsonNode & value, const std::set<IdentifierType> & valuesSet, const Variables & variables)
|
||||
std::set<IdentifierType> JsonRandom::filterKeys(const JsonNode & value, const std::set<IdentifierType> & valuesSet, const Variables & variables)
|
||||
{
|
||||
if(value.isString())
|
||||
return { decodeKey<IdentifierType>(value, variables) };
|
||||
@ -257,7 +255,7 @@ namespace JsonRandom
|
||||
return valuesSet;
|
||||
}
|
||||
|
||||
TResources loadResources(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
TResources JsonRandom::loadResources(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
TResources ret;
|
||||
|
||||
@ -275,7 +273,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
TResources loadResource(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
TResources JsonRandom::loadResource(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::set<GameResID> defaultResources{
|
||||
GameResID::WOOD,
|
||||
@ -296,7 +294,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
PrimarySkill loadPrimary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
PrimarySkill JsonRandom::loadPrimary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::set<PrimarySkill> defaultSkills{
|
||||
PrimarySkill::ATTACK,
|
||||
@ -308,7 +306,7 @@ namespace JsonRandom
|
||||
return *RandomGeneratorUtil::nextItem(potentialPicks, rng);
|
||||
}
|
||||
|
||||
std::vector<si32> loadPrimaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
std::vector<si32> JsonRandom::loadPrimaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::vector<si32> ret(GameConstants::PRIMARY_SKILLS, 0);
|
||||
std::set<PrimarySkill> defaultSkills{
|
||||
@ -340,18 +338,18 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
SecondarySkill loadSecondary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
SecondarySkill JsonRandom::loadSecondary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::set<SecondarySkill> defaultSkills;
|
||||
for(const auto & skill : VLC->skillh->objects)
|
||||
if (IObjectInterface::cb->isAllowed(skill->getId()))
|
||||
if (cb->isAllowed(skill->getId()))
|
||||
defaultSkills.insert(skill->getId());
|
||||
|
||||
std::set<SecondarySkill> potentialPicks = filterKeys(value, defaultSkills, variables);
|
||||
return *RandomGeneratorUtil::nextItem(potentialPicks, rng);
|
||||
}
|
||||
|
||||
std::map<SecondarySkill, si32> loadSecondaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
std::map<SecondarySkill, si32> JsonRandom::loadSecondaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::map<SecondarySkill, si32> ret;
|
||||
if(value.isStruct())
|
||||
@ -366,7 +364,7 @@ namespace JsonRandom
|
||||
{
|
||||
std::set<SecondarySkill> defaultSkills;
|
||||
for(const auto & skill : VLC->skillh->objects)
|
||||
if (IObjectInterface::cb->isAllowed(skill->getId()))
|
||||
if (cb->isAllowed(skill->getId()))
|
||||
defaultSkills.insert(skill->getId());
|
||||
|
||||
for(const auto & element : value.Vector())
|
||||
@ -381,19 +379,19 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
ArtifactID loadArtifact(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
ArtifactID JsonRandom::loadArtifact(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::set<ArtifactID> allowedArts;
|
||||
for(const auto & artifact : VLC->arth->objects)
|
||||
if (IObjectInterface::cb->isAllowed(artifact->getId()) && VLC->arth->legalArtifact(artifact->getId()))
|
||||
if (cb->isAllowed(artifact->getId()) && VLC->arth->legalArtifact(artifact->getId()))
|
||||
allowedArts.insert(artifact->getId());
|
||||
|
||||
std::set<ArtifactID> potentialPicks = filterKeys(value, allowedArts, variables);
|
||||
|
||||
return IObjectInterface::cb->gameState()->pickRandomArtifact(rng, potentialPicks);
|
||||
return cb->gameState()->pickRandomArtifact(rng, potentialPicks);
|
||||
}
|
||||
|
||||
std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
std::vector<ArtifactID> JsonRandom::loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::vector<ArtifactID> ret;
|
||||
for (const JsonNode & entry : value.Vector())
|
||||
@ -403,11 +401,11 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
SpellID loadSpell(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
SpellID JsonRandom::loadSpell(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::set<SpellID> defaultSpells;
|
||||
for(const auto & spell : VLC->spellh->objects)
|
||||
if (IObjectInterface::cb->isAllowed(spell->getId()) && !spell->isSpecial())
|
||||
if (cb->isAllowed(spell->getId()) && !spell->isSpecial())
|
||||
defaultSpells.insert(spell->getId());
|
||||
|
||||
std::set<SpellID> potentialPicks = filterKeys(value, defaultSpells, variables);
|
||||
@ -420,7 +418,7 @@ namespace JsonRandom
|
||||
return *RandomGeneratorUtil::nextItem(potentialPicks, rng);
|
||||
}
|
||||
|
||||
std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
std::vector<SpellID> JsonRandom::loadSpells(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::vector<SpellID> ret;
|
||||
for (const JsonNode & entry : value.Vector())
|
||||
@ -430,7 +428,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<PlayerColor> loadColors(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
std::vector<PlayerColor> JsonRandom::loadColors(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::vector<PlayerColor> ret;
|
||||
std::set<PlayerColor> defaultPlayers;
|
||||
@ -446,7 +444,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<HeroTypeID> loadHeroes(const JsonNode & value, CRandomGenerator & rng)
|
||||
std::vector<HeroTypeID> JsonRandom::loadHeroes(const JsonNode & value, CRandomGenerator & rng)
|
||||
{
|
||||
std::vector<HeroTypeID> ret;
|
||||
for(auto & entry : value.Vector())
|
||||
@ -456,7 +454,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, CRandomGenerator & rng)
|
||||
std::vector<HeroClassID> JsonRandom::loadHeroClasses(const JsonNode & value, CRandomGenerator & rng)
|
||||
{
|
||||
std::vector<HeroClassID> ret;
|
||||
for(auto & entry : value.Vector())
|
||||
@ -466,7 +464,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
CStackBasicDescriptor JsonRandom::loadCreature(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
CStackBasicDescriptor stack;
|
||||
|
||||
@ -495,7 +493,7 @@ namespace JsonRandom
|
||||
return stack;
|
||||
}
|
||||
|
||||
std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
std::vector<CStackBasicDescriptor> JsonRandom::loadCreatures(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
|
||||
{
|
||||
std::vector<CStackBasicDescriptor> ret;
|
||||
for (const JsonNode & node : value.Vector())
|
||||
@ -505,7 +503,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<RandomStackInfo> evaluateCreatures(const JsonNode & value, const Variables & variables)
|
||||
std::vector<JsonRandom::RandomStackInfo> JsonRandom::evaluateCreatures(const JsonNode & value, const Variables & variables)
|
||||
{
|
||||
std::vector<RandomStackInfo> ret;
|
||||
for (const JsonNode & node : value.Vector())
|
||||
@ -519,7 +517,8 @@ namespace JsonRandom
|
||||
info.minAmount = static_cast<si32>(node["min"].Float());
|
||||
info.maxAmount = static_cast<si32>(node["max"].Float());
|
||||
}
|
||||
const CCreature * crea = VLC->creh->objects[VLC->identifiers()->getIdentifier("creature", node["type"]).value()];
|
||||
CreatureID creatureID(VLC->identifiers()->getIdentifier("creature", node["type"]).value());
|
||||
const CCreature * crea = creatureID.toCreature();
|
||||
info.allowedCreatures.push_back(crea);
|
||||
if (node["upgradeChance"].Float() > 0)
|
||||
{
|
||||
@ -531,7 +530,7 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<Bonus> DLL_LINKAGE loadBonuses(const JsonNode & value)
|
||||
std::vector<Bonus> JsonRandom::loadBonuses(const JsonNode & value)
|
||||
{
|
||||
std::vector<Bonus> ret;
|
||||
for (const JsonNode & entry : value.Vector())
|
||||
@ -542,6 +541,4 @@ namespace JsonRandom
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "GameConstants.h"
|
||||
#include "ResourceSet.h"
|
||||
#include "GameCallbackHolder.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -22,10 +23,29 @@ struct Bonus;
|
||||
struct Component;
|
||||
class CStackBasicDescriptor;
|
||||
|
||||
namespace JsonRandom
|
||||
class DLL_LINKAGE JsonRandom : public GameCallbackHolder
|
||||
{
|
||||
public:
|
||||
using Variables = std::map<std::string, int>;
|
||||
|
||||
private:
|
||||
template<typename IdentifierType>
|
||||
std::set<IdentifierType> filterKeys(const JsonNode & value, const std::set<IdentifierType> & valuesSet, const Variables & variables);
|
||||
|
||||
template<typename IdentifierType>
|
||||
std::set<IdentifierType> filterKeysTyped(const JsonNode & value, const std::set<IdentifierType> & valuesSet);
|
||||
|
||||
template<typename IdentifierType>
|
||||
IdentifierType decodeKey(const std::string & modScope, const std::string & value, const Variables & variables);
|
||||
|
||||
template<typename IdentifierType>
|
||||
IdentifierType decodeKey(const JsonNode & value, const Variables & variables);
|
||||
|
||||
si32 loadVariable(const std::string & variableGroup, const std::string & value, const Variables & variables, si32 defaultValue);
|
||||
|
||||
public:
|
||||
using GameCallbackHolder::GameCallbackHolder;
|
||||
|
||||
struct DLL_LINKAGE RandomStackInfo
|
||||
{
|
||||
std::vector<const CCreature *> allowedCreatures;
|
||||
@ -33,30 +53,30 @@ namespace JsonRandom
|
||||
si32 maxAmount;
|
||||
};
|
||||
|
||||
DLL_LINKAGE si32 loadValue(const JsonNode & value, CRandomGenerator & rng, const Variables & variables, si32 defaultValue = 0);
|
||||
si32 loadValue(const JsonNode & value, CRandomGenerator & rng, const Variables & variables, si32 defaultValue = 0);
|
||||
|
||||
DLL_LINKAGE TResources loadResources(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE TResources loadResource(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE PrimarySkill loadPrimary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::vector<si32> loadPrimaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE SecondarySkill loadSecondary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::map<SecondarySkill, si32> loadSecondaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
TResources loadResources(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
TResources loadResource(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
PrimarySkill loadPrimary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::vector<si32> loadPrimaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
SecondarySkill loadSecondary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::map<SecondarySkill, si32> loadSecondaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
|
||||
DLL_LINKAGE ArtifactID loadArtifact(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
ArtifactID loadArtifact(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
|
||||
DLL_LINKAGE SpellID loadSpell(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
SpellID loadSpell(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
|
||||
DLL_LINKAGE CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::vector<RandomStackInfo> evaluateCreatures(const JsonNode & value, const Variables & variables);
|
||||
CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::vector<RandomStackInfo> evaluateCreatures(const JsonNode & value, const Variables & variables);
|
||||
|
||||
DLL_LINKAGE std::vector<PlayerColor> loadColors(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
DLL_LINKAGE std::vector<HeroTypeID> loadHeroes(const JsonNode & value, CRandomGenerator & rng);
|
||||
DLL_LINKAGE std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, CRandomGenerator & rng);
|
||||
std::vector<PlayerColor> loadColors(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
|
||||
std::vector<HeroTypeID> loadHeroes(const JsonNode & value, CRandomGenerator & rng);
|
||||
std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, CRandomGenerator & rng);
|
||||
|
||||
DLL_LINKAGE std::vector<Bonus> loadBonuses(const JsonNode & value);
|
||||
}
|
||||
static std::vector<Bonus> loadBonuses(const JsonNode & value);
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
RiverTypeHandler::RiverTypeHandler()
|
||||
{
|
||||
objects.push_back(new RiverType);
|
||||
objects.push_back(new RiverType());
|
||||
|
||||
VLC->generaltexth->registerString("core", objects[0]->getNameTextID(), "");
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
RoadTypeHandler::RoadTypeHandler()
|
||||
{
|
||||
objects.push_back(new RoadType);
|
||||
objects.push_back(new RoadType());
|
||||
|
||||
VLC->generaltexth->registerString("core", objects[0]->getNameTextID(), "");
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ FactionID PlayerSettings::getCastleValidated() const
|
||||
{
|
||||
if (!castle.isValid())
|
||||
return FactionID(0);
|
||||
if (castle.getNum() < VLC->townh->size() && VLC->townh->objects[castle.getNum()]->town != nullptr)
|
||||
if (castle.getNum() < VLC->townh->size() && castle.toEntity(VLC)->hasTown())
|
||||
return castle;
|
||||
|
||||
return FactionID(0);
|
||||
|
114
lib/VCMI_Lib.cpp
114
lib/VCMI_Lib.cpp
@ -65,54 +65,54 @@ DLL_LINKAGE void loadDLLClasses(bool onlyEssential)
|
||||
|
||||
const ArtifactService * LibClasses::artifacts() const
|
||||
{
|
||||
return arth;
|
||||
return arth.get();
|
||||
}
|
||||
|
||||
const CreatureService * LibClasses::creatures() const
|
||||
{
|
||||
return creh;
|
||||
return creh.get();
|
||||
}
|
||||
|
||||
const FactionService * LibClasses::factions() const
|
||||
{
|
||||
return townh;
|
||||
return townh.get();
|
||||
}
|
||||
|
||||
const HeroClassService * LibClasses::heroClasses() const
|
||||
{
|
||||
return &heroh->classes;
|
||||
return heroclassesh.get();
|
||||
}
|
||||
|
||||
const HeroTypeService * LibClasses::heroTypes() const
|
||||
{
|
||||
return heroh;
|
||||
return heroh.get();
|
||||
}
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
const scripting::Service * LibClasses::scripts() const
|
||||
{
|
||||
return scriptHandler;
|
||||
return scriptHandler.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
const spells::Service * LibClasses::spells() const
|
||||
{
|
||||
return spellh;
|
||||
return spellh.get();
|
||||
}
|
||||
|
||||
const SkillService * LibClasses::skills() const
|
||||
{
|
||||
return skillh;
|
||||
return skillh.get();
|
||||
}
|
||||
|
||||
const IBonusTypeHandler * LibClasses::getBth() const
|
||||
{
|
||||
return bth;
|
||||
return bth.get();
|
||||
}
|
||||
|
||||
const CIdentifierStorage * LibClasses::identifiers() const
|
||||
{
|
||||
return identifiersHandler;
|
||||
return identifiersHandler.get();
|
||||
}
|
||||
|
||||
const spells::effects::Registry * LibClasses::spellEffects() const
|
||||
@ -127,17 +127,17 @@ spells::effects::Registry * LibClasses::spellEffects()
|
||||
|
||||
const BattleFieldService * LibClasses::battlefields() const
|
||||
{
|
||||
return battlefieldsHandler;
|
||||
return battlefieldsHandler.get();
|
||||
}
|
||||
|
||||
const ObstacleService * LibClasses::obstacles() const
|
||||
{
|
||||
return obstacleHandler;
|
||||
return obstacleHandler.get();
|
||||
}
|
||||
|
||||
const IGameSettings * LibClasses::settings() const
|
||||
{
|
||||
return settingsHandler;
|
||||
return settingsHandler.get();
|
||||
}
|
||||
|
||||
void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data)
|
||||
@ -154,7 +154,7 @@ void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode &
|
||||
townh->updateEntity(index, data);
|
||||
break;
|
||||
case Metatype::HERO_CLASS:
|
||||
heroh->classes.updateEntity(index, data);
|
||||
heroclassesh->updateEntity(index, data);
|
||||
break;
|
||||
case Metatype::HERO_TYPE:
|
||||
heroh->updateEntity(index, data);
|
||||
@ -185,8 +185,8 @@ void LibClasses::loadFilesystem(bool extractArchives)
|
||||
void LibClasses::loadModFilesystem()
|
||||
{
|
||||
CStopWatch loadTime;
|
||||
modh = new CModHandler();
|
||||
identifiersHandler = new CIdentifierStorage();
|
||||
modh = std::make_unique<CModHandler>();
|
||||
identifiersHandler = std::make_unique<CIdentifierStorage>();
|
||||
modh->loadMods();
|
||||
logGlobal->info("\tMod handler: %d ms", loadTime.getDiff());
|
||||
|
||||
@ -199,9 +199,9 @@ static void logHandlerLoaded(const std::string & name, CStopWatch & timer)
|
||||
logGlobal->info("\t\t %s handler: %d ms", name, timer.getDiff());
|
||||
}
|
||||
|
||||
template <class Handler> void createHandler(Handler *&handler, const std::string &name, CStopWatch &timer)
|
||||
template <class Handler> void createHandler(std::shared_ptr<Handler> & handler, const std::string &name, CStopWatch &timer)
|
||||
{
|
||||
handler = new Handler();
|
||||
handler = std::make_shared<Handler>();
|
||||
logHandlerLoaded(name, timer);
|
||||
}
|
||||
|
||||
@ -219,6 +219,7 @@ void LibClasses::init(bool onlyEssential)
|
||||
createHandler(riverTypeHandler, "River", pomtime);
|
||||
createHandler(terrainTypeHandler, "Terrain", pomtime);
|
||||
createHandler(heroh, "Hero", pomtime);
|
||||
createHandler(heroclassesh, "Hero classes", pomtime);
|
||||
createHandler(arth, "Artifact", pomtime);
|
||||
createHandler(creh, "Creature", pomtime);
|
||||
createHandler(townh, "Town", pomtime);
|
||||
@ -239,77 +240,6 @@ void LibClasses::init(bool onlyEssential)
|
||||
modh->afterLoad(onlyEssential);
|
||||
}
|
||||
|
||||
void LibClasses::clear()
|
||||
{
|
||||
delete heroh;
|
||||
delete arth;
|
||||
delete creh;
|
||||
delete townh;
|
||||
delete objh;
|
||||
delete objtypeh;
|
||||
delete spellh;
|
||||
delete skillh;
|
||||
delete modh;
|
||||
delete bth;
|
||||
delete tplh;
|
||||
delete terviewh;
|
||||
#if SCRIPTING_ENABLED
|
||||
delete scriptHandler;
|
||||
#endif
|
||||
delete battlefieldsHandler;
|
||||
delete generaltexth;
|
||||
delete identifiersHandler;
|
||||
delete obstacleHandler;
|
||||
delete terrainTypeHandler;
|
||||
delete riverTypeHandler;
|
||||
delete roadTypeHandler;
|
||||
delete settingsHandler;
|
||||
makeNull();
|
||||
}
|
||||
|
||||
void LibClasses::makeNull()
|
||||
{
|
||||
generaltexth = nullptr;
|
||||
heroh = nullptr;
|
||||
arth = nullptr;
|
||||
creh = nullptr;
|
||||
townh = nullptr;
|
||||
objh = nullptr;
|
||||
objtypeh = nullptr;
|
||||
spellh = nullptr;
|
||||
skillh = nullptr;
|
||||
modh = nullptr;
|
||||
bth = nullptr;
|
||||
tplh = nullptr;
|
||||
terviewh = nullptr;
|
||||
#if SCRIPTING_ENABLED
|
||||
scriptHandler = nullptr;
|
||||
#endif
|
||||
battlefieldsHandler = nullptr;
|
||||
identifiersHandler = nullptr;
|
||||
obstacleHandler = nullptr;
|
||||
terrainTypeHandler = nullptr;
|
||||
riverTypeHandler = nullptr;
|
||||
roadTypeHandler = nullptr;
|
||||
settingsHandler = nullptr;
|
||||
}
|
||||
|
||||
LibClasses::LibClasses()
|
||||
{
|
||||
//init pointers to handlers
|
||||
makeNull();
|
||||
}
|
||||
|
||||
void LibClasses::callWhenDeserializing()
|
||||
{
|
||||
//FIXME: check if any of these are needed
|
||||
//generaltexth = new CGeneralTextHandler();
|
||||
//generaltexth->load();
|
||||
//arth->load(true);
|
||||
//modh->recreateHandlers();
|
||||
//modh->loadConfigFromFile ("defaultMods"); //TODO: remember last saved config
|
||||
}
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
void LibClasses::scriptsLoaded()
|
||||
{
|
||||
@ -317,10 +247,8 @@ void LibClasses::scriptsLoaded()
|
||||
}
|
||||
#endif
|
||||
|
||||
LibClasses::~LibClasses()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
LibClasses::LibClasses() = default;
|
||||
LibClasses::~LibClasses() = default;
|
||||
|
||||
std::shared_ptr<CContentHandler> LibClasses::getContent() const
|
||||
{
|
||||
|
@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class CConsoleHandler;
|
||||
class CArtHandler;
|
||||
class CHeroHandler;
|
||||
class CHeroClassHandler;
|
||||
class CCreatureHandler;
|
||||
class CSpellHandler;
|
||||
class CSkillHandler;
|
||||
@ -47,20 +48,15 @@ namespace scripting
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// Loads and constructs several handlers
|
||||
class DLL_LINKAGE LibClasses : public Services
|
||||
class DLL_LINKAGE LibClasses final : public Services
|
||||
{
|
||||
CBonusTypeHandler * bth;
|
||||
std::shared_ptr<CBonusTypeHandler> bth;
|
||||
|
||||
void callWhenDeserializing(); //should be called only by serialize !!!
|
||||
void makeNull(); //sets all handler pointers to null
|
||||
std::shared_ptr<CContentHandler> getContent() const;
|
||||
void setContent(std::shared_ptr<CContentHandler> content);
|
||||
|
||||
public:
|
||||
bool IS_AI_ENABLED = false; //unused?
|
||||
|
||||
const ArtifactService * artifacts() const override;
|
||||
const CreatureService * creatures() const override;
|
||||
const FactionService * factions() const override;
|
||||
@ -83,35 +79,34 @@ public:
|
||||
const IBonusTypeHandler * getBth() const; //deprecated
|
||||
const CIdentifierStorage * identifiers() const;
|
||||
|
||||
CArtHandler * arth;
|
||||
CHeroHandler * heroh;
|
||||
CCreatureHandler * creh;
|
||||
CSpellHandler * spellh;
|
||||
CSkillHandler * skillh;
|
||||
CObjectHandler * objh;
|
||||
CObjectClassesHandler * objtypeh;
|
||||
CTownHandler * townh;
|
||||
CGeneralTextHandler * generaltexth;
|
||||
CModHandler * modh;
|
||||
std::shared_ptr<CArtHandler> arth;
|
||||
std::shared_ptr<CHeroHandler> heroh;
|
||||
std::shared_ptr<CHeroClassHandler> heroclassesh;
|
||||
std::shared_ptr<CCreatureHandler> creh;
|
||||
std::shared_ptr<CSpellHandler> spellh;
|
||||
std::shared_ptr<CSkillHandler> skillh;
|
||||
std::shared_ptr<CObjectHandler> objh;
|
||||
std::shared_ptr<CObjectClassesHandler> objtypeh;
|
||||
std::shared_ptr<CTownHandler> townh;
|
||||
std::shared_ptr<CGeneralTextHandler> generaltexth;
|
||||
std::shared_ptr<CModHandler> modh;
|
||||
std::shared_ptr<TerrainTypeHandler> terrainTypeHandler;
|
||||
std::shared_ptr<RoadTypeHandler> roadTypeHandler;
|
||||
std::shared_ptr<RiverTypeHandler> riverTypeHandler;
|
||||
std::shared_ptr<CIdentifierStorage> identifiersHandler;
|
||||
std::shared_ptr<CTerrainViewPatternConfig> terviewh;
|
||||
std::shared_ptr<CRmgTemplateStorage> tplh;
|
||||
std::shared_ptr<BattleFieldHandler> battlefieldsHandler;
|
||||
std::shared_ptr<ObstacleHandler> obstacleHandler;
|
||||
std::shared_ptr<GameSettings> settingsHandler;
|
||||
|
||||
TerrainTypeHandler * terrainTypeHandler;
|
||||
RoadTypeHandler * roadTypeHandler;
|
||||
RiverTypeHandler * riverTypeHandler;
|
||||
CIdentifierStorage * identifiersHandler;
|
||||
|
||||
CTerrainViewPatternConfig * terviewh;
|
||||
CRmgTemplateStorage * tplh;
|
||||
BattleFieldHandler * battlefieldsHandler;
|
||||
ObstacleHandler * obstacleHandler;
|
||||
GameSettings * settingsHandler;
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::ScriptHandler * scriptHandler;
|
||||
std::shared_ptr<scripting::ScriptHandler> scriptHandler;
|
||||
#endif
|
||||
|
||||
LibClasses(); //c-tor, loads .lods and NULLs handlers
|
||||
~LibClasses();
|
||||
void init(bool onlyEssential); //uses standard config file
|
||||
void clear(); //deletes all handlers and its data
|
||||
|
||||
// basic initialization. should be called before init(). Can also extract original H3 archives
|
||||
void loadFilesystem(bool extractArchives);
|
||||
|
@ -240,7 +240,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
|
||||
{
|
||||
try
|
||||
{
|
||||
RangeGenerator obidgen(0, VLC->obstacleHandler->objects.size() - 1, ourRand);
|
||||
RangeGenerator obidgen(0, VLC->obstacleHandler->size() - 1, ourRand);
|
||||
auto obstPtr = std::make_shared<CObstacleInstance>();
|
||||
obstPtr->obstacleType = CObstacleInstance::ABSOLUTE_OBSTACLE;
|
||||
obstPtr->ID = obidgen.getSuchNumber(appropriateAbsoluteObstacle);
|
||||
@ -262,7 +262,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
|
||||
{
|
||||
while(tilesToBlock > 0)
|
||||
{
|
||||
RangeGenerator obidgen(0, VLC->obstacleHandler->objects.size() - 1, ourRand);
|
||||
RangeGenerator obidgen(0, VLC->obstacleHandler->size() - 1, ourRand);
|
||||
auto tileAccessibility = curB->getAccesibility();
|
||||
const int obid = obidgen.getSuchNumber(appropriateUsualObstacle);
|
||||
const ObstacleInfo &obi = *Obstacle(obid).getInfo();
|
||||
@ -1009,7 +1009,7 @@ scripting::Pool * BattleInfo::getContextPool() const
|
||||
{
|
||||
//this is real battle, use global scripting context pool
|
||||
//TODO: make this line not ugly
|
||||
return IObjectInterface::cb->getGlobalContextPool();
|
||||
return battleGetFightingHero(0)->cb->getGlobalContextPool();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -401,10 +401,9 @@ PlayerColor CBattleInfoEssentials::battleGetOwner(const battle::Unit * unit) con
|
||||
|
||||
PlayerColor initialOwner = getBattle()->getSidePlayer(unit->unitSide());
|
||||
|
||||
static CSelector selector = Selector::type()(BonusType::HYPNOTIZED);
|
||||
static std::string cachingString = "type_103s-1";
|
||||
static const CSelector selector = Selector::type()(BonusType::HYPNOTIZED);
|
||||
|
||||
if(unit->hasBonus(selector, cachingString))
|
||||
if(unit->hasBonus(selector))
|
||||
return otherPlayer(initialOwner);
|
||||
else
|
||||
return initialOwner;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "Bonus.h"
|
||||
#include "CBonusSystemNode.h"
|
||||
#include "Limiters.h"
|
||||
#include "Updaters.h"
|
||||
#include "Propagators.h"
|
||||
|
@ -15,39 +15,39 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
DLL_LINKAGE CSelectFieldEqual<BonusType> & type()
|
||||
DLL_LINKAGE const CSelectFieldEqual<BonusType> & type()
|
||||
{
|
||||
static CSelectFieldEqual<BonusType> stype(&Bonus::type);
|
||||
static const CSelectFieldEqual<BonusType> stype(&Bonus::type);
|
||||
return stype;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CSelectFieldEqual<BonusSubtypeID> & subtype()
|
||||
DLL_LINKAGE const CSelectFieldEqual<BonusSubtypeID> & subtype()
|
||||
{
|
||||
static CSelectFieldEqual<BonusSubtypeID> ssubtype(&Bonus::subtype);
|
||||
static const CSelectFieldEqual<BonusSubtypeID> ssubtype(&Bonus::subtype);
|
||||
return ssubtype;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CSelectFieldEqual<CAddInfo> & info()
|
||||
DLL_LINKAGE const CSelectFieldEqual<CAddInfo> & info()
|
||||
{
|
||||
static CSelectFieldEqual<CAddInfo> sinfo(&Bonus::additionalInfo);
|
||||
static const CSelectFieldEqual<CAddInfo> sinfo(&Bonus::additionalInfo);
|
||||
return sinfo;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CSelectFieldEqual<BonusSource> & sourceType()
|
||||
DLL_LINKAGE const CSelectFieldEqual<BonusSource> & sourceType()
|
||||
{
|
||||
static CSelectFieldEqual<BonusSource> ssourceType(&Bonus::source);
|
||||
static const CSelectFieldEqual<BonusSource> ssourceType(&Bonus::source);
|
||||
return ssourceType;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CSelectFieldEqual<BonusSource> & targetSourceType()
|
||||
DLL_LINKAGE const CSelectFieldEqual<BonusSource> & targetSourceType()
|
||||
{
|
||||
static CSelectFieldEqual<BonusSource> ssourceType(&Bonus::targetSourceType);
|
||||
static const CSelectFieldEqual<BonusSource> ssourceType(&Bonus::targetSourceType);
|
||||
return ssourceType;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CSelectFieldEqual<BonusLimitEffect> & effectRange()
|
||||
DLL_LINKAGE const CSelectFieldEqual<BonusLimitEffect> & effectRange()
|
||||
{
|
||||
static CSelectFieldEqual<BonusLimitEffect> seffectRange(&Bonus::effectRange);
|
||||
static const CSelectFieldEqual<BonusLimitEffect> seffectRange(&Bonus::effectRange);
|
||||
return seffectRange;
|
||||
}
|
||||
|
||||
|
@ -125,12 +125,12 @@ public:
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
extern DLL_LINKAGE CSelectFieldEqual<BonusType> & type();
|
||||
extern DLL_LINKAGE CSelectFieldEqual<BonusSubtypeID> & subtype();
|
||||
extern DLL_LINKAGE CSelectFieldEqual<CAddInfo> & info();
|
||||
extern DLL_LINKAGE CSelectFieldEqual<BonusSource> & sourceType();
|
||||
extern DLL_LINKAGE CSelectFieldEqual<BonusSource> & targetSourceType();
|
||||
extern DLL_LINKAGE CSelectFieldEqual<BonusLimitEffect> & effectRange();
|
||||
extern DLL_LINKAGE const CSelectFieldEqual<BonusType> & type();
|
||||
extern DLL_LINKAGE const CSelectFieldEqual<BonusSubtypeID> & subtype();
|
||||
extern DLL_LINKAGE const CSelectFieldEqual<CAddInfo> & info();
|
||||
extern DLL_LINKAGE const CSelectFieldEqual<BonusSource> & sourceType();
|
||||
extern DLL_LINKAGE const CSelectFieldEqual<BonusSource> & targetSourceType();
|
||||
extern DLL_LINKAGE const CSelectFieldEqual<BonusLimitEffect> & effectRange();
|
||||
extern DLL_LINKAGE CWillLastTurns turns;
|
||||
extern DLL_LINKAGE CWillLastDays days;
|
||||
|
||||
|
@ -20,18 +20,25 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
std::atomic<int64_t> CBonusSystemNode::treeChanged(1);
|
||||
constexpr bool CBonusSystemNode::cachingEnabled = true;
|
||||
|
||||
#define FOREACH_PARENT(pname) TNodes lparents; getParents(lparents); for(CBonusSystemNode *pname : lparents)
|
||||
#define FOREACH_RED_CHILD(pname) TNodes lchildren; getRedChildren(lchildren); for(CBonusSystemNode *pname : lchildren)
|
||||
std::shared_ptr<Bonus> CBonusSystemNode::getLocalBonus(const CSelector & selector)
|
||||
{
|
||||
auto ret = bonuses.getFirst(selector);
|
||||
if(ret)
|
||||
return ret;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & selector)
|
||||
std::shared_ptr<const Bonus> CBonusSystemNode::getFirstBonus(const CSelector & selector) const
|
||||
{
|
||||
auto ret = bonuses.getFirst(selector);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
FOREACH_PARENT(pname)
|
||||
TCNodes lparents;
|
||||
getParents(lparents);
|
||||
for(const CBonusSystemNode *pname : lparents)
|
||||
{
|
||||
ret = pname->getBonusLocalFirst(selector);
|
||||
ret = pname->getFirstBonus(selector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -39,28 +46,15 @@ std::shared_ptr<Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & se
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<const Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & selector) const
|
||||
{
|
||||
return (const_cast<CBonusSystemNode*>(this))->getBonusLocalFirst(selector);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getParents(TCNodes & out) const /*retrieves list of parent nodes (nodes to inherit bonuses from) */
|
||||
{
|
||||
for(const auto * elem : parents)
|
||||
for(const auto * elem : parentsToInherit)
|
||||
out.insert(elem);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getParents(TNodes &out)
|
||||
{
|
||||
for (auto * elem : parents)
|
||||
{
|
||||
out.insert(elem);
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getAllParents(TCNodes & out) const //retrieves list of parent nodes (nodes to inherit bonuses from)
|
||||
{
|
||||
for(auto * parent : parents)
|
||||
for(auto * parent : parentsToInherit)
|
||||
{
|
||||
out.insert(parent);
|
||||
parent->getAllParents(out);
|
||||
@ -227,39 +221,6 @@ CBonusSystemNode::CBonusSystemNode(ENodeTypes NodeType):
|
||||
{
|
||||
}
|
||||
|
||||
CBonusSystemNode::CBonusSystemNode(CBonusSystemNode && other) noexcept:
|
||||
bonuses(std::move(other.bonuses)),
|
||||
exportedBonuses(std::move(other.exportedBonuses)),
|
||||
nodeType(other.nodeType),
|
||||
cachedLast(0),
|
||||
isHypotheticNode(other.isHypotheticNode)
|
||||
{
|
||||
std::swap(parents, other.parents);
|
||||
std::swap(children, other.children);
|
||||
|
||||
//fixing bonus tree without recalculation
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
for(CBonusSystemNode * n : parents)
|
||||
{
|
||||
n->children -= &other;
|
||||
n->children.push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
for(CBonusSystemNode * n : children)
|
||||
{
|
||||
n->parents -= &other;
|
||||
n->parents.push_back(this);
|
||||
}
|
||||
|
||||
//cache ignored
|
||||
|
||||
//cachedBonuses
|
||||
//cachedRequests
|
||||
}
|
||||
|
||||
CBonusSystemNode::~CBonusSystemNode()
|
||||
{
|
||||
detachFromAll();
|
||||
@ -273,14 +234,14 @@ CBonusSystemNode::~CBonusSystemNode()
|
||||
|
||||
void CBonusSystemNode::attachTo(CBonusSystemNode & parent)
|
||||
{
|
||||
assert(!vstd::contains(parents, &parent));
|
||||
parents.push_back(&parent);
|
||||
assert(!vstd::contains(parentsToPropagate, &parent));
|
||||
parentsToPropagate.push_back(&parent);
|
||||
|
||||
attachToSource(parent);
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(parent.actsAsBonusSourceOnly())
|
||||
parent.newRedDescendant(*this);
|
||||
else
|
||||
if(!parent.actsAsBonusSourceOnly())
|
||||
newRedDescendant(parent);
|
||||
|
||||
parent.newChildAttached(*this);
|
||||
@ -289,21 +250,35 @@ void CBonusSystemNode::attachTo(CBonusSystemNode & parent)
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
void CBonusSystemNode::detachFrom(CBonusSystemNode & parent)
|
||||
void CBonusSystemNode::attachToSource(const CBonusSystemNode & parent)
|
||||
{
|
||||
assert(vstd::contains(parents, &parent));
|
||||
assert(!vstd::contains(parentsToInherit, &parent));
|
||||
parentsToInherit.push_back(&parent);
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(parent.actsAsBonusSourceOnly())
|
||||
parent.removedRedDescendant(*this);
|
||||
else
|
||||
parent.newRedDescendant(*this);
|
||||
}
|
||||
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
void CBonusSystemNode::detachFrom(CBonusSystemNode & parent)
|
||||
{
|
||||
assert(vstd::contains(parentsToPropagate, &parent));
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(!parent.actsAsBonusSourceOnly())
|
||||
removedRedDescendant(parent);
|
||||
}
|
||||
|
||||
if (vstd::contains(parents, &parent))
|
||||
detachFromSource(parent);
|
||||
|
||||
if (vstd::contains(parentsToPropagate, &parent))
|
||||
{
|
||||
parents -= &parent;
|
||||
parentsToPropagate -= &parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -318,6 +293,30 @@ void CBonusSystemNode::detachFrom(CBonusSystemNode & parent)
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
|
||||
void CBonusSystemNode::detachFromSource(const CBonusSystemNode & parent)
|
||||
{
|
||||
assert(vstd::contains(parentsToInherit, &parent));
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(parent.actsAsBonusSourceOnly())
|
||||
parent.removedRedDescendant(*this);
|
||||
}
|
||||
|
||||
if (vstd::contains(parentsToInherit, &parent))
|
||||
{
|
||||
parentsToInherit -= &parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
logBonus->error("Error on Detach. Node %s (nodeType=%d) has not parent %s (nodeType=%d)"
|
||||
, nodeShortInfo(), nodeType, parent.nodeShortInfo(), parent.nodeType);
|
||||
}
|
||||
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removeBonusesRecursive(const CSelector & s)
|
||||
{
|
||||
removeBonuses(s);
|
||||
@ -405,8 +404,10 @@ void CBonusSystemNode::propagateBonus(const std::shared_ptr<Bonus> & b, const CB
|
||||
logBonus->trace("#$# %s #propagated to# %s", propagated->Description(), nodeName());
|
||||
}
|
||||
|
||||
FOREACH_RED_CHILD(child)
|
||||
child->propagateBonus(b, source);
|
||||
TNodes lchildren;
|
||||
getRedChildren(lchildren);
|
||||
for(CBonusSystemNode *pname : lchildren)
|
||||
pname->propagateBonus(b, source);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::unpropagateBonus(const std::shared_ptr<Bonus> & b)
|
||||
@ -417,8 +418,10 @@ void CBonusSystemNode::unpropagateBonus(const std::shared_ptr<Bonus> & b)
|
||||
logBonus->trace("#$# %s #is no longer propagated to# %s", b->Description(), nodeName());
|
||||
}
|
||||
|
||||
FOREACH_RED_CHILD(child)
|
||||
child->unpropagateBonus(b);
|
||||
TNodes lchildren;
|
||||
getRedChildren(lchildren);
|
||||
for(CBonusSystemNode *pname : lchildren)
|
||||
pname->unpropagateBonus(b);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::newChildAttached(CBonusSystemNode & child)
|
||||
@ -440,13 +443,16 @@ void CBonusSystemNode::childDetached(CBonusSystemNode & child)
|
||||
|
||||
void CBonusSystemNode::detachFromAll()
|
||||
{
|
||||
while(!parents.empty())
|
||||
detachFrom(*parents.front());
|
||||
while(!parentsToPropagate.empty())
|
||||
detachFrom(*parentsToPropagate.front());
|
||||
|
||||
while(!parentsToInherit.empty())
|
||||
detachFromSource(*parentsToInherit.front());
|
||||
}
|
||||
|
||||
bool CBonusSystemNode::isIndependentNode() const
|
||||
{
|
||||
return parents.empty() && children.empty();
|
||||
return parentsToInherit.empty() && parentsToPropagate.empty() && children.empty();
|
||||
}
|
||||
|
||||
std::string CBonusSystemNode::nodeName() const
|
||||
@ -464,12 +470,13 @@ std::string CBonusSystemNode::nodeShortInfo() const
|
||||
void CBonusSystemNode::deserializationFix()
|
||||
{
|
||||
exportBonuses();
|
||||
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getRedParents(TNodes & out)
|
||||
void CBonusSystemNode::getRedParents(TCNodes & out) const
|
||||
{
|
||||
FOREACH_PARENT(pname)
|
||||
TCNodes lparents;
|
||||
getParents(lparents);
|
||||
for(const CBonusSystemNode *pname : lparents)
|
||||
{
|
||||
if(pname->actsAsBonusSourceOnly())
|
||||
{
|
||||
@ -479,7 +486,7 @@ void CBonusSystemNode::getRedParents(TNodes & out)
|
||||
|
||||
if(!actsAsBonusSourceOnly())
|
||||
{
|
||||
for(CBonusSystemNode *child : children)
|
||||
for(const CBonusSystemNode *child : children)
|
||||
{
|
||||
out.insert(child);
|
||||
}
|
||||
@ -488,7 +495,7 @@ void CBonusSystemNode::getRedParents(TNodes & out)
|
||||
|
||||
void CBonusSystemNode::getRedChildren(TNodes &out)
|
||||
{
|
||||
FOREACH_PARENT(pname)
|
||||
for(CBonusSystemNode *pname : parentsToPropagate)
|
||||
{
|
||||
if(!pname->actsAsBonusSourceOnly())
|
||||
{
|
||||
@ -505,17 +512,17 @@ void CBonusSystemNode::getRedChildren(TNodes &out)
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant)
|
||||
void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant) const
|
||||
{
|
||||
for(const auto & b : exportedBonuses)
|
||||
{
|
||||
if(b->propagator)
|
||||
descendant.propagateBonus(b, *this);
|
||||
}
|
||||
TNodes redParents;
|
||||
TCNodes redParents;
|
||||
getRedAncestors(redParents); //get all red parents recursively
|
||||
|
||||
for(auto * parent : redParents)
|
||||
for(const auto * parent : redParents)
|
||||
{
|
||||
for(const auto & b : parent->exportedBonuses)
|
||||
{
|
||||
@ -525,13 +532,13 @@ void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant)
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removedRedDescendant(CBonusSystemNode & descendant)
|
||||
void CBonusSystemNode::removedRedDescendant(CBonusSystemNode & descendant) const
|
||||
{
|
||||
for(const auto & b : exportedBonuses)
|
||||
if(b->propagator)
|
||||
descendant.unpropagateBonus(b);
|
||||
|
||||
TNodes redParents;
|
||||
TCNodes redParents;
|
||||
getRedAncestors(redParents); //get all red parents recursively
|
||||
|
||||
for(auto * parent : redParents)
|
||||
@ -542,14 +549,14 @@ void CBonusSystemNode::removedRedDescendant(CBonusSystemNode & descendant)
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getRedAncestors(TNodes &out)
|
||||
void CBonusSystemNode::getRedAncestors(TCNodes &out) const
|
||||
{
|
||||
getRedParents(out);
|
||||
|
||||
TNodes redParents;
|
||||
TCNodes redParents;
|
||||
getRedParents(redParents);
|
||||
|
||||
for(CBonusSystemNode * parent : redParents)
|
||||
for(const CBonusSystemNode * parent : redParents)
|
||||
parent->getRedAncestors(out);
|
||||
}
|
||||
|
||||
@ -574,9 +581,9 @@ CBonusSystemNode::ENodeTypes CBonusSystemNode::getNodeType() const
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
const TNodesVector& CBonusSystemNode::getParentNodes() const
|
||||
const TCNodesVector& CBonusSystemNode::getParentNodes() const
|
||||
{
|
||||
return parents;
|
||||
return parentsToInherit;
|
||||
}
|
||||
|
||||
void CBonusSystemNode::setNodeType(CBonusSystemNode::ENodeTypes type)
|
||||
@ -646,4 +653,4 @@ int64_t CBonusSystemNode::getTreeVersion() const
|
||||
return treeChanged;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -19,6 +19,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
using TNodes = std::set<CBonusSystemNode *>;
|
||||
using TCNodes = std::set<const CBonusSystemNode *>;
|
||||
using TNodesVector = std::vector<CBonusSystemNode *>;
|
||||
using TCNodesVector = std::vector<const CBonusSystemNode *>;
|
||||
|
||||
class DLL_LINKAGE CBonusSystemNode : public virtual IBonusBearer, public boost::noncopyable
|
||||
{
|
||||
@ -33,7 +34,8 @@ private:
|
||||
BonusList bonuses; //wielded bonuses (local or up-propagated here)
|
||||
BonusList exportedBonuses; //bonuses coming from this node (wielded or propagated away)
|
||||
|
||||
TNodesVector parents; //parents -> we inherit bonuses from them, we may attach our bonuses to them
|
||||
TCNodesVector parentsToInherit; // we inherit bonuses from them
|
||||
TNodesVector parentsToPropagate; // we may attach our bonuses to them
|
||||
TNodesVector children;
|
||||
|
||||
ENodeTypes nodeType;
|
||||
@ -54,8 +56,8 @@ private:
|
||||
TConstBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const;
|
||||
std::shared_ptr<Bonus> getUpdatedBonus(const std::shared_ptr<Bonus> & b, const TUpdaterPtr & updater) const;
|
||||
|
||||
void getRedParents(TNodes &out); //retrieves list of red parent nodes (nodes bonuses propagate from)
|
||||
void getRedAncestors(TNodes &out);
|
||||
void getRedParents(TCNodes &out) const; //retrieves list of red parent nodes (nodes bonuses propagate from)
|
||||
void getRedAncestors(TCNodes &out) const;
|
||||
void getRedChildren(TNodes &out);
|
||||
|
||||
void getAllParents(TCNodes & out) const;
|
||||
@ -66,8 +68,8 @@ private:
|
||||
void unpropagateBonus(const std::shared_ptr<Bonus> & b);
|
||||
bool actsAsBonusSourceOnly() const;
|
||||
|
||||
void newRedDescendant(CBonusSystemNode & descendant); //propagation needed
|
||||
void removedRedDescendant(CBonusSystemNode & descendant); //de-propagation needed
|
||||
void newRedDescendant(CBonusSystemNode & descendant) const; //propagation needed
|
||||
void removedRedDescendant(CBonusSystemNode & descendant) const; //de-propagation needed
|
||||
|
||||
std::string nodeShortInfo() const;
|
||||
|
||||
@ -80,21 +82,23 @@ protected:
|
||||
public:
|
||||
explicit CBonusSystemNode(bool isHypotetic = false);
|
||||
explicit CBonusSystemNode(ENodeTypes NodeType);
|
||||
CBonusSystemNode(CBonusSystemNode && other) noexcept;
|
||||
virtual ~CBonusSystemNode();
|
||||
|
||||
void limitBonuses(const BonusList &allBonuses, BonusList &out) const; //out will bo populed with bonuses that are not limited here
|
||||
TBonusListPtr limitBonuses(const BonusList &allBonuses) const; //same as above, returns out by val for convienence
|
||||
TConstBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const override;
|
||||
void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from),
|
||||
std::shared_ptr<const Bonus> getBonusLocalFirst(const CSelector & selector) const;
|
||||
|
||||
//non-const interface
|
||||
void getParents(TNodes &out); //retrieves list of parent nodes (nodes to inherit bonuses from)
|
||||
std::shared_ptr<Bonus> getBonusLocalFirst(const CSelector & selector);
|
||||
/// Returns first bonus matching selector
|
||||
std::shared_ptr<const Bonus> getFirstBonus(const CSelector & selector) const;
|
||||
|
||||
/// Provides write access to first bonus from this node that matches selector
|
||||
std::shared_ptr<Bonus> getLocalBonus(const CSelector & selector);
|
||||
|
||||
void attachTo(CBonusSystemNode & parent);
|
||||
void attachToSource(const CBonusSystemNode & parent);
|
||||
void detachFrom(CBonusSystemNode & parent);
|
||||
void detachFromSource(const CBonusSystemNode & parent);
|
||||
void detachFromAll();
|
||||
virtual void addNewBonus(const std::shared_ptr<Bonus>& b);
|
||||
void accumulateBonus(const std::shared_ptr<Bonus>& b); //add value of bonus with same type/subtype or create new
|
||||
@ -115,7 +119,7 @@ public:
|
||||
const BonusList & getExportedBonusList() const;
|
||||
CBonusSystemNode::ENodeTypes getNodeType() const;
|
||||
void setNodeType(CBonusSystemNode::ENodeTypes type);
|
||||
const TNodesVector & getParentNodes() const;
|
||||
const TCNodesVector & getParentNodes() const;
|
||||
|
||||
static void treeHasChanged();
|
||||
|
||||
@ -128,14 +132,12 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
// h & bonuses;
|
||||
h & nodeType;
|
||||
h & exportedBonuses;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
//h & parents & children;
|
||||
}
|
||||
|
||||
friend class CBonusProxy;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "CBonusSystemNode.h"
|
||||
#include "IBonusBearer.h"
|
||||
#include "BonusList.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "CampaignState.h"
|
||||
|
||||
#include "../JsonNode.h"
|
||||
#include "../Point.h"
|
||||
#include "../filesystem/ResourcePath.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CGeneralTextHandler.h"
|
||||
@ -224,7 +225,7 @@ std::set<HeroTypeID> CampaignState::getReservedHeroes() const
|
||||
|
||||
const CGHeroInstance * CampaignState::strongestHero(CampaignScenarioID scenarioId, const PlayerColor & owner) const
|
||||
{
|
||||
std::function<bool(const JsonNode & node)> isOwned = [owner](const JsonNode & node)
|
||||
std::function<bool(const JsonNode & node)> isOwned = [&](const JsonNode & node)
|
||||
{
|
||||
auto * h = CampaignState::crossoverDeserialize(node, nullptr);
|
||||
bool result = h->tempOwner == owner;
|
||||
@ -316,7 +317,7 @@ std::optional<ui8> CampaignState::getBonusID(CampaignScenarioID which) const
|
||||
return chosenCampaignBonuses.at(which);
|
||||
}
|
||||
|
||||
std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId) const
|
||||
std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId, IGameCallback * cb) const
|
||||
{
|
||||
// FIXME: there is certainly better way to handle maps inside campaigns
|
||||
if(scenarioId == CampaignScenarioID::NONE)
|
||||
@ -327,7 +328,7 @@ std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId) const
|
||||
boost::to_lower(scenarioName);
|
||||
scenarioName += ':' + std::to_string(scenarioId.getNum());
|
||||
const auto & mapContent = mapPieces.find(scenarioId)->second;
|
||||
return mapService.loadMap(mapContent.data(), mapContent.size(), scenarioName, getModName(), getEncoding());
|
||||
return mapService.loadMap(mapContent.data(), mapContent.size(), scenarioName, getModName(), getEncoding(), cb);
|
||||
}
|
||||
|
||||
std::unique_ptr<CMapHeader> CampaignState::getMapHeader(CampaignScenarioID scenarioId) const
|
||||
@ -355,7 +356,7 @@ std::shared_ptr<CMapInfo> CampaignState::getMapInfo(CampaignScenarioID scenarioI
|
||||
return mapInfo;
|
||||
}
|
||||
|
||||
JsonNode CampaignState::crossoverSerialize(CGHeroInstance * hero)
|
||||
JsonNode CampaignState::crossoverSerialize(CGHeroInstance * hero) const
|
||||
{
|
||||
JsonNode node;
|
||||
JsonSerializer handler(nullptr, node);
|
||||
@ -363,10 +364,10 @@ JsonNode CampaignState::crossoverSerialize(CGHeroInstance * hero)
|
||||
return node;
|
||||
}
|
||||
|
||||
CGHeroInstance * CampaignState::crossoverDeserialize(const JsonNode & node, CMap * map)
|
||||
CGHeroInstance * CampaignState::crossoverDeserialize(const JsonNode & node, CMap * map) const
|
||||
{
|
||||
JsonDeserializer handler(nullptr, const_cast<JsonNode&>(node));
|
||||
auto * hero = new CGHeroInstance();
|
||||
auto * hero = new CGHeroInstance(map->cb);
|
||||
hero->ID = Obj::HERO;
|
||||
hero->serializeJsonOptions(handler);
|
||||
if (map)
|
||||
|
@ -27,6 +27,7 @@ class CMapHeader;
|
||||
class CMapInfo;
|
||||
class JsonNode;
|
||||
class Point;
|
||||
class IGameCallback;
|
||||
|
||||
class DLL_LINKAGE CampaignRegions
|
||||
{
|
||||
@ -277,7 +278,7 @@ public:
|
||||
/// Returns true if all available scenarios have been completed and campaign is finished
|
||||
bool isCampaignFinished() const;
|
||||
|
||||
std::unique_ptr<CMap> getMap(CampaignScenarioID scenarioId) const;
|
||||
std::unique_ptr<CMap> getMap(CampaignScenarioID scenarioId, IGameCallback * cb) const;
|
||||
std::unique_ptr<CMapHeader> getMapHeader(CampaignScenarioID scenarioId) const;
|
||||
std::shared_ptr<CMapInfo> getMapInfo(CampaignScenarioID scenarioId) const;
|
||||
|
||||
@ -298,8 +299,8 @@ public:
|
||||
/// May return empty JsonNode if such hero was not found
|
||||
const JsonNode & getHeroByType(HeroTypeID heroID) const;
|
||||
|
||||
static JsonNode crossoverSerialize(CGHeroInstance * hero);
|
||||
static CGHeroInstance * crossoverDeserialize(const JsonNode & node, CMap * map);
|
||||
JsonNode crossoverSerialize(CGHeroInstance * hero) const;
|
||||
CGHeroInstance * crossoverDeserialize(const JsonNode & node, CMap * map) const;
|
||||
|
||||
std::string campaignSet;
|
||||
|
||||
|
@ -151,6 +151,16 @@ std::string HeroClassID::entityType()
|
||||
return "heroClass";
|
||||
}
|
||||
|
||||
const CHeroClass * HeroClassID::toHeroClass() const
|
||||
{
|
||||
return dynamic_cast<const CHeroClass*>(toEntity(VLC));
|
||||
}
|
||||
|
||||
const HeroClass * HeroClassID::toEntity(const Services * services) const
|
||||
{
|
||||
return services->heroClasses()->getByIndex(num);
|
||||
}
|
||||
|
||||
si32 ObjectInstanceID::decode(const std::string & identifier)
|
||||
{
|
||||
return std::stoi(identifier);
|
||||
|
@ -21,6 +21,8 @@ class Creature;
|
||||
class CreatureService;
|
||||
class HeroType;
|
||||
class CHero;
|
||||
class CHeroClass;
|
||||
class HeroClass;
|
||||
class HeroTypeService;
|
||||
class Faction;
|
||||
class Skill;
|
||||
@ -81,6 +83,9 @@ public:
|
||||
DLL_LINKAGE static si32 decode(const std::string & identifier);
|
||||
DLL_LINKAGE static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
|
||||
const CHeroClass * toHeroClass() const;
|
||||
const HeroClass * toEntity(const Services * services) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE HeroTypeID : public EntityIdentifier<HeroTypeID>
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include "../mapObjectConstructors/DwellingInstanceConstructor.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../mapObjects/CQuest.h"
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
#include "../mapping/CMap.h"
|
||||
#include "../mapping/CMapEditManager.h"
|
||||
#include "../mapping/CMapService.h"
|
||||
@ -97,7 +99,7 @@ HeroTypeID CGameState::pickUnusedHeroTypeRandomly(const PlayerColor & owner)
|
||||
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
||||
for(const HeroTypeID & hid : getUnusedAllowedHeroes())
|
||||
{
|
||||
if(VLC->heroh->objects[hid.getNum()]->heroClass->faction == ps.castle)
|
||||
if(hid.toHeroType()->heroClass->faction == ps.castle)
|
||||
factionHeroes.push_back(hid);
|
||||
else
|
||||
otherHeroes.push_back(hid);
|
||||
@ -169,14 +171,16 @@ CGameState::~CGameState()
|
||||
initialOpts.dellNull();
|
||||
}
|
||||
|
||||
void CGameState::preInit(Services * services)
|
||||
void CGameState::preInit(Services * newServices, IGameCallback * newCallback)
|
||||
{
|
||||
this->services = services;
|
||||
services = newServices;
|
||||
callback = newCallback;
|
||||
}
|
||||
|
||||
void CGameState::init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator & progressTracking, bool allowSavingRandomMap)
|
||||
{
|
||||
preInitAuto();
|
||||
assert(services);
|
||||
assert(callback);
|
||||
logGlobal->info("\tUsing random seed: %d", si->seedToBeUsed);
|
||||
getRandomGenerator().setSeed(si->seedToBeUsed);
|
||||
scenarioOps = CMemorySerializer::deepCopy(*si).release();
|
||||
@ -224,7 +228,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
|
||||
|
||||
for(auto & elem : teams)
|
||||
{
|
||||
CGObelisk::visited[elem.first] = 0;
|
||||
map->obelisksVisited[elem.first] = 0;
|
||||
}
|
||||
|
||||
logGlobal->debug("\tChecking objectives");
|
||||
@ -284,21 +288,13 @@ void CGameState::updateEntity(Metatype metatype, int32_t index, const JsonNode &
|
||||
|
||||
void CGameState::updateOnLoad(StartInfo * si)
|
||||
{
|
||||
preInitAuto();
|
||||
assert(services);
|
||||
assert(callback);
|
||||
scenarioOps->playerInfos = si->playerInfos;
|
||||
for(auto & i : si->playerInfos)
|
||||
gs->players[i.first].human = i.second.isControlledByHuman();
|
||||
}
|
||||
|
||||
void CGameState::preInitAuto()
|
||||
{
|
||||
if(services == nullptr)
|
||||
{
|
||||
logGlobal->error("Game state preinit missing");
|
||||
preInit(VLC);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking)
|
||||
{
|
||||
if(scenarioOps->createRandomMap())
|
||||
@ -307,7 +303,7 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
|
||||
CStopWatch sw;
|
||||
|
||||
// Gen map
|
||||
CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, scenarioOps->seedToBeUsed);
|
||||
CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, callback, scenarioOps->seedToBeUsed);
|
||||
progressTracking.include(mapGenerator);
|
||||
|
||||
std::unique_ptr<CMap> randomMap = mapGenerator.generate();
|
||||
@ -370,7 +366,7 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
|
||||
{
|
||||
logGlobal->info("Open map file: %s", scenarioOps->mapname);
|
||||
const ResourcePath mapURI(scenarioOps->mapname, EResType::MAP);
|
||||
map = mapService->loadMap(mapURI).release();
|
||||
map = mapService->loadMap(mapURI, callback).release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,7 +557,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
|
||||
}
|
||||
|
||||
auto handler = VLC->objtypeh->getHandlerFor(Obj::HERO, heroTypeId.toHeroType()->heroClass->getIndex());
|
||||
CGObjectInstance * obj = handler->create(handler->getTemplates().front());
|
||||
CGObjectInstance * obj = handler->create(callback, handler->getTemplates().front());
|
||||
CGHeroInstance * hero = dynamic_cast<CGHeroInstance *>(obj);
|
||||
|
||||
hero->ID = Obj::HERO;
|
||||
@ -635,7 +631,7 @@ void CGameState::initHeroes()
|
||||
if (tile.terType->isWater())
|
||||
{
|
||||
auto handler = VLC->objtypeh->getHandlerFor(Obj::BOAT, hero->getBoatType().getNum());
|
||||
CGBoat * boat = dynamic_cast<CGBoat*>(handler->create());
|
||||
auto boat = dynamic_cast<CGBoat*>(handler->create(callback, nullptr));
|
||||
handler->configureObject(boat, gs->getRandomGenerator());
|
||||
|
||||
boat->pos = hero->pos;
|
||||
@ -673,7 +669,7 @@ void CGameState::initHeroes()
|
||||
|
||||
for(const HeroTypeID & htype : heroesToCreate) //all not used allowed heroes go with default state into the pool
|
||||
{
|
||||
auto * vhi = new CGHeroInstance();
|
||||
auto * vhi = new CGHeroInstance(callback);
|
||||
vhi->initHero(getRandomGenerator(), htype);
|
||||
|
||||
int typeID = htype.getNum();
|
||||
@ -772,11 +768,11 @@ void CGameState::initTowns()
|
||||
if (campaign)
|
||||
campaign->initTowns();
|
||||
|
||||
CGTownInstance::universitySkills.clear();
|
||||
CGTownInstance::universitySkills.push_back(SecondarySkill(SecondarySkill::FIRE_MAGIC));
|
||||
CGTownInstance::universitySkills.push_back(SecondarySkill(SecondarySkill::AIR_MAGIC));
|
||||
CGTownInstance::universitySkills.push_back(SecondarySkill(SecondarySkill::WATER_MAGIC));
|
||||
CGTownInstance::universitySkills.push_back(SecondarySkill(SecondarySkill::EARTH_MAGIC));
|
||||
map->townUniversitySkills.clear();
|
||||
map->townUniversitySkills.push_back(SecondarySkill(SecondarySkill::FIRE_MAGIC));
|
||||
map->townUniversitySkills.push_back(SecondarySkill(SecondarySkill::AIR_MAGIC));
|
||||
map->townUniversitySkills.push_back(SecondarySkill(SecondarySkill::WATER_MAGIC));
|
||||
map->townUniversitySkills.push_back(SecondarySkill(SecondarySkill::EARTH_MAGIC));
|
||||
|
||||
for (auto & elem : map->towns)
|
||||
{
|
||||
@ -936,7 +932,7 @@ void CGameState::initMapObjects()
|
||||
}
|
||||
}
|
||||
}
|
||||
CGSubterraneanGate::postInit(); //pairing subterranean gates
|
||||
CGSubterraneanGate::postInit(callback); //pairing subterranean gates
|
||||
|
||||
map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed and initialized
|
||||
}
|
||||
@ -1208,7 +1204,7 @@ int3 CGameState::guardingCreaturePosition (int3 pos) const
|
||||
|
||||
void CGameState::updateRumor()
|
||||
{
|
||||
static std::vector<RumorState::ERumorType> rumorTypes = {RumorState::TYPE_MAP, RumorState::TYPE_SPECIAL, RumorState::TYPE_RAND, RumorState::TYPE_RAND};
|
||||
static const std::vector<RumorState::ERumorType> rumorTypes = {RumorState::TYPE_MAP, RumorState::TYPE_SPECIAL, RumorState::TYPE_RAND, RumorState::TYPE_RAND};
|
||||
std::vector<RumorState::ERumorTypeSpecial> sRumorTypes = {
|
||||
RumorState::RUMOR_OBELISKS, RumorState::RUMOR_ARTIFACTS, RumorState::RUMOR_ARMY, RumorState::RUMOR_INCOME};
|
||||
if(map->grailPos.valid()) // Grail should always be on map, but I had related crash I didn't manage to reproduce
|
||||
@ -1722,10 +1718,10 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
|
||||
}
|
||||
if(level >= 3) //obelisks found
|
||||
{
|
||||
auto getObeliskVisited = [](const TeamID & t)
|
||||
auto getObeliskVisited = [&](const TeamID & t)
|
||||
{
|
||||
if(CGObelisk::visited.count(t))
|
||||
return CGObelisk::visited[t];
|
||||
if(map->obelisksVisited.count(t))
|
||||
return map->obelisksVisited[t];
|
||||
else
|
||||
return ui8(0);
|
||||
};
|
||||
@ -1928,14 +1924,6 @@ TeamState::TeamState()
|
||||
fogOfWarMap = std::make_unique<boost::multi_array<ui8, 3>>();
|
||||
}
|
||||
|
||||
TeamState::TeamState(TeamState && other) noexcept:
|
||||
CBonusSystemNode(std::move(other)),
|
||||
id(other.id)
|
||||
{
|
||||
std::swap(players, other.players);
|
||||
std::swap(fogOfWarMap, other.fogOfWarMap);
|
||||
}
|
||||
|
||||
CRandomGenerator & CGameState::getRandomGenerator()
|
||||
{
|
||||
return rand;
|
||||
|
@ -97,10 +97,12 @@ public:
|
||||
/// list of players currently making turn. Usually - just one, except for simturns
|
||||
std::set<PlayerColor> actingPlayers;
|
||||
|
||||
IGameCallback * callback;
|
||||
|
||||
CGameState();
|
||||
virtual ~CGameState();
|
||||
|
||||
void preInit(Services * services);
|
||||
void preInit(Services * services, IGameCallback * callback);
|
||||
|
||||
void init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator &, bool allowSavingRandomMap = true);
|
||||
void updateOnLoad(StartInfo * si);
|
||||
@ -193,7 +195,6 @@ public:
|
||||
|
||||
private:
|
||||
// ----- initialization -----
|
||||
void preInitAuto();
|
||||
void initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking);
|
||||
void checkMapChecksum();
|
||||
void initGlobalBonuses();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../campaign/CampaignState.h"
|
||||
#include "../mapping/CMapEditManager.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../networkPacks/ArtifactLocation.h"
|
||||
#include "../mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
@ -90,7 +91,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(std::vector<CampaignHeroR
|
||||
.And(Selector::subtype()(BonusSubtypeID(g)))
|
||||
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
|
||||
|
||||
cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g.getNum()];
|
||||
cgh->getLocalBonus(sel)->val = cgh->type->heroClass->primarySkillInitial[g.getNum()];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -347,7 +348,7 @@ void CGameStateCampaign::replaceHeroesPlaceholders(const std::vector<CampaignHer
|
||||
if(heroPlaceholder->tempOwner.isValidPlayer())
|
||||
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
||||
heroToPlace->pos = heroPlaceholder->pos;
|
||||
heroToPlace->type = VLC->heroh->objects[heroToPlace->getHeroType().getNum()];
|
||||
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
|
||||
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
|
||||
|
||||
gameState->map->removeBlockVisTiles(heroPlaceholder, true);
|
||||
@ -402,7 +403,7 @@ std::vector<CampaignHeroReplacement> CGameStateCampaign::generateCampaignHeroesT
|
||||
continue;
|
||||
}
|
||||
|
||||
CGHeroInstance * hero = CampaignState::crossoverDeserialize(node, gameState->map);
|
||||
CGHeroInstance * hero = campaignState->crossoverDeserialize(node, gameState->map);
|
||||
|
||||
logGlobal->info("Hero crossover: Loading placeholder for %d (%s)", hero->getHeroType(), hero->getNameTranslated());
|
||||
|
||||
@ -427,7 +428,7 @@ std::vector<CampaignHeroReplacement> CGameStateCampaign::generateCampaignHeroesT
|
||||
if (nodeListIter == nodeList.end())
|
||||
break;
|
||||
|
||||
CGHeroInstance * hero = CampaignState::crossoverDeserialize(*nodeListIter, gameState->map);
|
||||
CGHeroInstance * hero = campaignState->crossoverDeserialize(*nodeListIter, gameState->map);
|
||||
nodeListIter++;
|
||||
|
||||
logGlobal->info("Hero crossover: Loading placeholder as %d (%s)", hero->getHeroType(), hero->getNameTranslated());
|
||||
@ -599,7 +600,7 @@ bool CGameStateCampaign::playerHasStartingHero(PlayerColor playerColor) const
|
||||
|
||||
std::unique_ptr<CMap> CGameStateCampaign::getCurrentMap() const
|
||||
{
|
||||
return gameState->scenarioOps->campState->getMap(CampaignScenarioID::NONE);
|
||||
return gameState->scenarioOps->campState->getMap(CampaignScenarioID::NONE, gameState->callback);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -19,6 +19,7 @@ class ObjectTemplate;
|
||||
class CGObjectInstance;
|
||||
class CRandomGenerator;
|
||||
class IObjectInfo;
|
||||
class IGameCallback;
|
||||
|
||||
/// Class responsible for creation of objects of specific type & subtype
|
||||
class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
|
||||
@ -109,7 +110,7 @@ public:
|
||||
|
||||
/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
|
||||
/// to allow creating objects before game start (e.g. map loading)
|
||||
virtual CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const = 0;
|
||||
virtual CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
|
||||
|
||||
/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
|
||||
/// This should set remaining properties, including randomized or depending on map
|
||||
|
@ -34,18 +34,19 @@ void CBankInstanceConstructor::initTypeData(const JsonNode & input)
|
||||
coastVisitable = input["coastVisitable"].Bool();
|
||||
}
|
||||
|
||||
BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRandomGenerator & rng) const
|
||||
BankConfig CBankInstanceConstructor::generateConfig(IGameCallback * cb, const JsonNode & level, CRandomGenerator & rng) const
|
||||
{
|
||||
BankConfig bc;
|
||||
JsonRandom randomizer(cb);
|
||||
JsonRandom::Variables emptyVariables;
|
||||
|
||||
bc.chance = static_cast<ui32>(level["chance"].Float());
|
||||
bc.guards = JsonRandom::loadCreatures(level["guards"], rng, emptyVariables);
|
||||
bc.guards = randomizer.loadCreatures(level["guards"], rng, emptyVariables);
|
||||
|
||||
bc.resources = ResourceSet(level["reward"]["resources"]);
|
||||
bc.creatures = JsonRandom::loadCreatures(level["reward"]["creatures"], rng, emptyVariables);
|
||||
bc.artifacts = JsonRandom::loadArtifacts(level["reward"]["artifacts"], rng, emptyVariables);
|
||||
bc.spells = JsonRandom::loadSpells(level["reward"]["spells"], rng, emptyVariables);
|
||||
bc.creatures = randomizer.loadCreatures(level["reward"]["creatures"], rng, emptyVariables);
|
||||
bc.artifacts = randomizer.loadArtifacts(level["reward"]["artifacts"], rng, emptyVariables);
|
||||
bc.spells = randomizer.loadSpells(level["reward"]["spells"], rng, emptyVariables);
|
||||
|
||||
return bc;
|
||||
}
|
||||
@ -70,7 +71,7 @@ void CBankInstanceConstructor::randomizeObject(CBank * bank, CRandomGenerator &
|
||||
cumulativeChance += static_cast<int>(node["chance"].Float());
|
||||
if(selectedChance < cumulativeChance)
|
||||
{
|
||||
bank->setConfig(generateConfig(node, rng));
|
||||
bank->setConfig(generateConfig(bank->cb, node, rng));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -82,80 +83,16 @@ CBankInfo::CBankInfo(const JsonVector & Config) :
|
||||
assert(!Config.empty());
|
||||
}
|
||||
|
||||
static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature * crea, si32 amount)
|
||||
{
|
||||
army.totalStrength += crea->getFightValue() * amount;
|
||||
|
||||
bool walker = true;
|
||||
if(crea->hasBonusOfType(BonusType::SHOOTER))
|
||||
{
|
||||
army.shootersStrength += crea->getFightValue() * amount;
|
||||
walker = false;
|
||||
}
|
||||
if(crea->hasBonusOfType(BonusType::FLYING))
|
||||
{
|
||||
army.flyersStrength += crea->getFightValue() * amount;
|
||||
walker = false;
|
||||
}
|
||||
if(walker)
|
||||
army.walkersStrength += crea->getFightValue() * amount;
|
||||
}
|
||||
|
||||
IObjectInfo::CArmyStructure CBankInfo::minGuards() const
|
||||
{
|
||||
JsonRandom::Variables emptyVariables;
|
||||
|
||||
std::vector<IObjectInfo::CArmyStructure> armies;
|
||||
for(auto configEntry : config)
|
||||
{
|
||||
auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"], emptyVariables);
|
||||
IObjectInfo::CArmyStructure army;
|
||||
for(auto & stack : stacks)
|
||||
{
|
||||
assert(!stack.allowedCreatures.empty());
|
||||
auto weakest = boost::range::min_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b)
|
||||
{
|
||||
return a->getFightValue() < b->getFightValue();
|
||||
});
|
||||
addStackToArmy(army, *weakest, stack.minAmount);
|
||||
}
|
||||
armies.push_back(army);
|
||||
}
|
||||
return *boost::range::min_element(armies);
|
||||
}
|
||||
|
||||
IObjectInfo::CArmyStructure CBankInfo::maxGuards() const
|
||||
{
|
||||
JsonRandom::Variables emptyVariables;
|
||||
|
||||
std::vector<IObjectInfo::CArmyStructure> armies;
|
||||
for(auto configEntry : config)
|
||||
{
|
||||
auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"], emptyVariables);
|
||||
IObjectInfo::CArmyStructure army;
|
||||
for(auto & stack : stacks)
|
||||
{
|
||||
assert(!stack.allowedCreatures.empty());
|
||||
auto strongest = boost::range::max_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b)
|
||||
{
|
||||
return a->getFightValue() < b->getFightValue();
|
||||
});
|
||||
addStackToArmy(army, *strongest, stack.maxAmount);
|
||||
}
|
||||
armies.push_back(army);
|
||||
}
|
||||
return *boost::range::max_element(armies);
|
||||
}
|
||||
|
||||
TPossibleGuards CBankInfo::getPossibleGuards() const
|
||||
TPossibleGuards CBankInfo::getPossibleGuards(IGameCallback * cb) const
|
||||
{
|
||||
JsonRandom::Variables emptyVariables;
|
||||
JsonRandom randomizer(cb);
|
||||
TPossibleGuards out;
|
||||
|
||||
for(const JsonNode & configEntry : config)
|
||||
{
|
||||
const JsonNode & guardsInfo = configEntry["guards"];
|
||||
auto stacks = JsonRandom::evaluateCreatures(guardsInfo, emptyVariables);
|
||||
auto stacks = randomizer.evaluateCreatures(guardsInfo, emptyVariables);
|
||||
IObjectInfo::CArmyStructure army;
|
||||
|
||||
|
||||
@ -188,15 +125,16 @@ std::vector<PossibleReward<TResources>> CBankInfo::getPossibleResourcesReward()
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<PossibleReward<CStackBasicDescriptor>> CBankInfo::getPossibleCreaturesReward() const
|
||||
std::vector<PossibleReward<CStackBasicDescriptor>> CBankInfo::getPossibleCreaturesReward(IGameCallback * cb) const
|
||||
{
|
||||
JsonRandom::Variables emptyVariables;
|
||||
JsonRandom randomizer(cb);
|
||||
std::vector<PossibleReward<CStackBasicDescriptor>> aproximateReward;
|
||||
|
||||
for(const JsonNode & configEntry : config)
|
||||
{
|
||||
const JsonNode & guardsInfo = configEntry["reward"]["creatures"];
|
||||
auto stacks = JsonRandom::evaluateCreatures(guardsInfo, emptyVariables);
|
||||
auto stacks = randomizer.evaluateCreatures(guardsInfo, emptyVariables);
|
||||
|
||||
for(auto stack : stacks)
|
||||
{
|
||||
|
@ -55,13 +55,9 @@ class DLL_LINKAGE CBankInfo : public IObjectInfo
|
||||
public:
|
||||
CBankInfo(const JsonVector & Config);
|
||||
|
||||
TPossibleGuards getPossibleGuards() const;
|
||||
TPossibleGuards getPossibleGuards(IGameCallback * cb) const;
|
||||
std::vector<PossibleReward<TResources>> getPossibleResourcesReward() const;
|
||||
std::vector<PossibleReward<CStackBasicDescriptor>> getPossibleCreaturesReward() const;
|
||||
|
||||
// These functions should try to evaluate minimal possible/max possible guards to give provide information on possible thread to AI
|
||||
CArmyStructure minGuards() const override;
|
||||
CArmyStructure maxGuards() const override;
|
||||
std::vector<PossibleReward<CStackBasicDescriptor>> getPossibleCreaturesReward(IGameCallback * cb) const;
|
||||
|
||||
bool givesResources() const override;
|
||||
bool givesArtifacts() const override;
|
||||
@ -71,7 +67,7 @@ public:
|
||||
|
||||
class CBankInstanceConstructor : public CDefaultObjectTypeHandler<CBank>
|
||||
{
|
||||
BankConfig generateConfig(const JsonNode & conf, CRandomGenerator & rng) const;
|
||||
BankConfig generateConfig(IGameCallback * cb, const JsonNode & conf, CRandomGenerator & rng) const;
|
||||
|
||||
JsonVector levels;
|
||||
|
||||
|
@ -27,9 +27,9 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
|
||||
randomizeObject(castedObject, rng);
|
||||
}
|
||||
|
||||
CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const final
|
||||
CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const final
|
||||
{
|
||||
ObjectType * result = createObject();
|
||||
ObjectType * result = createObject(cb);
|
||||
|
||||
preInitObject(result);
|
||||
|
||||
@ -44,9 +44,9 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
|
||||
protected:
|
||||
virtual void initializeObject(ObjectType * object) const {}
|
||||
virtual void randomizeObject(ObjectType * object, CRandomGenerator & rng) const {}
|
||||
virtual ObjectType * createObject() const
|
||||
virtual ObjectType * createObject(IGameCallback * cb) const
|
||||
{
|
||||
return new ObjectType();
|
||||
return new ObjectType(cb);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -31,9 +31,9 @@ bool CRewardableConstructor::hasNameTextID() const
|
||||
return !objectInfo.getParameters()["name"].isNull();
|
||||
}
|
||||
|
||||
CGObjectInstance * CRewardableConstructor::create(std::shared_ptr<const ObjectTemplate> tmpl) const
|
||||
CGObjectInstance * CRewardableConstructor::create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const
|
||||
{
|
||||
auto * ret = new CRewardableObject();
|
||||
auto * ret = new CRewardableObject(cb);
|
||||
preInitObject(ret);
|
||||
ret->appearance = tmpl;
|
||||
ret->blockVisit = blockVisit;
|
||||
@ -44,7 +44,7 @@ void CRewardableConstructor::configureObject(CGObjectInstance * object, CRandomG
|
||||
{
|
||||
if(auto * rewardableObject = dynamic_cast<CRewardableObject*>(object))
|
||||
{
|
||||
objectInfo.configureObject(rewardableObject->configuration, rng);
|
||||
objectInfo.configureObject(rewardableObject->configuration, rng, object->cb);
|
||||
for(auto & rewardInfo : rewardableObject->configuration.info)
|
||||
{
|
||||
for (auto & bonus : rewardInfo.reward.bonuses)
|
||||
|
@ -25,7 +25,7 @@ class DLL_LINKAGE CRewardableConstructor : public AObjectTypeHandler
|
||||
public:
|
||||
bool hasNameTextID() const override;
|
||||
|
||||
CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
|
||||
CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
|
||||
|
||||
void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
|
||||
|
||||
|
@ -102,7 +102,7 @@ void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
|
||||
|
||||
void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, CRandomGenerator & rng) const
|
||||
{
|
||||
auto templ = getOverride(CGObjectInstance::cb->getTile(object->pos)->terType->getId(), object);
|
||||
auto templ = getOverride(object->cb->getTile(object->pos)->terType->getId(), object);
|
||||
if(templ)
|
||||
object->appearance = templ;
|
||||
}
|
||||
@ -122,7 +122,7 @@ void CHeroInstanceConstructor::initTypeData(const JsonNode & input)
|
||||
VLC->identifiers()->requestIdentifier(
|
||||
"heroClass",
|
||||
input["heroClass"],
|
||||
[&](si32 index) { heroClass = VLC->heroh->classes[index]; });
|
||||
[&](si32 index) { heroClass = HeroClassID(index).toHeroClass(); });
|
||||
|
||||
filtersJson = input["filters"];
|
||||
}
|
||||
@ -224,7 +224,7 @@ void MarketInstanceConstructor::initTypeData(const JsonNode & input)
|
||||
speech = input["speech"].String();
|
||||
}
|
||||
|
||||
CGMarket * MarketInstanceConstructor::createObject() const
|
||||
CGMarket * MarketInstanceConstructor::createObject(IGameCallback * cb) const
|
||||
{
|
||||
if(marketModes.size() == 1)
|
||||
{
|
||||
@ -232,13 +232,13 @@ CGMarket * MarketInstanceConstructor::createObject() const
|
||||
{
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
return new CGBlackMarket;
|
||||
return new CGBlackMarket(cb);
|
||||
|
||||
case EMarketMode::RESOURCE_SKILL:
|
||||
return new CGUniversity;
|
||||
return new CGUniversity(cb);
|
||||
}
|
||||
}
|
||||
return new CGMarket;
|
||||
return new CGMarket(cb);
|
||||
}
|
||||
|
||||
void MarketInstanceConstructor::initializeObject(CGMarket * market) const
|
||||
@ -256,11 +256,12 @@ void MarketInstanceConstructor::initializeObject(CGMarket * market) const
|
||||
|
||||
void MarketInstanceConstructor::randomizeObject(CGMarket * object, CRandomGenerator & rng) const
|
||||
{
|
||||
JsonRandom randomizer(object->cb);
|
||||
JsonRandom::Variables emptyVariables;
|
||||
|
||||
if(auto * university = dynamic_cast<CGUniversity *>(object))
|
||||
{
|
||||
for(auto skill : JsonRandom::loadSecondaries(predefinedOffer, rng, emptyVariables))
|
||||
for(auto skill : randomizer.loadSecondaries(predefinedOffer, rng, emptyVariables))
|
||||
university->skills.push_back(skill.first);
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ protected:
|
||||
void initTypeData(const JsonNode & input) override;
|
||||
|
||||
public:
|
||||
CFaction * faction = nullptr;
|
||||
const CFaction * faction = nullptr;
|
||||
std::map<std::string, LogicalExpression<BuildingID>> filters;
|
||||
|
||||
void initializeObject(CGTownInstance * object) const override;
|
||||
@ -76,7 +76,7 @@ protected:
|
||||
void initTypeData(const JsonNode & input) override;
|
||||
|
||||
public:
|
||||
CHeroClass * heroClass = nullptr;
|
||||
const CHeroClass * heroClass = nullptr;
|
||||
std::map<std::string, LogicalExpression<HeroTypeID>> filters;
|
||||
|
||||
void initializeObject(CGHeroInstance * object) const override;
|
||||
@ -121,7 +121,7 @@ protected:
|
||||
std::string speech;
|
||||
|
||||
public:
|
||||
CGMarket * createObject() const override;
|
||||
CGMarket * createObject(IGameCallback * cb) const override;
|
||||
void initializeObject(CGMarket * object) const override;
|
||||
void randomizeObject(CGMarket * object, CRandomGenerator & rng) const override;
|
||||
|
||||
|
@ -45,7 +45,7 @@ void DwellingInstanceConstructor::initTypeData(const JsonNode & input)
|
||||
{
|
||||
VLC->identifiers()->requestIdentifier("creature", creaturesOnLevel[currentCreature], [=] (si32 index)
|
||||
{
|
||||
availableCreatures[currentLevel][currentCreature] = VLC->creh->objects[index];
|
||||
availableCreatures[currentLevel][currentCreature] = CreatureID(index).toCreature();
|
||||
});
|
||||
}
|
||||
assert(!availableCreatures[currentLevel].empty());
|
||||
@ -68,9 +68,9 @@ void DwellingInstanceConstructor::initializeObject(CGDwelling * obj) const
|
||||
}
|
||||
}
|
||||
|
||||
void DwellingInstanceConstructor::randomizeObject(CGDwelling * object, CRandomGenerator &rng) const
|
||||
void DwellingInstanceConstructor::randomizeObject(CGDwelling * dwelling, CRandomGenerator &rng) const
|
||||
{
|
||||
auto * dwelling = dynamic_cast<CGDwelling *>(object);
|
||||
JsonRandom randomizer(dwelling->cb);
|
||||
|
||||
dwelling->creatures.clear();
|
||||
dwelling->creatures.reserve(availableCreatures.size());
|
||||
@ -94,7 +94,7 @@ void DwellingInstanceConstructor::randomizeObject(CGDwelling * object, CRandomGe
|
||||
else if(guards.getType() == JsonNode::JsonType::DATA_VECTOR) //custom guards (eg. Elemental Conflux)
|
||||
{
|
||||
JsonRandom::Variables emptyVariables;
|
||||
for(auto & stack : JsonRandom::loadCreatures(guards, rng, emptyVariables))
|
||||
for(auto & stack : randomizer.loadCreatures(guards, rng, emptyVariables))
|
||||
{
|
||||
dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->getId(), stack.count));
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CDefaultObjectTypeHandler.h"
|
||||
#include "../mapObjects/CGDwelling.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CDefaultObjectTypeHandler.h"
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -34,11 +34,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns possible composition of guards. Actual guards would be
|
||||
/// somewhere between these two values
|
||||
virtual CArmyStructure minGuards() const { return CArmyStructure(); }
|
||||
virtual CArmyStructure maxGuards() const { return CArmyStructure(); }
|
||||
|
||||
virtual bool givesResources() const { return false; }
|
||||
|
||||
virtual bool givesExperience() const { return false; }
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CDefaultObjectTypeHandler.h"
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -40,12 +40,13 @@ void CArmedInstance::randomizeArmy(FactionID type)
|
||||
// Take Angelic Alliance troop-mixing freedom of non-evil units into account.
|
||||
CSelector CArmedInstance::nonEvilAlignmentMixSelector = Selector::type()(BonusType::NONEVIL_ALIGNMENT_MIX);
|
||||
|
||||
CArmedInstance::CArmedInstance()
|
||||
:CArmedInstance(false)
|
||||
CArmedInstance::CArmedInstance(IGameCallback *cb)
|
||||
:CArmedInstance(cb, false)
|
||||
{
|
||||
}
|
||||
|
||||
CArmedInstance::CArmedInstance(bool isHypothetic):
|
||||
CArmedInstance::CArmedInstance(IGameCallback *cb, bool isHypothetic):
|
||||
CGObjectInstance(cb),
|
||||
CBonusSystemNode(isHypothetic),
|
||||
nonEvilAlignmentMix(this, nonEvilAlignmentMixSelector),
|
||||
battle(nullptr)
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
virtual CBonusSystemNode & whatShouldBeAttached();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CArmedInstance();
|
||||
CArmedInstance(bool isHypothetic);
|
||||
CArmedInstance(IGameCallback *cb);
|
||||
CArmedInstance(IGameCallback *cb, bool isHypothetic);
|
||||
|
||||
PlayerColor getOwner() const override
|
||||
{
|
||||
|
@ -37,8 +37,10 @@ static std::string visitedTxt(const bool visited)
|
||||
return VLC->generaltexth->allTexts[id];
|
||||
}
|
||||
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CBank::CBank() = default;
|
||||
CBank::CBank(IGameCallback *cb)
|
||||
: CArmedInstance(cb)
|
||||
{}
|
||||
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CBank::~CBank() = default;
|
||||
|
||||
|
@ -27,7 +27,7 @@ class DLL_LINKAGE CBank : public CArmedInstance
|
||||
void doVisit(const CGHeroInstance * hero) const;
|
||||
|
||||
public:
|
||||
CBank();
|
||||
CBank(IGameCallback *cb);
|
||||
~CBank() override;
|
||||
|
||||
void setConfig(const BankConfig & bc);
|
||||
|
@ -313,11 +313,11 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
||||
powerFactor = -3;
|
||||
|
||||
std::set<CreatureID> myKindCres; //what creatures are the same kind as we
|
||||
const CCreature * myCreature = VLC->creh->objects[getCreature().getNum()];
|
||||
const CCreature * myCreature = getCreature().toCreature();
|
||||
myKindCres.insert(myCreature->getId()); //we
|
||||
myKindCres.insert(myCreature->upgrades.begin(), myCreature->upgrades.end()); //our upgrades
|
||||
|
||||
for(ConstTransitivePtr<CCreature> &crea : VLC->creh->objects)
|
||||
for(auto const & crea : VLC->creh->objects)
|
||||
{
|
||||
if(vstd::contains(crea->upgrades, myCreature->getId())) //it's our base creatures
|
||||
myKindCres.insert(crea->getId());
|
||||
|
@ -18,6 +18,8 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class DLL_LINKAGE CGCreature : public CArmedInstance //creatures on map
|
||||
{
|
||||
public:
|
||||
using CArmedInstance::CArmedInstance;
|
||||
|
||||
enum Action {
|
||||
FIGHT = -2, FLEE = -1, JOIN_FOR_FREE = 0 //values > 0 mean gold price
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../mapObjectConstructors/DwellingInstanceConstructor.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../networkPacks/StackLocation.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
#include "../networkPacks/PacksForClientBattle.h"
|
||||
@ -43,7 +44,10 @@ void CGDwellingRandomizationInfo::serializeJson(JsonSerializeFormat & handler)
|
||||
}
|
||||
}
|
||||
|
||||
CGDwelling::CGDwelling() = default;
|
||||
CGDwelling::CGDwelling(IGameCallback *cb):
|
||||
CArmedInstance(cb)
|
||||
{}
|
||||
|
||||
CGDwelling::~CGDwelling() = default;
|
||||
|
||||
FactionID CGDwelling::randomizeFaction(CRandomGenerator & rand)
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
std::optional<CGDwellingRandomizationInfo> randomizationInfo; //random dwelling options; not serialized
|
||||
TCreaturesSet creatures; //creatures[level] -> <vector of alternative ids (base creature and upgrades, creatures amount>
|
||||
|
||||
CGDwelling();
|
||||
CGDwelling(IGameCallback *cb);
|
||||
~CGDwelling() override;
|
||||
|
||||
protected:
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "../serializer/JsonSerializeFormat.h"
|
||||
#include "../mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
#include "../modding/ModScope.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
#include "../networkPacks/PacksForClientBattle.h"
|
||||
@ -274,7 +275,9 @@ int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti)
|
||||
return ti->valOfBonuses(BonusType::MOVEMENT, onLand ? BonusCustomSubtype::heroMovementLand : BonusCustomSubtype::heroMovementSea);
|
||||
}
|
||||
|
||||
CGHeroInstance::CGHeroInstance():
|
||||
CGHeroInstance::CGHeroInstance(IGameCallback * cb)
|
||||
: CArmedInstance(cb),
|
||||
type(nullptr),
|
||||
tacticFormationEnabled(false),
|
||||
inTownGarrison(false),
|
||||
moveDir(4),
|
||||
@ -316,7 +319,7 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
|
||||
{
|
||||
assert(validTypes(true));
|
||||
if(!type)
|
||||
type = VLC->heroh->objects[getHeroType().getNum()];
|
||||
type = getHeroType().toHeroType();
|
||||
|
||||
if (ID == Obj::HERO)
|
||||
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
||||
@ -590,11 +593,11 @@ void CGHeroInstance::pickRandomObject(CRandomGenerator & rand)
|
||||
{
|
||||
ID = Obj::HERO;
|
||||
subID = cb->gameState()->pickNextHeroType(getOwner());
|
||||
type = VLC->heroh->objects[getHeroType().getNum()];
|
||||
type = getHeroType().toHeroType();
|
||||
randomizeArmy(type->heroClass->faction);
|
||||
}
|
||||
else
|
||||
type = VLC->heroh->objects[getHeroType().getNum()];
|
||||
type = getHeroType().toHeroType();
|
||||
|
||||
auto oldSubID = subID;
|
||||
|
||||
@ -789,7 +792,7 @@ void CGHeroInstance::spendMana(ServerCallback * server, const int spellCost) con
|
||||
|
||||
bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
|
||||
{
|
||||
const bool isAllowed = IObjectInterface::cb->isAllowed(spell->getId());
|
||||
const bool isAllowed = cb->isAllowed(spell->getId());
|
||||
|
||||
const bool inSpellBook = vstd::contains(spells, spell->getId()) && hasSpellbook();
|
||||
const bool specificBonus = hasBonusOfType(BonusType::SPELL, BonusSubtypeID(spell->getId()));
|
||||
@ -853,7 +856,7 @@ bool CGHeroInstance::canLearnSpell(const spells::Spell * spell, bool allowBanned
|
||||
return false;//creature abilities can not be learned
|
||||
}
|
||||
|
||||
if(!allowBanned && !IObjectInterface::cb->isAllowed(spell->getId()))
|
||||
if(!allowBanned && !cb->isAllowed(spell->getId()))
|
||||
{
|
||||
logGlobal->warn("Hero %s try to learn banned spell %s", nodeName(), spell->getNameTranslated());
|
||||
return false;//banned spells should not be learned
|
||||
@ -879,7 +882,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
||||
double necromancySkill = valOfBonuses(BonusType::UNDEAD_RAISE_PERCENTAGE) / 100.0;
|
||||
const ui8 necromancyLevel = valOfBonuses(BonusType::IMPROVED_NECROMANCY);
|
||||
vstd::amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
|
||||
const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
|
||||
const std::map<CreatureID,si32> &casualties = battleResult.casualties[!battleResult.winner];
|
||||
// figure out what to raise - pick strongest creature meeting requirements
|
||||
CreatureID creatureTypeRaised = CreatureID::NONE; //now we always have IMPROVED_NECROMANCY, no need for hardcode
|
||||
int requiredCasualtyLevel = 1;
|
||||
@ -888,7 +891,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
||||
{
|
||||
int maxCasualtyLevel = 1;
|
||||
for(const auto & casualty : casualties)
|
||||
vstd::amax(maxCasualtyLevel, VLC->creatures()->getByIndex(casualty.first)->getLevel());
|
||||
vstd::amax(maxCasualtyLevel, VLC->creatures()->getById(casualty.first)->getLevel());
|
||||
// pick best bonus available
|
||||
std::shared_ptr<Bonus> topPick;
|
||||
for(const std::shared_ptr<Bonus> & newPick : *improvedNecromancy)
|
||||
@ -936,7 +939,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
||||
double raisedUnits = 0;
|
||||
for(const auto & casualty : casualties)
|
||||
{
|
||||
const CCreature * c = VLC->creh->objects[casualty.first];
|
||||
const CCreature * c = casualty.first.toCreature();
|
||||
double raisedFromCasualty = std::min(c->getMaxHealth() / raisedUnitHealth, 1.0) * casualty.second * necromancySkill;
|
||||
if(c->getLevel() < requiredCasualtyLevel)
|
||||
raisedFromCasualty *= 0.5;
|
||||
@ -1258,7 +1261,7 @@ EDiggingStatus CGHeroInstance::diggingStatus() const
|
||||
{
|
||||
if(static_cast<int>(movement) < movementPointsLimit(true))
|
||||
return EDiggingStatus::LACK_OF_MOVEMENT;
|
||||
if(!VLC->arth->objects[ArtifactID::GRAIL]->canBePutAt(this))
|
||||
if(ArtifactID(ArtifactID::GRAIL).toArtifact()->canBePutAt(this))
|
||||
return EDiggingStatus::BACKPACK_IS_FULL;
|
||||
return cb->getTileDigStatus(visitablePos());
|
||||
}
|
||||
@ -1409,7 +1412,7 @@ void CGHeroInstance::setPrimarySkill(PrimarySkill primarySkill, si64 value, ui8
|
||||
{
|
||||
if(primarySkill < PrimarySkill::EXPERIENCE)
|
||||
{
|
||||
auto skill = getBonusLocalFirst(Selector::type()(BonusType::PRIMARY_SKILL)
|
||||
auto skill = getLocalBonus(Selector::type()(BonusType::PRIMARY_SKILL)
|
||||
.And(Selector::subtype()(BonusSubtypeID(primarySkill)))
|
||||
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL)));
|
||||
assert(skill);
|
||||
@ -1742,7 +1745,7 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
if(!appearance)
|
||||
{
|
||||
// crossoverDeserialize
|
||||
type = VLC->heroh->objects[getHeroType().getNum()];
|
||||
type = getHeroType().toHeroType();
|
||||
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
||||
}
|
||||
|
||||
@ -1760,7 +1763,7 @@ void CGHeroInstance::serializeJsonDefinition(JsonSerializeFormat & handler)
|
||||
|
||||
bool CGHeroInstance::isMissionCritical() const
|
||||
{
|
||||
for(const TriggeredEvent & event : IObjectInterface::cb->getMapHeader()->triggeredEvents)
|
||||
for(const TriggeredEvent & event : cb->getMapHeader()->triggeredEvents)
|
||||
{
|
||||
if (event.effect.type != EventEffect::DEFEAT)
|
||||
continue;
|
||||
|
@ -28,6 +28,8 @@ enum class EHeroGender : uint8_t;
|
||||
class DLL_LINKAGE CGHeroPlaceholder : public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
using CGObjectInstance::CGObjectInstance;
|
||||
|
||||
/// if this is placeholder by power, then power rank of desired hero
|
||||
std::optional<ui8> powerRank;
|
||||
|
||||
@ -69,7 +71,7 @@ public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConstTransitivePtr<CHero> type;
|
||||
const CHero * type;
|
||||
TExpType exp; //experience points
|
||||
ui32 level; //current level of hero
|
||||
|
||||
@ -249,7 +251,7 @@ public:
|
||||
/// If this hero perishes, the scenario is failed
|
||||
bool isMissionCritical() const;
|
||||
|
||||
CGHeroInstance();
|
||||
CGHeroInstance(IGameCallback *cb);
|
||||
virtual ~CGHeroInstance();
|
||||
|
||||
PlayerColor getOwner() const override;
|
||||
|
@ -55,9 +55,9 @@ std::vector<TradeItemBuy> CGMarket::availableItemsIds(EMarketMode mode) const
|
||||
return std::vector<TradeItemBuy>();
|
||||
}
|
||||
|
||||
CGMarket::CGMarket()
|
||||
{
|
||||
}
|
||||
CGMarket::CGMarket(IGameCallback *cb):
|
||||
CGObjectInstance(cb)
|
||||
{}
|
||||
|
||||
std::vector<TradeItemBuy> CGBlackMarket::availableItemsIds(EMarketMode mode) const
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
std::string title;
|
||||
std::string speech; //currently shown only in university
|
||||
|
||||
CGMarket();
|
||||
CGMarket(IGameCallback *cb);
|
||||
///IObjectInterface
|
||||
void onHeroVisit(const CGHeroInstance * h) const override; //open trading window
|
||||
void initObj(CRandomGenerator & rand) override;//set skills for trade
|
||||
@ -49,6 +49,8 @@ public:
|
||||
class DLL_LINKAGE CGBlackMarket : public CGMarket
|
||||
{
|
||||
public:
|
||||
using CGMarket::CGMarket;
|
||||
|
||||
std::vector<const CArtifact *> artifacts; //available artifacts
|
||||
|
||||
void newTurn(CRandomGenerator & rand) const override; //reset artifacts for black market every month
|
||||
@ -64,6 +66,8 @@ public:
|
||||
class DLL_LINKAGE CGUniversity : public CGMarket
|
||||
{
|
||||
public:
|
||||
using CGMarket::CGMarket;
|
||||
|
||||
std::vector<TradeItemBuy> skills; //available skills
|
||||
|
||||
std::vector<TradeItemBuy> availableItemsIds(EMarketMode mode) const override;
|
||||
|
@ -28,7 +28,8 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
//TODO: remove constructor
|
||||
CGObjectInstance::CGObjectInstance():
|
||||
CGObjectInstance::CGObjectInstance(IGameCallback *cb):
|
||||
IObjectInterface(cb),
|
||||
pos(-1,-1,-1),
|
||||
ID(Obj::NO_OBJ),
|
||||
subID(-1),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user