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