1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Use toEntity/toXXX methods in Identifier instead VLC objects access

This commit is contained in:
Ivan Savenko
2023-11-02 18:45:46 +02:00
parent 8d5fa41a19
commit 184f5a72cc
29 changed files with 101 additions and 90 deletions

View File

@@ -1944,7 +1944,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
cancelText.appendTextID("core.genrltxt.596"); cancelText.appendTextID("core.genrltxt.596");
cancelText.replaceTextID(creature->getNameSingularTextID()); cancelText.replaceTextID(creature->getNameSingularTextID());
std::string costString = std::to_string(aid.toArtifact(CGI->artifacts())->getPrice()); std::string costString = std::to_string(aid.toEntity(CGI->artifacts())->getPrice());
title = std::make_shared<CLabel>(165, 28, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, titleString.toString()); title = std::make_shared<CLabel>(165, 28, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, titleString.toString());
costText = std::make_shared<CLabel>(165, 218, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->jktexts[43]); costText = std::make_shared<CLabel>(165, 218, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->jktexts[43]);

View File

@@ -257,7 +257,7 @@ DLL_LINKAGE void ArtifactUtils::insertScrrollSpellName(std::string & description
if(sid.getNum() >= 0) if(sid.getNum() >= 0)
{ {
if(nameStart != std::string::npos && nameEnd != std::string::npos) if(nameStart != std::string::npos && nameEnd != std::string::npos)
description = description.replace(nameStart, nameEnd - nameStart + 1, sid.toSpell(VLC->spells())->getNameTranslated()); description = description.replace(nameStart, nameEnd - nameStart + 1, sid.toEntity(VLC->spells())->getNameTranslated());
} }
} }

View File

@@ -125,15 +125,17 @@ SecondarySkill CHeroClass::chooseSecSkill(const std::set<SecondarySkill> & possi
{ {
int totalProb = 0; int totalProb = 0;
for(const auto & possible : possibles) for(const auto & possible : possibles)
{ if (secSkillProbability.count(possible) != 0)
totalProb += secSkillProbability[possible]; totalProb += secSkillProbability.at(possible);
}
if (totalProb != 0) // may trigger if set contains only banned skills (0 probability) if (totalProb != 0) // may trigger if set contains only banned skills (0 probability)
{ {
auto ran = rand.nextInt(totalProb - 1); auto ran = rand.nextInt(totalProb - 1);
for(const auto & possible : possibles) for(const auto & possible : possibles)
{ {
ran -= secSkillProbability[possible]; if (secSkillProbability.count(possible) != 0)
ran -= secSkillProbability.at(possible);
if(ran < 0) if(ran < 0)
{ {
return possible; return possible;
@@ -271,8 +273,6 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js
int probability = static_cast<int>(skillPair.second.Integer()); int probability = static_cast<int>(skillPair.second.Integer());
VLC->identifiers()->requestIdentifier(skillPair.second.meta, "skill", skillPair.first, [heroClass, probability](si32 skillID) VLC->identifiers()->requestIdentifier(skillPair.second.meta, "skill", skillPair.first, [heroClass, probability](si32 skillID)
{ {
if(heroClass->secSkillProbability.size() <= skillID)
heroClass->secSkillProbability.resize(skillID + 1, -1); // -1 = override with default later
heroClass->secSkillProbability[skillID] = probability; heroClass->secSkillProbability[skillID] = probability;
}); });
} }
@@ -369,11 +369,11 @@ void CHeroClassHandler::afterLoadFinalization()
auto chance = static_cast<float>(heroClass->defaultTavernChance * faction->town->defaultTavernChance); auto chance = static_cast<float>(heroClass->defaultTavernChance * faction->town->defaultTavernChance);
heroClass->selectionProbability[faction->getId()] = static_cast<int>(sqrt(chance) + 0.5); //FIXME: replace with std::round once MVS supports it heroClass->selectionProbability[faction->getId()] = static_cast<int>(sqrt(chance) + 0.5); //FIXME: replace with std::round once MVS supports it
} }
// set default probabilities for gaining secondary skills where not loaded previously // set default probabilities for gaining secondary skills where not loaded previously
heroClass->secSkillProbability.resize(VLC->skillh->size(), -1);
for(int skillID = 0; skillID < VLC->skillh->size(); skillID++) for(int skillID = 0; skillID < VLC->skillh->size(); skillID++)
{ {
if(heroClass->secSkillProbability[skillID] < 0) if(heroClass->secSkillProbability.count(skillID) == 0)
{ {
const CSkill * skill = (*VLC->skillh)[SecondarySkill(skillID)]; const CSkill * skill = (*VLC->skillh)[SecondarySkill(skillID)];
logMod->trace("%s: no probability for %s, using default", heroClass->identifier, skill->getJsonKey()); logMod->trace("%s: no probability for %s, using default", heroClass->identifier, skill->getJsonKey());

View File

@@ -157,7 +157,7 @@ public:
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
std::vector<int> primarySkillHighLevel;// same for high levels (> 10) std::vector<int> primarySkillHighLevel;// same for high levels (> 10)
std::vector<int> secSkillProbability; //probabilities of gaining secondary skills (out of 112), in id order std::map<SecondarySkill, int> secSkillProbability; //probabilities of gaining secondary skills (out of 112), in id order
std::map<FactionID, int> selectionProbability; //probability of selection in towns std::map<FactionID, int> selectionProbability; //probability of selection in towns
@@ -201,12 +201,6 @@ public:
h & imageBattleFemale; h & imageBattleFemale;
h & imageMapMale; h & imageMapMale;
h & imageMapFemale; h & imageMapFemale;
if(!h.saving)
{
for(int & i : secSkillProbability)
vstd::amax(i, 0);
}
} }
EAlignment getAlignment() const; EAlignment getAlignment() const;
}; };

View File

@@ -148,11 +148,11 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const
{ {
for (int j = 0; j < 3 ; j++) for (int j = 0; j < 3 ; j++)
out.push_back(VLC->arth->objects[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE)]); out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());
for (int j = 0; j < 3 ; j++) for (int j = 0; j < 3 ; j++)
out.push_back(VLC->arth->objects[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR)]); out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR).toArtifact());
out.push_back(VLC->arth->objects[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR)]); out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR).toArtifact());
} }
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level) void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)

