1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Remove most of non-const access to VLC entities

This commit is contained in:
Ivan Savenko 2023-12-31 23:43:35 +02:00
parent bd5682ecc3
commit d5c4478816
55 changed files with 236 additions and 305 deletions

View File

@ -350,10 +350,11 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
LOGL("Casting spells sounds like fun. Let's see...");
//Get all spells we can cast
std::vector<const CSpell*> possibleSpells;
vstd::copy_if(VLC->spellh->objects, std::back_inserter(possibleSpells), [hero, this](const CSpell *s) -> bool
{
return s->canBeCast(cb->getBattle(battleID).get(), spells::Mode::HERO, hero);
});
for (auto const & s : VLC->spellh->objects)
if (s->canBeCast(cb->getBattle(battleID).get(), spells::Mode::HERO, hero))
possibleSpells.push_back(s.get());
LOGFL("I can cast %d spells.", possibleSpells.size());
vstd::erase_if(possibleSpells, [](const CSpell *s)

View File

@ -276,12 +276,10 @@ creInfo infoFromDC(const dwellingContent & dc)
ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed
if (ci.creID != CreatureID::NONE)
{
ci.cre = VLC->creatures()->getById(ci.creID);
ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.
ci.level = ci.creID.toCreature()->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.
}
else
{
ci.cre = nullptr;
ci.level = 0;
}
return ci;

View File

@ -163,7 +163,6 @@ struct creInfo
{
int count;
CreatureID creID;
const Creature * cre;
int level;
};
creInfo infoFromDC(const dwellingContent & dc);

View File

@ -63,9 +63,9 @@ std::vector<SlotInfo> ArmyManager::toSlotInfo(std::vector<creInfo> army) const
{
SlotInfo slot;
slot.creature = VLC->creh->objects[i.cre->getId()];
slot.creature = i.creID.toCreature();
slot.count = i.count;
slot.power = evaluateStackPower(i.cre, i.count);
slot.power = evaluateStackPower(i.creID.toCreature(), i.count);
result.push_back(slot);
}
@ -259,7 +259,7 @@ std::shared_ptr<CCreatureSet> ArmyManager::getArmyAvailableToBuyAsCCreatureSet(
if(!ci.count || ci.creID == CreatureID::NONE)
continue;
vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford
vstd::amin(ci.count, availableRes / ci.creID.toCreature()->getFullRecruitCost()); //max count we can afford
if(!ci.count)
continue;
@ -270,7 +270,7 @@ std::shared_ptr<CCreatureSet> ArmyManager::getArmyAvailableToBuyAsCCreatureSet(
break;
army->setCreature(dst, ci.creID, ci.count);
availableRes -= ci.cre->getFullRecruitCost() * ci.count;
availableRes -= ci.creID.toCreature()->getFullRecruitCost() * ci.count;
}
return army;
@ -287,7 +287,7 @@ ui64 ArmyManager::howManyReinforcementsCanBuy(
for(const creInfo & ci : army)
{
aivalue += ci.count * ci.cre->getAIValue();
aivalue += ci.count * ci.creID.toCreature()->getAIValue();
}
return aivalue;
@ -320,7 +320,7 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
if(i < GameConstants::CREATURES_PER_TOWN && countGrowth)
{
ci.count += town ? town->creatureGrowth(i) : ci.cre->getGrowth();
ci.count += town ? town->creatureGrowth(i) : ci.creID.toCreature()->getGrowth();
}
if(!ci.count) continue;
@ -334,13 +334,13 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
freeHeroSlots--; //new slot will be occupied
}
vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford
vstd::amin(ci.count, availableRes / ci.creID.toCreature()->getFullRecruitCost()); //max count we can afford
if(!ci.count) continue;
ci.level = i; //this is important for Dungeon Summoning Portal
creaturesInDwellings.push_back(ci);
availableRes -= ci.cre->getFullRecruitCost() * ci.count;
availableRes -= ci.creID.toCreature()->getFullRecruitCost() * ci.count;
}
return creaturesInDwellings;

View File

@ -54,12 +54,12 @@ void BuyArmy::accept(AIGateway * ai)
if(objid != CreatureID::NONE && ci.creID.getNum() != objid)
continue;
vstd::amin(ci.count, res / ci.cre->getFullRecruitCost());
vstd::amin(ci.count, res / ci.creID.toCreature()->getFullRecruitCost());
if(ci.count)
{
cb->recruitCreatures(town, town->getUpperArmy(), ci.creID, ci.count, ci.level);
valueBought += ci.count * ci.cre->getAIValue();
valueBought += ci.count * ci.creID.toCreature()->getAIValue();
}
}

View File

@ -373,10 +373,10 @@ HeroExchangeArmy * HeroExchangeMap::tryUpgrade(
for(auto & creatureToBuy : buyArmy)
{
auto targetSlot = target->getSlotFor(dynamic_cast<const CCreature*>(creatureToBuy.cre));
auto targetSlot = target->getSlotFor(dynamic_cast<const CCreature*>(creatureToBuy.creID.toCreature()));
target->addToSlot(targetSlot, creatureToBuy.creID, creatureToBuy.count);
target->armyCost += creatureToBuy.cre->getFullRecruitCost() * creatureToBuy.count;
target->armyCost += creatureToBuy.creID.toCreature()->getFullRecruitCost() * creatureToBuy.count;
target->requireBuyArmy = true;
}
}

View File

@ -19,9 +19,6 @@ CServerHandler * CSH;
CGameInfo::CGameInfo()
{
generaltexth = nullptr;
mh = nullptr;
townh = nullptr;
globalServices = nullptr;
}

View File