View File

@@ -114,35 +114,35 @@ std::string MetaString::getLocalString(const std::pair<EMetaText, ui32> & txt) c
{ {
case EMetaText::ART_NAMES: case EMetaText::ART_NAMES:
{ {
const auto * art = ArtifactID(ser).toArtifact(VLC->artifacts()); const auto * art = ArtifactID(ser).toEntity(VLC->artifacts());
if(art) if(art)
return art->getNameTranslated(); return art->getNameTranslated();
return "#!#"; return "#!#";
} }
case EMetaText::ART_DESCR: case EMetaText::ART_DESCR:
{ {
const auto * art = ArtifactID(ser).toArtifact(VLC->artifacts()); const auto * art = ArtifactID(ser).toEntity(VLC->artifacts());
if(art) if(art)
return art->getDescriptionTranslated(); return art->getDescriptionTranslated();
return "#!#"; return "#!#";
} }
case EMetaText::ART_EVNTS: case EMetaText::ART_EVNTS:
{ {
const auto * art = ArtifactID(ser).toArtifact(VLC->artifacts()); const auto * art = ArtifactID(ser).toEntity(VLC->artifacts());
if(art) if(art)
return art->getEventTranslated(); return art->getEventTranslated();
return "#!#"; return "#!#";
} }
case EMetaText::CRE_PL_NAMES: case EMetaText::CRE_PL_NAMES:
{ {
const auto * cre = CreatureID(ser).toCreature(VLC->creatures()); const auto * cre = CreatureID(ser).toEntity(VLC->creatures());
if(cre) if(cre)
return cre->getNamePluralTranslated(); return cre->getNamePluralTranslated();
return "#!#"; return "#!#";
} }
case EMetaText::CRE_SING_NAMES: case EMetaText::CRE_SING_NAMES:
{ {
const auto * cre = CreatureID(ser).toCreature(VLC->creatures()); const auto * cre = CreatureID(ser).toEntity(VLC->creatures());
if(cre) if(cre)
return cre->getNameSingularTranslated(); return cre->getNameSingularTranslated();
return "#!#"; return "#!#";
@@ -157,7 +157,7 @@ std::string MetaString::getLocalString(const std::pair<EMetaText, ui32> & txt) c
} }
case EMetaText::SPELL_NAME: case EMetaText::SPELL_NAME:
{ {
const auto * spell = SpellID(ser).toSpell(VLC->spells()); const auto * spell = SpellID(ser).toEntity(VLC->spells());
if(spell) if(spell)
return spell->getNameTranslated(); return spell->getNameTranslated();
return "#!#"; return "#!#";

View File

@@ -100,13 +100,13 @@ std::string Bonus::Description(std::optional<si32> customValue) const
switch(source) switch(source)
{ {
case BonusSource::ARTIFACT: case BonusSource::ARTIFACT:
str << sid.as<ArtifactID>().toArtifact(VLC->artifacts())->getNameTranslated(); str << sid.as<ArtifactID>().toEntity(VLC->artifacts())->getNameTranslated();
break; break;
case BonusSource::SPELL_EFFECT: case BonusSource::SPELL_EFFECT:
str << sid.as<SpellID>().toSpell(VLC->spells())->getNameTranslated(); str << sid.as<SpellID>().toEntity(VLC->spells())->getNameTranslated();
break; break;
case BonusSource::CREATURE_ABILITY: case BonusSource::CREATURE_ABILITY:
str << sid.as<CreatureID>().toCreature(VLC->creatures())->getNamePluralTranslated(); str << sid.as<CreatureID>().toEntity(VLC->creatures())->getNamePluralTranslated();
break; break;
case BonusSource::SECONDARY_SKILL: case BonusSource::SECONDARY_SKILL:
str << VLC->skills()->getById(sid.as<SecondarySkill>())->getNameTranslated(); str << VLC->skills()->getById(sid.as<SecondarySkill>())->getNameTranslated();

View File

@@ -114,7 +114,7 @@ CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature & creature_, bool Inc
void CCreatureTypeLimiter::setCreature(const CreatureID & id) void CCreatureTypeLimiter::setCreature(const CreatureID & id)
{ {
creature = VLC->creh->objects[id]; creature = id.toCreature();
} }
std::string CCreatureTypeLimiter::toString() const std::string CCreatureTypeLimiter::toString() const

View File

@@ -28,6 +28,7 @@
#include "modding/IdentifierStorage.h" #include "modding/IdentifierStorage.h"
#include "modding/ModScope.h" #include "modding/ModScope.h"
#include "VCMI_Lib.h" #include "VCMI_Lib.h"
#include "CHeroHandler.h"
#include "CArtHandler.h"//todo: remove #include "CArtHandler.h"//todo: remove
#include "CCreatureHandler.h"//todo: remove #include "CCreatureHandler.h"//todo: remove
#include "spells/CSpellHandler.h" //todo: remove #include "spells/CSpellHandler.h" //todo: remove
@@ -191,10 +192,10 @@ std::string HeroTypeID::entityType()
const CArtifact * ArtifactIDBase::toArtifact() const const CArtifact * ArtifactIDBase::toArtifact() const
{ {
return dynamic_cast<const CArtifact*>(toArtifact(VLC->artifacts())); return dynamic_cast<const CArtifact*>(toEntity(VLC->artifacts()));
} }
const Artifact * ArtifactIDBase::toArtifact(const ArtifactService * service) const const Artifact * ArtifactIDBase::toEntity(const ArtifactService * service) const
{ {
return service->getByIndex(num); return service->getByIndex(num);
} }
@@ -237,7 +238,7 @@ const CCreature * CreatureIDBase::toCreature() const
return VLC->creh->objects.at(num); return VLC->creh->objects.at(num);
} }
const Creature * CreatureIDBase::toCreature(const CreatureService * creatures) const const Creature * CreatureIDBase::toEntity(const CreatureService * creatures) const
{ {
return creatures->getByIndex(num); return creatures->getByIndex(num);
} }
@@ -271,7 +272,17 @@ const CSpell * SpellIDBase::toSpell() const
return VLC->spellh->objects[num]; return VLC->spellh->objects[num];
} }
const spells::Spell * SpellIDBase::toSpell(const spells::Service * service) const const spells::Spell * SpellIDBase::toEntity(const spells::Service * service) const
{
return service->getByIndex(num);
}
const CHero * HeroTypeID::toHeroType() const
{
return dynamic_cast<const CHero*>(toEntity(VLC->heroTypes()));
}
const HeroType * HeroTypeID::toEntity(const HeroTypeService * service) const
{ {
return service->getByIndex(num); return service->getByIndex(num);
} }

View File

@@ -18,6 +18,9 @@ class Artifact;
class ArtifactService; class ArtifactService;
class Creature; class Creature;
class CreatureService; class CreatureService;
class HeroType;
class CHero;
class HeroTypeService;
namespace spells namespace spells
{ {
@@ -186,6 +189,9 @@ public:
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 CHero * toHeroType() const;
const HeroType * toEntity(const HeroTypeService * service) const;
DLL_LINKAGE static const HeroTypeID NONE; DLL_LINKAGE static const HeroTypeID NONE;
DLL_LINKAGE static const HeroTypeID RANDOM; DLL_LINKAGE static const HeroTypeID RANDOM;
@@ -675,7 +681,7 @@ public:
}; };
DLL_LINKAGE const CArtifact * toArtifact() const; DLL_LINKAGE const CArtifact * toArtifact() const;
DLL_LINKAGE const Artifact * toArtifact(const ArtifactService * service) const; DLL_LINKAGE const Artifact * toEntity(const ArtifactService * service) const;
}; };
class ArtifactID : public IdentifierWithEnum<ArtifactID, ArtifactIDBase> class ArtifactID : public IdentifierWithEnum<ArtifactID, ArtifactIDBase>
@@ -715,7 +721,7 @@ public:
}; };
DLL_LINKAGE const CCreature * toCreature() const; DLL_LINKAGE const CCreature * toCreature() const;
DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const; DLL_LINKAGE const Creature * toEntity(const CreatureService * creatures) const;
}; };
class DLL_LINKAGE CreatureID : public IdentifierWithEnum<CreatureID, CreatureIDBase> class DLL_LINKAGE CreatureID : public IdentifierWithEnum<CreatureID, CreatureIDBase>
@@ -833,7 +839,7 @@ public:
}; };
const CSpell * toSpell() const; //deprecated const CSpell * toSpell() const; //deprecated
const spells::Spell * toSpell(const spells::Service * service) const; const spells::Spell * toEntity(const spells::Service * service) const;
}; };
class DLL_LINKAGE SpellID : public IdentifierWithEnum<SpellID, SpellIDBase> class DLL_LINKAGE SpellID : public IdentifierWithEnum<SpellID, SpellIDBase>