@ -56,7 +56,7 @@ extern CClientState * CCS;
/// CGameInfo class
/// for allowing different functions for accessing game informations
class CGameInfo : public Services
class CGameInfo final : public Services
{
public:
const ArtifactService * artifacts() const override;
@ -78,19 +78,20 @@ public:
const spells::effects::Registry * spellEffects() const override;
spells::effects::Registry * spellEffects() override;
ConstTransitivePtr<CModHandler> modh; //public?
ConstTransitivePtr<BattleFieldHandler> battleFieldHandler;
ConstTransitivePtr<CHeroHandler> heroh;
ConstTransitivePtr<CCreatureHandler> creh;
ConstTransitivePtr<CSpellHandler> spellh;
ConstTransitivePtr<CSkillHandler> skillh;
ConstTransitivePtr<CObjectHandler> objh;
ConstTransitivePtr<TerrainTypeHandler> terrainTypeHandler;
ConstTransitivePtr<CObjectClassesHandler> objtypeh;
ConstTransitivePtr<ObstacleHandler> obstacleHandler;
CGeneralTextHandler * generaltexth;
CMapHandler * mh;
CTownHandler * townh;
std::shared_ptr<const CModHandler> modh;
std::shared_ptr<const BattleFieldHandler> battleFieldHandler;
std::shared_ptr<const CHeroHandler> heroh;
std::shared_ptr<const CCreatureHandler> creh;
std::shared_ptr<const CSpellHandler> spellh;
std::shared_ptr<const CSkillHandler> skillh;
std::shared_ptr<const CObjectHandler> objh;
std::shared_ptr<const TerrainTypeHandler> terrainTypeHandler;
std::shared_ptr<const CObjectClassesHandler> objtypeh;
std::shared_ptr<const ObstacleHandler> obstacleHandler;
std::shared_ptr<const CGeneralTextHandler> generaltexth;
std::shared_ptr<const CTownHandler> townh;
std::shared_ptr<CMapHandler> mh;
void setFromLib();

View File

@ -370,7 +370,7 @@ void CClient::endGame()
logNetwork->info("Ending current game!");
removeGUI();
vstd::clear_pointer(const_cast<CGameInfo *>(CGI)->mh);
const_cast<CGameInfo *>(CGI)->mh.reset();
vstd::clear_pointer(gs);
logNetwork->info("Deleted mapHandler and gameState.");
@ -392,7 +392,7 @@ void CClient::initMapHandler()
// During loading CPlayerInterface from serialized state it's depend on MH
if(!settings["session"]["headless"].Bool())
{
const_cast<CGameInfo *>(CGI)->mh = new CMapHandler(gs->map);
const_cast<CGameInfo *>(CGI)->mh = std::make_shared<CMapHandler>(gs->map);
logNetwork->trace("Creating mapHandler: %d ms", CSH->th->getDiff());
}

View File

@ -187,14 +187,14 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createScroll(const SpellID & sid)
{
auto ret = new CArtifactInstance(VLC->arth->objects[ArtifactID::SPELL_SCROLL]);
auto ret = new CArtifactInstance(ArtifactID(ArtifactID::SPELL_SCROLL).toArtifact());
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELL,
BonusSource::ARTIFACT_INSTANCE, -1, BonusSourceID(ArtifactID(ArtifactID::SPELL_SCROLL)), BonusSubtypeID(sid));
ret->addNewBonus(bonus);
return ret;
}
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(CArtifact * art)
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const CArtifact * art)
{
assert(art);
@ -216,7 +216,7 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(CArtifa
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const ArtifactID & aid)
{
return ArtifactUtils::createNewArtifactInstance((*VLC->arth)[aid]);
return ArtifactUtils::createNewArtifactInstance(aid.toArtifact());
}
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID)

View File

@ -40,7 +40,7 @@ namespace ArtifactUtils
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
DLL_LINKAGE std::vector<const CArtifact*> assemblyPossibilities(const CArtifactSet * artSet, const ArtifactID & aid);
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(CArtifact * art);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const CArtifact * art);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
DLL_LINKAGE CArtifactInstance * createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID = SpellID::NONE);
DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid);

View File

@ -49,12 +49,12 @@ bool CCombinedArtifact::isCombined() const
return !(constituents.empty());
}
const std::vector<CArtifact*> & CCombinedArtifact::getConstituents() const
const std::vector<const CArtifact*> & CCombinedArtifact::getConstituents() const
{
return constituents;
}
const std::vector<CArtifact*> & CCombinedArtifact::getPartOf() const
const std::vector<const CArtifact*> & CCombinedArtifact::getPartOf() const
{
return partOf;
}
@ -597,7 +597,7 @@ void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node)
{
// when this code is called both combinational art as well as component are loaded
// so it is safe to access any of them
art->constituents.push_back(objects[id]);
art->constituents.push_back(ArtifactID(id).toArtifact());
objects[id]->partOf.push_back(art);
});
}

View File

@ -47,12 +47,12 @@ class DLL_LINKAGE CCombinedArtifact
protected:
CCombinedArtifact() = default;
std::vector<CArtifact*> constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
std::vector<CArtifact*> partOf; // Reverse map of constituents - combined arts that include this art
std::vector<const CArtifact*> constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
std::vector<const CArtifact*> partOf; // Reverse map of constituents - combined arts that include this art
public:
bool isCombined() const;
const std::vector<CArtifact*> & getConstituents() const;
const std::vector<CArtifact*> & getPartOf() const;
const std::vector<const CArtifact*> & getConstituents() const;
const std::vector<const CArtifact*> & getPartOf() const;
};
class DLL_LINKAGE CScrollArtifact

View File

@ -107,7 +107,7 @@ void CArtifactInstance::init()
setNodeType(ARTIFACT_INSTANCE);
}
CArtifactInstance::CArtifactInstance(CArtifact * art)
CArtifactInstance::CArtifactInstance(const CArtifact * art)
{
init();
setType(art);
@ -118,10 +118,10 @@ CArtifactInstance::CArtifactInstance()
init();
}
void CArtifactInstance::setType(CArtifact * art)
void CArtifactInstance::setType(const CArtifact * art)
{
artType = art;
attachTo(*art);
attachTo(const_cast<CArtifact&>(*art));
}
std::string CArtifactInstance::nodeName() const

View File

@ -73,11 +73,11 @@ protected:
ArtifactInstanceID id;
public:
ConstTransitivePtr<CArtifact> artType;
const CArtifact * artType;
CArtifactInstance(CArtifact * art);
CArtifactInstance(const CArtifact * art);
CArtifactInstance();
void setType(CArtifact * art);
void setType(const CArtifact * art);
std::string nodeName() const override;
std::string getDescription() const;
ArtifactID getTypeId() const;

View File

@ -407,20 +407,9 @@ void CCreature::serializeJson(JsonSerializeFormat & handler)
CCreatureHandler::CCreatureHandler()
: expAfterUpgrade(0)
{
VLC->creh = this;
loadCommanders();
}
const CCreature * CCreatureHandler::getCreature(const std::string & scope, const std::string & identifier) const
{
std::optional<si32> index = VLC->identifiers()->getIdentifier(scope, "creature", identifier);
if(!index)
throw std::runtime_error("Creature not found "+identifier);
return objects[*index];
}
void CCreatureHandler::loadCommanders()
{
auto configResource = JsonPath::builtin("config/commanders.json");
@ -797,7 +786,7 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects)
bl.clear();
loadStackExp(b, bl, parser);
for(const auto & b : bl)
(*this)[sid]->addNewBonus(b); //add directly to CCreature Node
objects[sid.getNum()]->addNewBonus(b); //add directly to CCreature Node
}
while (parser.endLine());

View File

@ -222,7 +222,7 @@ public:
std::vector< std::vector <ui8> > skillLevels; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE
std::vector <std::pair <std::shared_ptr<Bonus>, std::pair <ui8, ui8> > > skillRequirements; // first - Bonus, second - which two skills are needed to use it
const CCreature * getCreature(const std::string & scope, const std::string & identifier) const;
//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

View File

@ -739,11 +739,10 @@ void CStackInstance::giveStackExp(TExpType exp)
if (!vstd::iswithin(level, 1, 7))
level = 0;
CCreatureHandler * creh = VLC->creh;
ui32 maxExp = creh->expRanks[level].back();
ui32 maxExp = VLC->creh->expRanks[level].back();
vstd::amin(exp, static_cast<TExpType>(maxExp)); //prevent exp overflow due to different types
vstd::amin(exp, (maxExp * creh->maxExpPerBattle[level])/100);
vstd::amin(exp, (maxExp * VLC->creh->maxExpPerBattle[level])/100);
vstd::amin(experience += exp, maxExp); //can't get more exp than this limit
}
@ -1055,7 +1054,7 @@ void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler)
std::string typeName;
handler.serializeString("type", typeName);
if(!typeName.empty())
setType(VLC->creh->getCreature(ModScope::scopeMap(), typeName));
setType(CreatureID(CreatureID::decode(typeName)).toCreature());
}
}