View File

@@ -566,7 +566,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
} }
} }
auto handler = VLC->objtypeh->getHandlerFor(Obj::HERO, VLC->heroh->objects[heroTypeId]->heroClass->getIndex()); auto handler = VLC->objtypeh->getHandlerFor(Obj::HERO, heroTypeId.toHeroType()->heroClass->getIndex());
CGObjectInstance * obj = handler->create(handler->getTemplates().front()); CGObjectInstance * obj = handler->create(handler->getTemplates().front());
CGHeroInstance * hero = dynamic_cast<CGHeroInstance *>(obj); CGHeroInstance * hero = dynamic_cast<CGHeroInstance *>(obj);
@@ -630,7 +630,7 @@ void CGameState::initHeroes()
hero->initHero(getRandomGenerator()); hero->initHero(getRandomGenerator());
getPlayerState(hero->getOwner())->heroes.push_back(hero); getPlayerState(hero->getOwner())->heroes.push_back(hero);
map->allHeroes[hero->getHeroType()] = hero; map->allHeroes[hero->getHeroType().getNum()] = hero;
} }
// generate boats for all heroes on water // generate boats for all heroes on water
@@ -661,7 +661,7 @@ void CGameState::initHeroes()
{ {
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get()); auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
hero->initHero(getRandomGenerator()); hero->initHero(getRandomGenerator());
map->allHeroes[hero->getHeroType()] = hero; map->allHeroes[hero->getHeroType().getNum()] = hero;
} }
} }
@@ -674,7 +674,7 @@ void CGameState::initHeroes()
heroesPool->addHeroToPool(ph); heroesPool->addHeroToPool(ph);
heroesToCreate.erase(ph->type->getId()); heroesToCreate.erase(ph->type->getId());
map->allHeroes[ph->getHeroType()] = ph; map->allHeroes[ph->getHeroType().getNum()] = ph;
} }
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
@@ -760,7 +760,7 @@ void CGameState::initStartingBonus()
logGlobal->error("Cannot give starting artifact - no heroes!"); logGlobal->error("Cannot give starting artifact - no heroes!");
break; break;
} }
const Artifact * toGive = VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toArtifact(VLC->artifacts()); const Artifact * toGive = VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toEntity(VLC->artifacts());
CGHeroInstance *hero = elem.second.heroes[0]; CGHeroInstance *hero = elem.second.heroes[0];
if(!giveHeroArtifact(hero, toGive->getId())) if(!giveHeroArtifact(hero, toGive->getId()))