View File

@ -382,7 +382,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
if(creature->getFaction() == factionIndex && static_cast<int>(creature->getAIValue()) > maxAIValue)
{
maxAIValue = creature->getAIValue();
mostStrong = creature;
mostStrong = creature.get();
}
}

View File

@ -155,6 +155,13 @@ bool CHeroClass::isMagicHero() const
return affinity == MAGIC;
}
int CHeroClass::tavernProbability(FactionID faction) const
{
if (selectionProbability.count(faction))
return selectionProbability.at(faction);
return 0;
}
EAlignment CHeroClass::getAlignment() const
{
return VLC->factions()->getById(faction)->getAlignment();
@ -292,7 +299,7 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js
VLC->identifiers()->requestIdentifier ("creature", node["commander"],
[=](si32 commanderID)
{
heroClass->commander = VLC->creh->objects[commanderID];
heroClass->commander = CreatureID(commanderID).toCreature();
});
heroClass->defaultTavernChance = static_cast<ui32>(node["defaultTavern"].Float());
@ -369,9 +376,9 @@ std::vector<JsonNode> CHeroClassHandler::loadLegacyData()
void CHeroClassHandler::afterLoadFinalization()
{
// for each pair <class, town> set selection probability if it was not set before in tavern entries
for(CHeroClass * heroClass : objects)
for(auto & heroClass : objects)
{
for(CFaction * faction : VLC->townh->objects)
for(auto & faction : VLC->townh->objects)
{
if (!faction->town)
continue;
@ -394,7 +401,7 @@ void CHeroClassHandler::afterLoadFinalization()
}
}
for(CHeroClass * hc : objects)
for(auto const & hc : objects)
{
if (!hc->imageMapMale.empty())
{
@ -454,7 +461,7 @@ CHero * CHeroHandler::loadFromJson(const std::string & scope, const JsonNode & n
VLC->identifiers()->requestIdentifier("heroClass", node["class"],
[=](si32 classID)
{
hero->heroClass = classes[HeroClassID(classID)];
hero->heroClass = HeroClassID(classID).toHeroClass();
});
return hero;
@ -790,7 +797,7 @@ std::set<HeroTypeID> CHeroHandler::getDefaultAllowed() const
{
std::set<HeroTypeID> result;
for(const CHero * hero : objects)
for(auto & hero : objects)
if (hero && !hero->special)
result.insert(hero->getId());

View File

@ -57,7 +57,7 @@ public:
std::vector<InitialArmyStack> initialArmy;
CHeroClass * heroClass{};
const CHeroClass * heroClass = nullptr;
std::vector<std::pair<SecondarySkill, ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
BonusList specialty;
std::set<SpellID> spells;
@ -121,7 +121,7 @@ public:
// resulting chance = sqrt(town.chance * heroClass.chance)
ui32 defaultTavernChance;
CCreature * commander;
const CCreature * commander;
std::vector<int> primarySkillInitial; // initial primary skills
std::vector<int> primarySkillLowLevel; // probability (%) of getting point of primary skill when getting level
@ -154,6 +154,8 @@ public:
void serializeJson(JsonSerializeFormat & handler);
EAlignment getAlignment() const;
int tavernProbability(FactionID faction) const;
};
class DLL_LINKAGE CHeroClassHandler : public CHandlerBase<HeroClassID, HeroClass, CHeroClass, HeroClassService>
@ -189,8 +191,6 @@ class DLL_LINKAGE CHeroHandler : public CHandlerBase<HeroTypeID, HeroType, CHero
std::vector<std::function<void()>> callAfterLoadFinalization;
public:
CHeroClassHandler classes;
ui32 level(TExpType experience) const; //calculates level corresponding to given experience amount
TExpType reqExp(ui32 level) const; //calculates experience required for given level
ui32 maxSupportedLevel() const;

View File

@ -991,7 +991,7 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source)
VLC->identifiers()->requestIdentifier(node.second.meta, "heroClass",node.first, [=](si32 classID)
{
VLC->heroh->classes[HeroClassID(classID)]->selectionProbability[town->faction->getId()] = chance;
VLC->heroclassesh->objects[classID]->selectionProbability[town->faction->getId()] = chance;
});
}

View File

@ -44,11 +44,21 @@ public:
/// allows handler to do post-loading step for validation or integration of loaded data
virtual void afterLoadFinalization(){};
virtual ~IHandlerBase(){}
virtual ~IHandlerBase() = default;
};
template <class _ObjectID, class _ObjectBase, class _Object, class _ServiceBase> class CHandlerBase : public _ServiceBase, public IHandlerBase
{
const _Object * getObjectImpl(const int32_t index) const
{
if(index < 0 || index >= objects.size())
{
logMod->error("%s id %d is invalid", getTypeNames()[0], index);
throw std::runtime_error("Attempt to access invalid index " + std::to_string(index) + " of type " + getTypeNames().front());
}
return objects[index].get();
}
public:
virtual ~CHandlerBase()
{
@ -56,22 +66,31 @@ public:
{
o.dellNull();
}
}
_Object * getObjectWriteable(const int32_t index)
{
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();
}
const Entity * getBaseByIndex(const int32_t index) const override
{
return getByIndex(index);
return getObjectImpl(index);
}
const _ObjectBase * getById(const _ObjectID & id) const override
{
return (*this)[id].get();
return getObjectImpl(id.getNum());
}
const _ObjectBase * getByIndex(const int32_t index) const override
{
return (*this)[_ObjectID(index)].get();
return getObjectImpl(index);
}
void forEachBase(const std::function<void(const Entity * entity, bool & stop)> & cb) const override
@ -105,21 +124,14 @@ public:
registerObject(scope, type_name, name, object->getIndex());
}
ConstTransitivePtr<_Object> operator[] (const _ObjectID id) const
const _Object * operator[] (const _ObjectID id) const
{
const int32_t raw_id = id.getNum();
return operator[](raw_id);
return getObjectImpl(id.getNum());
}
ConstTransitivePtr<_Object> operator[] (int32_t index) const
const _Object * operator[] (int32_t index) const
{
if(index < 0 || index >= objects.size())
{
logMod->error("%s id %d is invalid", getTypeNames()[0], index);
throw std::runtime_error("Attempt to access invalid index " + std::to_string(index) + " of type " + getTypeNames().front());
}
return objects[index];
return getObjectImpl(index);
}
void updateEntity(int32_t index, const JsonNode & data)

View File

@ -519,7 +519,8 @@ namespace JsonRandom
info.minAmount = static_cast<si32>(node["min"].Float());
info.maxAmount = static_cast<si32>(node["max"].Float());
}
const CCreature * crea = VLC->creh->objects[VLC->identifiers()->getIdentifier("creature", node["type"]).value()];
CreatureID creatureID(VLC->identifiers()->getIdentifier("creature", node["type"]).value());
const CCreature * crea = creatureID.toCreature();
info.allowedCreatures.push_back(crea);
if (node["upgradeChance"].Float() > 0)
{

View File

@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
RiverTypeHandler::RiverTypeHandler()
{
objects.push_back(new RiverType);
objects.push_back(new RiverType());
VLC->generaltexth->registerString("core", objects[0]->getNameTextID(), "");
}

View File

@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
RoadTypeHandler::RoadTypeHandler()
{
objects.push_back(new RoadType);
objects.push_back(new RoadType());
VLC->generaltexth->registerString("core", objects[0]->getNameTextID(), "");
}

View File

@ -65,27 +65,27 @@ DLL_LINKAGE void loadDLLClasses(bool onlyEssential)
const ArtifactService * LibClasses::artifacts() const
{
return arth;
return arth.get();
}
const CreatureService * LibClasses::creatures() const
{
return creh;
return creh.get();
}
const FactionService * LibClasses::factions() const
{
return townh;
return townh.get();
}
const HeroClassService * LibClasses::heroClasses() const
{
return &heroh->classes;
return heroclassesh.get();
}
const HeroTypeService * LibClasses::heroTypes() const
{
return heroh;
return heroh.get();
}
#if SCRIPTING_ENABLED
@ -97,22 +97,22 @@ const scripting::Service * LibClasses::scripts() const
const spells::Service * LibClasses::spells() const
{
return spellh;
return spellh.get();
}
const SkillService * LibClasses::skills() const
{
return skillh;
return skillh.get();
}
const IBonusTypeHandler * LibClasses::getBth() const
{
return bth;
return bth.get();
}
const CIdentifierStorage * LibClasses::identifiers() const
{
return identifiersHandler;
return identifiersHandler.get();
}
const spells::effects::Registry * LibClasses::spellEffects() const
@ -127,17 +127,17 @@ spells::effects::Registry * LibClasses::spellEffects()
const BattleFieldService * LibClasses::battlefields() const
{
return battlefieldsHandler;
return battlefieldsHandler.get();
}
const ObstacleService * LibClasses::obstacles() const
{
return obstacleHandler;
return obstacleHandler.get();
}
const IGameSettings * LibClasses::settings() const
{
return settingsHandler;
return settingsHandler.get();
}
void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data)
@ -154,7 +154,7 @@ void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode &
townh->updateEntity(index, data);
break;
case Metatype::HERO_CLASS:
heroh->classes.updateEntity(index, data);
heroclassesh->updateEntity(index, data);
break;
case Metatype::HERO_TYPE:
heroh->updateEntity(index, data);
@ -185,8 +185,8 @@ void LibClasses::loadFilesystem(bool extractArchives)
void LibClasses::loadModFilesystem()
{
CStopWatch loadTime;
modh = new CModHandler();
identifiersHandler = new CIdentifierStorage();
modh = std::make_unique<CModHandler>();
identifiersHandler = std::make_unique<CIdentifierStorage>();
modh->loadMods();
logGlobal->info("\tMod handler: %d ms", loadTime.getDiff());
@ -199,9 +199,9 @@ static void logHandlerLoaded(const std::string & name, CStopWatch & timer)
logGlobal->info("\t\t %s handler: %d ms", name, timer.getDiff());
}
template <class Handler> void createHandler(Handler *&handler, const std::string &name, CStopWatch &timer)
template <class Handler> void createHandler(std::shared_ptr<Handler> & handler, const std::string &name, CStopWatch &timer)
{
handler = new Handler();
handler = std::make_shared<Handler>();
logHandlerLoaded(name, timer);
}
@ -219,6 +219,7 @@ void LibClasses::init(bool onlyEssential)
createHandler(riverTypeHandler, "River", pomtime);
createHandler(terrainTypeHandler, "Terrain", pomtime);
createHandler(heroh, "Hero", pomtime);
createHandler(heroclassesh, "Hero classes", pomtime);
createHandler(arth, "Artifact", pomtime);
createHandler(creh, "Creature", pomtime);
createHandler(townh, "Town", pomtime);
@ -239,77 +240,6 @@ void LibClasses::init(bool onlyEssential)
modh->afterLoad(onlyEssential);
}
void LibClasses::clear()
{
delete heroh;
delete arth;
delete creh;
delete townh;
delete objh;
delete objtypeh;
delete spellh;
delete skillh;
delete modh;
delete bth;
delete tplh;
delete terviewh;
#if SCRIPTING_ENABLED
delete scriptHandler;
#endif
delete battlefieldsHandler;
delete generaltexth;
delete identifiersHandler;
delete obstacleHandler;
delete terrainTypeHandler;
delete riverTypeHandler;
delete roadTypeHandler;
delete settingsHandler;
makeNull();
}
void LibClasses::makeNull()
{
generaltexth = nullptr;
heroh = nullptr;
arth = nullptr;
creh = nullptr;
townh = nullptr;
objh = nullptr;
objtypeh = nullptr;
spellh = nullptr;
skillh = nullptr;
modh = nullptr;
bth = nullptr;
tplh = nullptr;
terviewh = nullptr;
#if SCRIPTING_ENABLED
scriptHandler = nullptr;
#endif
battlefieldsHandler = nullptr;
identifiersHandler = nullptr;
obstacleHandler = nullptr;
terrainTypeHandler = nullptr;
riverTypeHandler = nullptr;
roadTypeHandler = nullptr;
settingsHandler = nullptr;
}
LibClasses::LibClasses()
{
//init pointers to handlers
makeNull();
}
void LibClasses::callWhenDeserializing()
{
//FIXME: check if any of these are needed
//generaltexth = new CGeneralTextHandler();
//generaltexth->load();
//arth->load(true);
//modh->recreateHandlers();
//modh->loadConfigFromFile ("defaultMods"); //TODO: remember last saved config
}
#if SCRIPTING_ENABLED
void LibClasses::scriptsLoaded()
{
@ -317,10 +247,8 @@ void LibClasses::scriptsLoaded()
}
#endif
LibClasses::~LibClasses()
{
clear();
}
LibClasses::LibClasses() = default;
LibClasses::~LibClasses() = default;
std::shared_ptr<CContentHandler> LibClasses::getContent() const
{

View File

@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
class CConsoleHandler;
class CArtHandler;
class CHeroHandler;
class CHeroClassHandler;
class CCreatureHandler;
class CSpellHandler;
class CSkillHandler;
@ -47,20 +48,15 @@ namespace scripting
}
#endif
/// Loads and constructs several handlers
class DLL_LINKAGE LibClasses : public Services
class DLL_LINKAGE LibClasses final : public Services
{
CBonusTypeHandler * bth;
std::shared_ptr<CBonusTypeHandler> bth;
void callWhenDeserializing(); //should be called only by serialize !!!
void makeNull(); //sets all handler pointers to null
std::shared_ptr<CContentHandler> getContent() const;
void setContent(std::shared_ptr<CContentHandler> content);
public:
bool IS_AI_ENABLED = false; //unused?
const ArtifactService * artifacts() const override;
const CreatureService * creatures() const override;
const FactionService * factions() const override;
@ -83,27 +79,27 @@ public:
const IBonusTypeHandler * getBth() const; //deprecated
const CIdentifierStorage * identifiers() const;
CArtHandler * arth;
CHeroHandler * heroh;
CCreatureHandler * creh;
CSpellHandler * spellh;
CSkillHandler * skillh;
CObjectHandler * objh;
CObjectClassesHandler * objtypeh;
CTownHandler * townh;
CGeneralTextHandler * generaltexth;
CModHandler * modh;
std::shared_ptr<CArtHandler> arth;
std::shared_ptr<CHeroHandler> heroh;
std::shared_ptr<CHeroClassHandler> heroclassesh;
std::shared_ptr<CCreatureHandler> creh;
std::shared_ptr<CSpellHandler> spellh;
std::shared_ptr<CSkillHandler> skillh;
std::shared_ptr<CObjectHandler> objh;
std::shared_ptr<CObjectClassesHandler> objtypeh;
std::shared_ptr<CTownHandler> townh;
std::shared_ptr<CGeneralTextHandler> generaltexth;
std::shared_ptr<CModHandler> modh;
std::shared_ptr<TerrainTypeHandler> terrainTypeHandler;
std::shared_ptr<RoadTypeHandler> roadTypeHandler;
std::shared_ptr<RiverTypeHandler> riverTypeHandler;
std::shared_ptr<CIdentifierStorage> identifiersHandler;
std::shared_ptr<CTerrainViewPatternConfig> terviewh;
std::shared_ptr<CRmgTemplateStorage> tplh;
std::shared_ptr<BattleFieldHandler> battlefieldsHandler;
std::shared_ptr<ObstacleHandler> obstacleHandler;
std::shared_ptr<GameSettings> settingsHandler;
TerrainTypeHandler * terrainTypeHandler;
RoadTypeHandler * roadTypeHandler;
RiverTypeHandler * riverTypeHandler;
CIdentifierStorage * identifiersHandler;
CTerrainViewPatternConfig * terviewh;
CRmgTemplateStorage * tplh;
BattleFieldHandler * battlefieldsHandler;
ObstacleHandler * obstacleHandler;
GameSettings * settingsHandler;
#if SCRIPTING_ENABLED
scripting::ScriptHandler * scriptHandler;
#endif
@ -111,7 +107,6 @@ public:
LibClasses(); //c-tor, loads .lods and NULLs handlers
~LibClasses();
void init(bool onlyEssential); //uses standard config file
void clear(); //deletes all handlers and its data
// basic initialization. should be called before init(). Can also extract original H3 archives
void loadFilesystem(bool extractArchives);

View File

@ -151,6 +151,16 @@ std::string HeroClassID::entityType()
return "heroClass";
}
const CHeroClass * HeroClassID::toHeroClass() const
{
return dynamic_cast<const CHeroClass*>(toEntity(VLC));
}
const HeroClass * HeroClassID::toEntity(const Services * services) const
{
return services->heroClasses()->getByIndex(num);
}
si32 ObjectInstanceID::decode(const std::string & identifier)
{
return std::stoi(identifier);

View File

@ -21,6 +21,8 @@ class Creature;
class CreatureService;
class HeroType;
class CHero;
class CHeroClass;
class HeroClass;
class HeroTypeService;
class Faction;
class Skill;
@ -81,6 +83,9 @@ public:
DLL_LINKAGE static si32 decode(const std::string & identifier);
DLL_LINKAGE static std::string encode(const si32 index);
static std::string entityType();
const CHeroClass * toHeroClass() const;
const HeroClass * toEntity(const Services * services) const;
};
class DLL_LINKAGE HeroTypeID : public EntityIdentifier<HeroTypeID>

View File

@ -347,7 +347,7 @@ void CGameStateCampaign::replaceHeroesPlaceholders(const std::vector<CampaignHer
if(heroPlaceholder->tempOwner.isValidPlayer())
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
heroToPlace->pos = heroPlaceholder->pos;
heroToPlace->type = VLC->heroh->objects[heroToPlace->getHeroType().getNum()];
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
gameState->map->removeBlockVisTiles(heroPlaceholder, true);

View File

@ -122,7 +122,7 @@ void CHeroInstanceConstructor::initTypeData(const JsonNode & input)
VLC->identifiers()->requestIdentifier(
"heroClass",
input["heroClass"],
[&](si32 index) { heroClass = VLC->heroh->classes[index]; });
[&](si32 index) { heroClass = HeroClassID(index).toHeroClass(); });
filtersJson = input["filters"];
}

View File

@ -57,7 +57,7 @@ protected:
void initTypeData(const JsonNode & input) override;
public:
CFaction * faction = nullptr;
const CFaction * faction = nullptr;
std::map<std::string, LogicalExpression<BuildingID>> filters;
void initializeObject(CGTownInstance * object) const override;
@ -76,7 +76,7 @@ protected:
void initTypeData(const JsonNode & input) override;
public:
CHeroClass * heroClass = nullptr;
const CHeroClass * heroClass = nullptr;
std::map<std::string, LogicalExpression<HeroTypeID>> filters;
void initializeObject(CGHeroInstance * object) const override;