View File

@@ -285,10 +285,9 @@ void CObjectClassesHandler::loadObject(std::string scope, std::string name, cons
VLC->identifiersHandler->registerObject(scope, "object", name, object->id); VLC->identifiersHandler->registerObject(scope, "object", name, object->id);
} }
void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, si32 ID, si32 subID) void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, MapObjectID ID, MapObjectSubID subID)
{ {
config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not NULL config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not NULL
assert(ID < objects.size());
assert(objects[ID]); assert(objects[ID]);
if ( subID >= objects[ID]->objects.size()) if ( subID >= objects[ID]->objects.size())
@@ -298,9 +297,8 @@ void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNo
loadSubObject(config.meta, identifier, config, objects[ID], subID); loadSubObject(config.meta, identifier, config, objects[ID], subID);
} }
void CObjectClassesHandler::removeSubObject(si32 ID, si32 subID) void CObjectClassesHandler::removeSubObject(MapObjectID ID, MapObjectSubID subID)
{ {
assert(ID < objects.size());
assert(objects[ID]); assert(objects[ID]);
assert(subID < objects[ID]->objects.size()); assert(subID < objects[ID]->objects.size());
objects[ID]->objects[subID] = nullptr; objects[ID]->objects[subID] = nullptr;
@@ -311,7 +309,7 @@ std::vector<bool> CObjectClassesHandler::getDefaultAllowed() const
return std::vector<bool>(); //TODO? return std::vector<bool>(); //TODO?
} }
TObjectTypeHandler CObjectClassesHandler::getHandlerFor(si32 type, si32 subtype) const TObjectTypeHandler CObjectClassesHandler::getHandlerFor(MapObjectID type, MapObjectSubID subtype) const
{ {
try try
{ {
@@ -352,9 +350,9 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(CompoundMapObjectID comp
return getHandlerFor(compoundIdentifier.primaryID, compoundIdentifier.secondaryID); return getHandlerFor(compoundIdentifier.primaryID, compoundIdentifier.secondaryID);
} }
std::set<si32> CObjectClassesHandler::knownObjects() const std::set<MapObjectID> CObjectClassesHandler::knownObjects() const
{ {
std::set<si32> ret; std::set<MapObjectID> ret;
for(auto * entry : objects) for(auto * entry : objects)
if (entry) if (entry)
@@ -363,9 +361,9 @@ std::set<si32> CObjectClassesHandler::knownObjects() const
return ret; return ret;
} }
std::set<si32> CObjectClassesHandler::knownSubObjects(si32 primaryID) const std::set<MapObjectSubID> CObjectClassesHandler::knownSubObjects(MapObjectID primaryID) const
{ {
std::set<si32> ret; std::set<MapObjectSubID> ret;
if (!objects.at(primaryID)) if (!objects.at(primaryID))
{ {
@@ -461,7 +459,7 @@ void CObjectClassesHandler::generateExtraMonolithsForRMG()
} }
} }
std::string CObjectClassesHandler::getObjectName(si32 type, si32 subtype) const std::string CObjectClassesHandler::getObjectName(MapObjectID type, MapObjectSubID subtype) const
{ {
const auto handler = getHandlerFor(type, subtype); const auto handler = getHandlerFor(type, subtype);
if (handler && handler->hasNameTextID()) if (handler && handler->hasNameTextID())
@@ -470,7 +468,7 @@ std::string CObjectClassesHandler::getObjectName(si32 type, si32 subtype) const
return objects[type]->getNameTranslated(); return objects[type]->getNameTranslated();
} }
SObjectSounds CObjectClassesHandler::getObjectSounds(si32 type, si32 subtype) const SObjectSounds CObjectClassesHandler::getObjectSounds(MapObjectID type, MapObjectSubID subtype) const
{ {
// TODO: these objects may have subID's that does not have associated handler: // TODO: these objects may have subID's that does not have associated handler:
// Prison: uses hero type as subID // Prison: uses hero type as subID
@@ -479,19 +477,18 @@ SObjectSounds CObjectClassesHandler::getObjectSounds(si32 type, si32 subtype) co
if(type == Obj::PRISON || type == Obj::HERO || type == Obj::SPELL_SCROLL) if(type == Obj::PRISON || type == Obj::HERO || type == Obj::SPELL_SCROLL)
subtype = 0; subtype = 0;
assert(type < objects.size());
assert(objects[type]); assert(objects[type]);
assert(subtype < objects[type]->objects.size()); assert(subtype < objects[type]->objects.size());
return getHandlerFor(type, subtype)->getSounds(); return getHandlerFor(type, subtype)->getSounds();
} }
std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const std::string CObjectClassesHandler::getObjectHandlerName(MapObjectID type) const
{ {
return objects.at(type)->handlerName; return objects.at(type)->handlerName;
} }
std::string CObjectClassesHandler::getJsonKey(si32 type) const std::string CObjectClassesHandler::getJsonKey(MapObjectID type) const
{ {
return objects.at(type)->getJsonKey(); return objects.at(type)->getJsonKey();
} }

View File

@@ -105,8 +105,8 @@ public:
void loadObject(std::string scope, std::string name, const JsonNode & data) override; void loadObject(std::string scope, std::string name, const JsonNode & data) override;
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override; void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
void loadSubObject(const std::string & identifier, JsonNode config, si32 ID, si32 subID); void loadSubObject(const std::string & identifier, JsonNode config, MapObjectID ID, MapObjectSubID subID);
void removeSubObject(si32 ID, si32 subID); void removeSubObject(MapObjectID ID, MapObjectSubID subID);
void beforeValidate(JsonNode & object) override; void beforeValidate(JsonNode & object) override;
void afterLoadFinalization() override; void afterLoadFinalization() override;
@@ -114,22 +114,22 @@ public:
std::vector<bool> getDefaultAllowed() const override; std::vector<bool> getDefaultAllowed() const override;
/// Queries to detect loaded objects /// Queries to detect loaded objects
std::set<si32> knownObjects() const; std::set<MapObjectID> knownObjects() const;
std::set<si32> knownSubObjects(si32 primaryID) const; std::set<MapObjectSubID> knownSubObjects(MapObjectID primaryID) const;
/// returns handler for specified object (ID-based). ObjectHandler keeps ownership /// returns handler for specified object (ID-based). ObjectHandler keeps ownership
TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const; TObjectTypeHandler getHandlerFor(MapObjectID type, MapObjectSubID subtype) const;
TObjectTypeHandler getHandlerFor(const std::string & scope, const std::string & type, const std::string & subtype) const; TObjectTypeHandler getHandlerFor(const std::string & scope, const std::string & type, const std::string & subtype) const;
TObjectTypeHandler getHandlerFor(CompoundMapObjectID compoundIdentifier) const; TObjectTypeHandler getHandlerFor(CompoundMapObjectID compoundIdentifier) const;
std::string getObjectName(si32 type, si32 subtype) const; std::string getObjectName(MapObjectID type, MapObjectSubID subtype) const;
SObjectSounds getObjectSounds(si32 type, si32 subtype) const; SObjectSounds getObjectSounds(MapObjectID type, MapObjectSubID subtype) const;
/// Returns handler string describing the handler (for use in client) /// Returns handler string describing the handler (for use in client)
std::string getObjectHandlerName(si32 type) const; std::string getObjectHandlerName(MapObjectID type) const;
std::string getJsonKey(si32 type) const; std::string getJsonKey(MapObjectID type) const;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {

View File

@@ -73,7 +73,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
for(const auto & slot : Slots()) for(const auto & slot : Slots())
{ {
const CStackInstance * inst = slot.second; const CStackInstance * inst = slot.second;
const CCreature * creature = VLC->creh->objects[inst->getCreatureID()]; const auto * creature = inst->getCreatureID().toEntity(VLC->creatures());
factions.insert(creature->getFaction()); factions.insert(creature->getFaction());
// Check for undead flag instead of faction (undead mummies are neutral) // Check for undead flag instead of faction (undead mummies are neutral)

View File

@@ -280,7 +280,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
iw.components.emplace_back(ComponentType::ARTIFACT, elem); iw.components.emplace_back(ComponentType::ARTIFACT, elem);
loot.appendRawString("%s"); loot.appendRawString("%s");
loot.replaceLocalString(EMetaText::ART_NAMES, elem); loot.replaceLocalString(EMetaText::ART_NAMES, elem);
cb->giveHeroNewArtifact(hero, VLC->arth->objects[elem], ArtifactPosition::FIRST_AVAILABLE); cb->giveHeroNewArtifact(hero, elem.toArtifact(), ArtifactPosition::FIRST_AVAILABLE);
} }
//display loot //display loot
if (!iw.components.empty()) if (!iw.components.empty())
@@ -314,7 +314,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
} }
for(const SpellID & spellId : bc->spells) for(const SpellID & spellId : bc->spells)
{ {
const auto * spell = spellId.toSpell(VLC->spells()); const auto * spell = spellId.toEntity(VLC->spells());
iw.text.appendLocalString(EMetaText::SPELL_NAME, spellId); iw.text.appendLocalString(EMetaText::SPELL_NAME, spellId);
if(spell->getLevel() <= hero->maxSpellLevel()) if(spell->getLevel() <= hero->maxSpellLevel())
{ {

View File

@@ -427,7 +427,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
if(!upgrades.empty()) if(!upgrades.empty())
{ {
auto it = RandomGeneratorUtil::nextItem(upgrades, CRandomGenerator::getDefault()); auto it = RandomGeneratorUtil::nextItem(upgrades, CRandomGenerator::getDefault());
cb->changeStackType(StackLocation(this, slotID), VLC->creh->objects[*it]); cb->changeStackType(StackLocation(this, slotID), it->toCreature());
} }
} }
} }
@@ -572,7 +572,7 @@ void CGCreature::giveReward(const CGHeroInstance * h) const
if(gainedArtifact != ArtifactID::NONE) if(gainedArtifact != ArtifactID::NONE)
{ {
cb->giveHeroNewArtifact(h, VLC->arth->objects[gainedArtifact], ArtifactPosition::FIRST_AVAILABLE); cb->giveHeroNewArtifact(h, gainedArtifact.toArtifact(), ArtifactPosition::FIRST_AVAILABLE);
iw.components.emplace_back(ComponentType::ARTIFACT, gainedArtifact); iw.components.emplace_back(ComponentType::ARTIFACT, gainedArtifact);
} }

View File

@@ -142,7 +142,7 @@ void CGDwelling::pickRandomObject(CRandomGenerator & rand)
{ {
const auto * handler = dynamic_cast<const DwellingInstanceConstructor *>(VLC->objtypeh->getHandlerFor(primaryID, entry).get()); const auto * handler = dynamic_cast<const DwellingInstanceConstructor *>(VLC->objtypeh->getHandlerFor(primaryID, entry).get());
if (handler->producesCreature(VLC->creh->objects[cid])) if (handler->producesCreature(cid.toCreature()))
return MapObjectSubID(entry); return MapObjectSubID(entry);
} }
return MapObjectSubID(); return MapObjectSubID();
@@ -319,7 +319,7 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const
else else
creaturesAccumulate = VLC->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL); creaturesAccumulate = VLC->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL);
CCreature *cre = VLC->creh->objects[creatures[i].second[0]]; const CCreature * cre =creatures[i].second[0].toCreature();
TQuantity amount = cre->getGrowth() * (1 + cre->valOfBonuses(BonusType::CREATURE_GROWTH_PERCENT)/100) + cre->valOfBonuses(BonusType::CREATURE_GROWTH); TQuantity amount = cre->getGrowth() * (1 + cre->valOfBonuses(BonusType::CREATURE_GROWTH_PERCENT)/100) + cre->valOfBonuses(BonusType::CREATURE_GROWTH);
if (creaturesAccumulate && ID != Obj::REFUGEE_CAMP) //camp should not try to accumulate different kinds of creatures if (creaturesAccumulate && ID != Obj::REFUGEE_CAMP) //camp should not try to accumulate different kinds of creatures
sac.creatures[i].first += amount; sac.creatures[i].first += amount;
@@ -355,7 +355,7 @@ void CGDwelling::updateGuards() const
{ {
for (auto creatureEntry : creatures) for (auto creatureEntry : creatures)
{ {
const CCreature * crea = VLC->creh->objects[creatureEntry.second.at(0)]; const CCreature * crea = creatureEntry.second.at(0).toCreature();
SlotID slot = getSlotFor(crea->getId()); SlotID slot = getSlotFor(crea->getId());
if (hasStackAtSlot(slot)) //stack already exists, overwrite it if (hasStackAtSlot(slot)) //stack already exists, overwrite it

View File

@@ -218,7 +218,10 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
if (getSecSkillLevel(which) > 0) if (getSecSkillLevel(which) > 0)
return false; return false;
if (type->heroClass->secSkillProbability[which] == 0) if (type->heroClass->secSkillProbability.count(which) == 0)
return false;
if (type->heroClass->secSkillProbability.at(which) == 0)
return false; return false;
return true; return true;

View File

@@ -917,7 +917,7 @@ const CTown * CGTownInstance::getTown() const
{ {
if(nullptr == town) if(nullptr == town)
{ {
return (*VLC->townh)[subID]->town; return (*VLC->townh)[getFaction()]->town;
} }
else else
return town; return town;

View File

@@ -775,7 +775,7 @@ std::string CGKeys::getHoverText(PlayerColor player) const
std::string CGKeys::getObjectName() const std::string CGKeys::getObjectName() const
{ {
return VLC->generaltexth->tentColors[subID] + " " + CGObjectInstance::getObjectName(); return VLC->generaltexth->tentColors[subID.getNum()] + " " + CGObjectInstance::getObjectName();
} }
bool CGKeymasterTent::wasVisited (PlayerColor player) const bool CGKeymasterTent::wasVisited (PlayerColor player) const
@@ -810,7 +810,7 @@ void CGBorderGuard::getRolloverText(MetaString &text, bool onHover) const
{ {
if (!onHover) if (!onHover)
{ {
text.appendRawString(VLC->generaltexth->tentColors[subID]); text.appendRawString(VLC->generaltexth->tentColors[subID.getNum()]);
text.appendRawString(" "); text.appendRawString(" ");
text.appendRawString(VLC->objtypeh->getObjectName(Obj::KEYMASTER, subID)); text.appendRawString(VLC->objtypeh->getObjectName(Obj::KEYMASTER, subID));
} }

View File

@@ -147,7 +147,7 @@ std::string CGMine::getHoverText(PlayerColor player) const
std::string hoverName = CArmedInstance::getHoverText(player); std::string hoverName = CArmedInstance::getHoverText(player);
if (tempOwner != PlayerColor::NEUTRAL) if (tempOwner != PlayerColor::NEUTRAL)
hoverName += "\n(" + VLC->generaltexth->restypes[producedResource] + ")"; hoverName += "\n(" + VLC->generaltexth->restypes[producedResource.getNum()] + ")";
if(stacksCount()) if(stacksCount())
{ {
@@ -252,7 +252,7 @@ GameResID CGResource::resourceID() const
std::string CGResource::getHoverText(PlayerColor player) const std::string CGResource::getHoverText(PlayerColor player) const
{ {
return VLC->generaltexth->restypes[resourceID()]; return VLC->generaltexth->restypes[resourceID().getNum()];
} }
void CGResource::pickRandomObject(CRandomGenerator & rand) void CGResource::pickRandomObject(CRandomGenerator & rand)
@@ -760,7 +760,7 @@ void CGArtifact::initObj(CRandomGenerator & rand)
storedArtifact = a; storedArtifact = a;
} }
if(!storedArtifact->artType) if(!storedArtifact->artType)
storedArtifact->setType(VLC->arth->objects[getArtifact()]); storedArtifact->setType(VLC->arth->objects[getArtifact().getNum()]);
} }
if(ID == Obj::SPELL_SCROLL) if(ID == Obj::SPELL_SCROLL)
subID = 1; subID = 1;

View File

@@ -926,7 +926,7 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
if(artifactID == ArtifactID::NONE) if(artifactID == ArtifactID::NONE)
return false; return false;
const Artifact * art = artifactID.toArtifact(VLC->artifacts()); const Artifact * art = artifactID.toEntity(VLC->artifacts());
if(!art) if(!art)
{ {

View File

@@ -171,10 +171,10 @@ namespace TriggeredEventsDetail
case EMetaclass::OBJECT: case EMetaclass::OBJECT:
{ {
//TODO //TODO
std::set<si32> subtypes = VLC->objtypeh->knownSubObjects(type); auto subtypes = VLC->objtypeh->knownSubObjects(type);
if(!subtypes.empty()) if(!subtypes.empty())
{ {
si32 subtype = *subtypes.begin(); auto subtype = *subtypes.begin();
auto handler = VLC->objtypeh->getHandlerFor(type, subtype); auto handler = VLC->objtypeh->getHandlerFor(type, subtype);
identifier = handler->getTypeName(); identifier = handler->getTypeName();
} }

View File

@@ -128,7 +128,7 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
for(const auto & spell : canLearnSpells) for(const auto & spell : canLearnSpells)
{ {
if (!hero->canLearnSpell(spell.toSpell(VLC->spells()), true)) if (!hero->canLearnSpell(spell.toEntity(VLC->spells()), true))
return false; return false;
} }

View File

@@ -49,7 +49,7 @@ void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const Effe
break; break;
} }
const auto *creatureType = creature.toCreature(m->creatures()); const auto *creatureType = creature.toEntity(m->creatures());
int32_t deadCount = targetStack->unitBaseAmount(); int32_t deadCount = targetStack->unitBaseAmount();
int32_t deadTotalHealth = targetStack->getTotalHealth(); int32_t deadTotalHealth = targetStack->getTotalHealth();
@@ -111,7 +111,7 @@ bool DemonSummon::isValidTarget(const Mechanics * m, const battle::Unit * unit)
if (unit->isGhost()) if (unit->isGhost())
return false; return false;
const auto *creatureType = creature.toCreature(m->creatures()); const auto *creatureType = creature.toEntity(m->creatures());
if (unit->getTotalHealth() < creatureType->getMaxHealth()) if (unit->getTotalHealth() < creatureType->getMaxHealth())
return false; return false;

View File

@@ -93,7 +93,7 @@ std::shared_ptr<const BonusList> Dispel::getBonuses(const Mechanics * m, const b
{ {
if(bonus->source == BonusSource::SPELL_EFFECT) if(bonus->source == BonusSource::SPELL_EFFECT)
{ {
const Spell * sourceSpell = bonus->sid.as<SpellID>().toSpell(m->spells()); const Spell * sourceSpell = bonus->sid.as<SpellID>().toEntity(m->spells());
if(!sourceSpell) if(!sourceSpell)
return false;//error return false;//error

View File

@@ -107,7 +107,7 @@ void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTar
if(summonByHealth) if(summonByHealth)
{ {
const auto *creatureType = creature.toCreature(m->creatures()); const auto *creatureType = creature.toEntity(m->creatures());
auto creatureMaxHealth = creatureType->getMaxHealth(); auto creatureMaxHealth = creatureType->getMaxHealth();
amount = static_cast<int32_t>(valueWithBonus / creatureMaxHealth); amount = static_cast<int32_t>(valueWithBonus / creatureMaxHealth);
} }

View File

@@ -143,7 +143,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
if(ins->storedArtifact) if(ins->storedArtifact)
{ {
if(!map->allowedSpells[ins->storedArtifact->getScrollSpellID()]) if(!map->allowedSpells[ins->storedArtifact->getScrollSpellID()])
issues.emplace_back(QString(tr("Spell scroll %1 is prohibited by map settings")).arg(ins->storedArtifact->getScrollSpellID().toSpell(VLC->spells())->getNameTranslated().c_str()), false); issues.emplace_back(QString(tr("Spell scroll %1 is prohibited by map settings")).arg(ins->storedArtifact->getScrollSpellID().toEntity(VLC->spells())->getNameTranslated().c_str()), false);
} }
else else
issues.emplace_back(QString(tr("Spell scroll %1 doesn't have instance assigned and must be removed")).arg(ins->instanceName.c_str()), true); issues.emplace_back(QString(tr("Spell scroll %1 doesn't have instance assigned and must be removed")).arg(ins->instanceName.c_str()), true);

View File

@@ -323,7 +323,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE); double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE);
for(auto & spellId : battle.getBattle()->getUsedSpells(battle.otherSide(battleResult->winner))) for(auto & spellId : battle.getBattle()->getUsedSpells(battle.otherSide(battleResult->winner)))
{ {
auto spell = spellId.toSpell(VLC->spells()); auto spell = spellId.toEntity(VLC->spells());
if(spell && spell->getLevel() <= eagleEyeLevel && !finishingBattle->winnerHero->spellbookContainsSpell(spell->getId()) && gameHandler->getRandomGenerator().nextInt(99) < eagleEyeChance) if(spell && spell->getLevel() <= eagleEyeLevel && !finishingBattle->winnerHero->spellbookContainsSpell(spell->getId()) && gameHandler->getRandomGenerator().nextInt(99) < eagleEyeChance)
cs.spells.insert(spell->getId()); cs.spells.insert(spell->getId());
} }