View File

@ -45,7 +45,7 @@ void DwellingInstanceConstructor::initTypeData(const JsonNode & input)
{
VLC->identifiers()->requestIdentifier("creature", creaturesOnLevel[currentCreature], [=] (si32 index)
{
availableCreatures[currentLevel][currentCreature] = VLC->creh->objects[index];
availableCreatures[currentLevel][currentCreature] = CreatureID(index).toCreature();
});
}
assert(!availableCreatures[currentLevel].empty());

View File

@ -313,11 +313,11 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
powerFactor = -3;
std::set<CreatureID> myKindCres; //what creatures are the same kind as we
const CCreature * myCreature = VLC->creh->objects[getCreature().getNum()];
const CCreature * myCreature = getCreature().toCreature();
myKindCres.insert(myCreature->getId()); //we
myKindCres.insert(myCreature->upgrades.begin(), myCreature->upgrades.end()); //our upgrades
for(ConstTransitivePtr<CCreature> &crea : VLC->creh->objects)
for(auto const & crea : VLC->creh->objects)
{
if(vstd::contains(crea->upgrades, myCreature->getId())) //it's our base creatures
myKindCres.insert(crea->getId());

View File

@ -316,7 +316,7 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
{
assert(validTypes(true));
if(!type)
type = VLC->heroh->objects[getHeroType().getNum()];
type = getHeroType().toHeroType();
if (ID == Obj::HERO)
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
@ -590,11 +590,11 @@ void CGHeroInstance::pickRandomObject(CRandomGenerator & rand)
{
ID = Obj::HERO;
subID = cb->gameState()->pickNextHeroType(getOwner());
type = VLC->heroh->objects[getHeroType().getNum()];
type = getHeroType().toHeroType();
randomizeArmy(type->heroClass->faction);
}
else
type = VLC->heroh->objects[getHeroType().getNum()];
type = getHeroType().toHeroType();
auto oldSubID = subID;
@ -879,7 +879,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
double necromancySkill = valOfBonuses(BonusType::UNDEAD_RAISE_PERCENTAGE) / 100.0;
const ui8 necromancyLevel = valOfBonuses(BonusType::IMPROVED_NECROMANCY);
vstd::amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
const std::map<CreatureID,si32> &casualties = battleResult.casualties[!battleResult.winner];
// figure out what to raise - pick strongest creature meeting requirements
CreatureID creatureTypeRaised = CreatureID::NONE; //now we always have IMPROVED_NECROMANCY, no need for hardcode
int requiredCasualtyLevel = 1;
@ -888,7 +888,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
{
int maxCasualtyLevel = 1;
for(const auto & casualty : casualties)
vstd::amax(maxCasualtyLevel, VLC->creatures()->getByIndex(casualty.first)->getLevel());
vstd::amax(maxCasualtyLevel, VLC->creatures()->getById(casualty.first)->getLevel());
// pick best bonus available
std::shared_ptr<Bonus> topPick;
for(const std::shared_ptr<Bonus> & newPick : *improvedNecromancy)
@ -936,7 +936,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
double raisedUnits = 0;
for(const auto & casualty : casualties)
{
const CCreature * c = VLC->creh->objects[casualty.first];
const CCreature * c = casualty.first.toCreature();
double raisedFromCasualty = std::min(c->getMaxHealth() / raisedUnitHealth, 1.0) * casualty.second * necromancySkill;
if(c->getLevel() < requiredCasualtyLevel)
raisedFromCasualty *= 0.5;
@ -1742,7 +1742,7 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
if(!appearance)
{
// crossoverDeserialize
type = VLC->heroh->objects[getHeroType().getNum()];
type = getHeroType().toHeroType();
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
}

View File

@ -69,7 +69,7 @@ public:
//////////////////////////////////////////////////////////////////////////
ConstTransitivePtr<CHero> type;
const CHero * type;
TExpType exp; //experience points
ui32 level; //current level of hero

View File

@ -769,7 +769,7 @@ void CGArtifact::initObj(CRandomGenerator & rand)
storedArtifact = a;
}
if(!storedArtifact->artType)
storedArtifact->setType(VLC->arth->objects[getArtifact().getNum()]);
storedArtifact->setType(getArtifact().toArtifact());
}
if(ID == Obj::SPELL_SCROLL)
subID = 1;

View File

@ -510,7 +510,7 @@ CDrawTerrainOperation::InvalidTiles CDrawTerrainOperation::getInvalidTiles(const
{
if(map->isInTheMap(pos))
{
auto * ptrConfig = VLC->terviewh;
const auto & ptrConfig = VLC->terviewh;
const auto * terType = map->getTile(pos).terType;
auto valid = validateTerrainView(pos, ptrConfig->getTerrainTypePatternById("n1")).result;

View File

@ -760,7 +760,7 @@ void CMapLoaderH3M::readAllowedArtifacts()
// ban combo artifacts
if(!features.levelSOD)
{
for(CArtifact * artifact : VLC->arth->objects)
for(auto const & artifact : VLC->arth->objects)
if(artifact->isCombined())
map->allowedArtifact.erase(artifact->getId());
}

View File

@ -189,23 +189,23 @@ void ContentTypeHandler::afterLoadFinalization()
void CContentHandler::init()
{
handlers.insert(std::make_pair("heroClasses", ContentTypeHandler(&VLC->heroh->classes, "heroClass")));
handlers.insert(std::make_pair("artifacts", ContentTypeHandler(VLC->arth, "artifact")));
handlers.insert(std::make_pair("creatures", ContentTypeHandler(VLC->creh, "creature")));
handlers.insert(std::make_pair("factions", ContentTypeHandler(VLC->townh, "faction")));
handlers.insert(std::make_pair("objects", ContentTypeHandler(VLC->objtypeh, "object")));
handlers.insert(std::make_pair("heroes", ContentTypeHandler(VLC->heroh, "hero")));
handlers.insert(std::make_pair("spells", ContentTypeHandler(VLC->spellh, "spell")));
handlers.insert(std::make_pair("skills", ContentTypeHandler(VLC->skillh, "skill")));
handlers.insert(std::make_pair("templates", ContentTypeHandler(VLC->tplh, "template")));
handlers.insert(std::make_pair("heroClasses", ContentTypeHandler(VLC->heroclassesh.get(), "heroClass")));
handlers.insert(std::make_pair("artifacts", ContentTypeHandler(VLC->arth.get(), "artifact")));
handlers.insert(std::make_pair("creatures", ContentTypeHandler(VLC->creh.get(), "creature")));
handlers.insert(std::make_pair("factions", ContentTypeHandler(VLC->townh.get(), "faction")));
handlers.insert(std::make_pair("objects", ContentTypeHandler(VLC->objtypeh.get(), "object")));
handlers.insert(std::make_pair("heroes", ContentTypeHandler(VLC->heroh.get(), "hero")));
handlers.insert(std::make_pair("spells", ContentTypeHandler(VLC->spellh.get(), "spell")));
handlers.insert(std::make_pair("skills", ContentTypeHandler(VLC->skillh.get(), "skill")));
handlers.insert(std::make_pair("templates", ContentTypeHandler(VLC->tplh.get(), "template")));
#if SCRIPTING_ENABLED
handlers.insert(std::make_pair("scripts", ContentTypeHandler(VLC->scriptHandler, "script")));
#endif
handlers.insert(std::make_pair("battlefields", ContentTypeHandler(VLC->battlefieldsHandler, "battlefield")));
handlers.insert(std::make_pair("terrains", ContentTypeHandler(VLC->terrainTypeHandler, "terrain")));
handlers.insert(std::make_pair("rivers", ContentTypeHandler(VLC->riverTypeHandler, "river")));
handlers.insert(std::make_pair("roads", ContentTypeHandler(VLC->roadTypeHandler, "road")));
handlers.insert(std::make_pair("obstacles", ContentTypeHandler(VLC->obstacleHandler, "obstacle")));
handlers.insert(std::make_pair("battlefields", ContentTypeHandler(VLC->battlefieldsHandler.get(), "battlefield")));
handlers.insert(std::make_pair("terrains", ContentTypeHandler(VLC->terrainTypeHandler.get(), "terrain")));
handlers.insert(std::make_pair("rivers", ContentTypeHandler(VLC->riverTypeHandler.get(), "river")));
handlers.insert(std::make_pair("roads", ContentTypeHandler(VLC->roadTypeHandler.get(), "road")));
handlers.insert(std::make_pair("obstacles", ContentTypeHandler(VLC->obstacleHandler.get(), "obstacle")));
//TODO: any other types of moddables?
}

View File

@ -1118,7 +1118,7 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
struct DLL_LINKAGE AssembledArtifact : CArtifactOperationPack
{
ArtifactLocation al; //where assembly will be put
CArtifact * builtArt;
const CArtifact * builtArt;
void applyGs(CGameState * gs);

View File

@ -128,7 +128,7 @@ struct DLL_LINKAGE BattleResult : public Query
BattleID battleID = BattleID::NONE;
EBattleResult result = EBattleResult::NORMAL;
ui8 winner = 2; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
std::map<ui32, si32> casualties[2]; //first => casualties of attackers - map crid => number
std::map<CreatureID, si32> casualties[2]; //first => casualties of attackers - map crid => number
TExpType exp[2] = {0, 0}; //exp for attacker and defender
std::set<ArtifactInstanceID> artifacts; //artifacts taken from loser to winner - currently unused

View File

@ -159,12 +159,12 @@ void TreasurePlacer::addAllPossibleObjects()
//all following objects are unlimited
oi.maxPerZone = std::numeric_limits<ui32>::max();
std::vector<CCreature *> creatures; //native creatures for this zone
std::vector<const CCreature *> creatures; //native creatures for this zone
for(auto cre : VLC->creh->objects)
{
if(!cre->special && cre->getFaction() == zone.getTownType())
{
creatures.push_back(cre);
creatures.push_back(cre.get());
}
}
@ -283,7 +283,7 @@ void TreasurePlacer::addAllPossibleObjects()
//pandora box with creatures
const std::vector<int> & tierValues = generator.getConfig().pandoraCreatureValues;
auto creatureToCount = [tierValues](CCreature * creature) -> int
auto creatureToCount = [tierValues](const CCreature * creature) -> int
{
if(!creature->getAIValue() || tierValues.empty()) //bug #2681
return 0; //this box won't be generated
@ -350,11 +350,11 @@ void TreasurePlacer::addAllPossibleObjects()
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
std::vector <CSpell *> spells;
std::vector <const CSpell *> spells;
for(auto spell : VLC->spellh->objects)
{
if(map.isAllowedSpell(spell->id) && spell->getLevel() == i)
spells.push_back(spell);
spells.push_back(spell.get());
}
RandomGeneratorUtil::randomShuffle(spells, zone.getRand());
@ -383,11 +383,11 @@ void TreasurePlacer::addAllPossibleObjects()
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
std::vector <CSpell *> spells;
std::vector <const CSpell *> spells;
for(auto spell : VLC->spellh->objects)
{
if(map.isAllowedSpell(spell->id) && spell->school[SpellSchool(i)])
spells.push_back(spell);
if(map.isAllowedSpell(spell->id) && spell->hasSchool(SpellSchool(i)))
spells.push_back(spell.get());
}
RandomGeneratorUtil::randomShuffle(spells, zone.getRand());
@ -415,11 +415,11 @@ void TreasurePlacer::addAllPossibleObjects()
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
std::vector <CSpell *> spells;
std::vector <const CSpell *> spells;
for(auto spell : VLC->spellh->objects)
{
if(map.isAllowedSpell(spell->id))
spells.push_back(spell);
spells.push_back(spell.get());
}
RandomGeneratorUtil::randomShuffle(spells, zone.getRand());

View File

@ -24,14 +24,8 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
{
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects,
[](const CGObjectInstance &obj){ return obj.id; });
registerVectoredType<CHero, HeroTypeID>(&lib->heroh->objects,
[](const CHero &h){ return h.getId(); });
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes,
[](const CGHeroInstance &h){ return h.type->getId(); });
registerVectoredType<CCreature, CreatureID>(&lib->creh->objects,
[](const CCreature &cre){ return cre.getId(); });
registerVectoredType<CArtifact, ArtifactID>(&lib->arth->objects,
[](const CArtifact &art){ return art.getId(); });
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->map->artInstances,
[](const CArtifactInstance &artInst){ return artInst.getId(); });
registerVectoredType<CQuest, si32>(&gs->map->quests,

View File

@ -65,11 +65,6 @@ class DLL_LINKAGE CSerializer
return t.getNum();
}
template <typename T, typename U>
void registerVectoredType(const std::vector<T*> *Vector, const std::function<U(const T&)> &idRetriever)
{
vectors[&typeid(T)] = VectorizedObjectInfo<T, U>(Vector, idRetriever);
}
template <typename T, typename U>
void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const std::function<U(const T&)> &idRetriever)
{

View File

@ -969,7 +969,7 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode &
void CSpellHandler::afterLoadFinalization()
{
for(auto spell : objects)
for(auto & spell : objects)
{
spell->setupMechanics();
}
@ -997,7 +997,7 @@ std::set<SpellID> CSpellHandler::getDefaultAllowed() const
{
std::set<SpellID> allowedSpells;
for(const CSpell * s : objects)
for(auto const & s : objects)
if (!s->isSpecial() && !s->isCreatureAbility())
allowedSpells.insert(s->getId());

View File

@ -125,7 +125,7 @@ void Graphics::load()
void Graphics::loadHeroAnimations()
{
for(auto & elem : VLC->heroh->classes.objects)
for(auto & elem : VLC->heroclassesh->objects)
{
for(auto templ : VLC->objtypeh->getHandlerFor(Obj::HERO, elem->getIndex())->getTemplates())
{

View File

@ -142,7 +142,7 @@ void Initializer::initialize(CGHeroInstance * o)
{
if(t->heroClass->getId() == HeroClassID(o->subID))
{
o->type = t;
o->type = t.get();
break;
}
}

View File

@ -153,7 +153,7 @@ void MapController::repairMap(CMap * map) const
}
if(obj->ID != Obj::RANDOM_HERO)
nih->type = type;
nih->type = type.get();
if(nih->ID == Obj::HERO) //not prison
nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();

View File

@ -48,7 +48,7 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
//load factions
for(auto idx : VLC->townh->getAllowedFactions())
{
CFaction * faction = VLC->townh->objects.at(idx);
const CFaction * faction = VLC->townh->objects.at(idx);
auto * item = new QListWidgetItem(QString::fromStdString(faction->getNameTranslated()));
item->setData(Qt::UserRole, QVariant::fromValue(idx.getNum()));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);

View File

@ -78,7 +78,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
if(!hplayers)
issues.emplace_back(tr("No human players allowed to play this map"), true);
std::set<CHero*> allHeroesOnMap; //used to find hero duplicated
std::set<const CHero*> allHeroesOnMap; //used to find hero duplicated
//checking all objects in the map
for(auto o : map->objects)

View File

@ -826,7 +826,7 @@ void CGameHandler::onNewTurn()
if (!t->creatures.at(k).second.empty()) // there are creatures at this level
{
ui32 &availableCount = sac.creatures.at(k).first;
const CCreature *cre = VLC->creh->objects.at(t->creatures.at(k).second.back());
const CCreature *cre = t->creatures.at(k).second.back().toCreature();
if (n.specialWeek == NewTurn::PLAGUE)
availableCount = t->creatures.at(k).first / 2; //halve their number, no growth
@ -2327,7 +2327,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
return;
}
CCreature * crea = VLC->creh->objects.at(t->town->creatures.at(level).at(upgradeNumber));
const CCreature * crea = t->town->creatures.at(level).at(upgradeNumber).toCreature();
SetAvailableCreatures ssi;
ssi.tid = t->id;
@ -2461,7 +2461,7 @@ bool CGameHandler::recruitCreatures(ObjectInstanceID objid, ObjectInstanceID dst
const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(getObj(objid));
const CArmedInstance * army = dynamic_cast<const CArmedInstance *>(getObj(dstid));
const CGHeroInstance * hero = dynamic_cast<const CGHeroInstance *>(getObj(dstid));
const CCreature * c = VLC->creh->objects.at(crid);
const CCreature * c = crid.toCreature();
const bool warMachine = c->warMachine != ArtifactID::NONE;
@ -2568,7 +2568,7 @@ bool CGameHandler::upgradeCreature(ObjectInstanceID objid, SlotID pos, CreatureI
giveResources(player, -totalCost);
//upgrade creature
changeStackType(StackLocation(obj, pos), VLC->creh->objects.at(upgID));
changeStackType(StackLocation(obj, pos), upgID.toCreature());
return true;
}
@ -2756,7 +2756,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLoca
auto hero = getHero(dst.artHolder);
if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dstSlot))
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
giveHeroNewArtifact(hero, ArtifactID(ArtifactID::SPELLBOOK).toArtifact(), ArtifactPosition::SPELLBOOK);
ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
if(src.artHolder != dst.artHolder)
@ -2795,7 +2795,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID
slots.push_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
if(ArtifactUtils::checkSpellbookIsNeeded(dstHero, artifact->getTypeId(), dstSlot))
giveHeroNewArtifact(dstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
giveHeroNewArtifact(dstHero, ArtifactID(ArtifactID::SPELLBOOK).toArtifact(), ArtifactPosition::SPELLBOOK);
}
};
@ -2883,7 +2883,7 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a
const auto dstLoc = ArtifactLocation(hero->id, artifactSlot);
if(assemble)
{
CArtifact * combinedArt = VLC->arth->objects[assembleTo];
const CArtifact * combinedArt = assembleTo.toArtifact();
if(!combinedArt->isCombined())
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to assemble is not a combined artifacts!");
if(!vstd::contains(ArtifactUtils::assemblyPossibilities(hero, destArtifact->getTypeId()), combinedArt))
@ -2897,7 +2897,7 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a
}
if(ArtifactUtils::checkSpellbookIsNeeded(hero, assembleTo, artifactSlot))
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
giveHeroNewArtifact(hero, ArtifactID(ArtifactID::SPELLBOOK).toArtifact(), ArtifactPosition::SPELLBOOK);
AssembledArtifact aa;
aa.al = dstLoc;
@ -2954,7 +2954,7 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid)
return false;
giveResource(hero->getOwner(),EGameResID::GOLD,-GameConstants::SPELLBOOK_GOLD_COST);
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
giveHeroNewArtifact(hero, ArtifactID(ArtifactID::SPELLBOOK).toArtifact(), ArtifactPosition::SPELLBOOK);
assert(hero->getArt(ArtifactPosition::SPELLBOOK));
giveSpells(town,hero);
return true;
@ -3025,7 +3025,7 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, GameRe
COMPLAIN_RET("Cannot find selected artifact on the list");
sendAndApply(&saa);
giveHeroNewArtifact(h, VLC->arth->objects[aid], ArtifactPosition::FIRST_AVAILABLE);
giveHeroNewArtifact(h, aid.toArtifact(), ArtifactPosition::FIRST_AVAILABLE);
return true;
}
@ -4080,7 +4080,7 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
RandomGeneratorUtil::randomShuffle(tiles, getRandomGenerator());
logGlobal->trace("Spawning wandering monsters. Found %d free tiles. Creature type: %d", tiles.size(), creatureID.num);
const CCreature *cre = VLC->creh->objects.at(creatureID);
const CCreature *cre = creatureID.toCreature();
for (int i = 0; i < (int)amount; ++i)
{
tile = tiles.begin();

View File

@ -253,7 +253,7 @@ std::vector<const CHeroClass *> HeroPoolProcessor::findAvailableClassesFor(const
continue;
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
bool heroClassBanned = elem.second->type->heroClass->selectionProbability[factionID] == 0;
bool heroClassBanned = elem.second->type->heroClass->tavernProbability(factionID) == 0;
if(heroAvailable && !heroClassBanned)
result.push_back(elem.second->type->heroClass);
@ -326,13 +326,13 @@ const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerCo
int totalWeight = 0;
for(const auto & heroClass : possibleClasses)
totalWeight += heroClass->selectionProbability.at(factionID);
totalWeight += heroClass->tavernProbability(factionID);
int roll = getRandomGenerator(player).nextInt(totalWeight - 1);
for(const auto & heroClass : possibleClasses)
{
roll -= heroClass->selectionProbability.at(factionID);
roll -= heroClass->tavernProbability(factionID);
if(roll < 0)
return heroClass;
}

View File

@ -137,7 +137,7 @@ void PlayerMessageProcessor::cheatGiveSpells(PlayerColor player, const CGHeroIns
///Give hero spellbook
if (!hero->hasSpellbook())
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
gameHandler->giveHeroNewArtifact(hero, ArtifactID(ArtifactID::SPELLBOOK).toArtifact(), ArtifactPosition::SPELLBOOK);
///Give all spells with bonus (to allow banned spells)
GiveBonus giveBonus(GiveBonus::ETarget::OBJECT);
@ -215,11 +215,11 @@ void PlayerMessageProcessor::cheatGiveMachines(PlayerColor player, const CGHeroI
return;
if (!hero->getArt(ArtifactPosition::MACH1))
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::BALLISTA], ArtifactPosition::MACH1);
gameHandler->giveHeroNewArtifact(hero, ArtifactID(ArtifactID::BALLISTA).toArtifact(), ArtifactPosition::MACH1);
if (!hero->getArt(ArtifactPosition::MACH2))
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::AMMO_CART], ArtifactPosition::MACH2);
gameHandler->giveHeroNewArtifact(hero, ArtifactID(ArtifactID::AMMO_CART).toArtifact(), ArtifactPosition::MACH2);
if (!hero->getArt(ArtifactPosition::MACH3))
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::FIRST_AID_TENT], ArtifactPosition::MACH3);
gameHandler->giveHeroNewArtifact(hero, ArtifactID(ArtifactID::FIRST_AID_TENT).toArtifact(), ArtifactPosition::MACH3);
}
void PlayerMessageProcessor::cheatGiveArtifacts(PlayerColor player, const CGHeroInstance * hero, std::vector<std::string> words)
@ -233,7 +233,7 @@ void PlayerMessageProcessor::cheatGiveArtifacts(PlayerColor player, const CGHero
{
auto artID = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "artifact", word, false);
if(artID && VLC->arth->objects[*artID])
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[*artID], ArtifactPosition::FIRST_AVAILABLE);
gameHandler->giveHeroNewArtifact(hero, ArtifactID(*artID).toArtifact(), ArtifactPosition::FIRST_AVAILABLE);
}
}
else
@ -241,7 +241,7 @@ void PlayerMessageProcessor::cheatGiveArtifacts(PlayerColor player, const CGHero
for(int g = 7; g < VLC->arth->objects.size(); ++g) //including artifacts from mods
{
if(VLC->arth->objects[g]->canBePutAt(hero))
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[g], ArtifactPosition::FIRST_AVAILABLE);
gameHandler->giveHeroNewArtifact(hero, ArtifactID(g).toArtifact(), ArtifactPosition::FIRST_AVAILABLE);
}
}
}