mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-14 02:33:51 +02:00
Merge pull request #3144 from IvanSavenko/remove_identifier_implicit_int_conversion
Remove (some of) implicit conversions of Identifier to integer
This commit is contained in:
commit
8dc5837395
@ -161,7 +161,7 @@ void CBonusSelection::createBonusesIcons()
|
||||
break;
|
||||
case CampaignBonusType::BUILDING:
|
||||
{
|
||||
int faction = -1;
|
||||
FactionID faction;
|
||||
for(auto & elem : CSH->si->playerInfos)
|
||||
{
|
||||
if(elem.second.isControlledByHuman())
|
||||
|
@ -1944,7 +1944,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
|
||||
cancelText.appendTextID("core.genrltxt.596");
|
||||
cancelText.replaceTextID(creature->getNameSingularTextID());
|
||||
|
||||
std::string costString = std::to_string(aid.toArtifact(CGI->artifacts())->getPrice());
|
||||
std::string costString = std::to_string(aid.toEntity(CGI)->getPrice());
|
||||
|
||||
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]);
|
||||
|
@ -257,7 +257,7 @@ DLL_LINKAGE void ArtifactUtils::insertScrrollSpellName(std::string & description
|
||||
if(sid.getNum() >= 0)
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ bool CArtifact::isBig() const
|
||||
|
||||
bool CArtifact::isTradable() const
|
||||
{
|
||||
switch(id)
|
||||
switch(id.toEnum())
|
||||
{
|
||||
case ArtifactID::SPELLBOOK:
|
||||
case ArtifactID::GRAIL:
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
BuildingID CBuildingHandler::campToERMU(int camp, int townType, const std::set<BuildingID> & builtBuildings)
|
||||
BuildingID CBuildingHandler::campToERMU(int camp, FactionID townType, const std::set<BuildingID> & builtBuildings)
|
||||
{
|
||||
static const std::vector<BuildingID> campToERMU =
|
||||
{
|
||||
@ -47,13 +47,13 @@ BuildingID CBuildingHandler::campToERMU(int camp, int townType, const std::set<B
|
||||
|
||||
if (i < 5) // last two levels don't have reserved horde ID. Yet another H3C weirdeness
|
||||
{
|
||||
if (vstd::contains(hordeLvlsPerTType[townType], i))
|
||||
if (vstd::contains(hordeLvlsPerTType[townType.getNum()], i))
|
||||
{
|
||||
if (camp == curPos)
|
||||
{
|
||||
if (hordeLvlsPerTType[townType][0] == i)
|
||||
if (hordeLvlsPerTType[townType.getNum()][0] == i)
|
||||
{
|
||||
BuildingID dwellingID(BuildingID::DWELL_UP_FIRST + hordeLvlsPerTType[townType][0]);
|
||||
BuildingID dwellingID(BuildingID::DWELL_UP_FIRST + hordeLvlsPerTType[townType.getNum()][0]);
|
||||
|
||||
if(vstd::contains(builtBuildings, dwellingID)) //if upgraded dwelling is built
|
||||
return BuildingID::HORDE_1_UPGR;
|
||||
@ -62,9 +62,9 @@ BuildingID CBuildingHandler::campToERMU(int camp, int townType, const std::set<B
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hordeLvlsPerTType[townType].size() > 1)
|
||||
if(hordeLvlsPerTType[townType.getNum()].size() > 1)
|
||||
{
|
||||
BuildingID dwellingID(BuildingID::DWELL_UP_FIRST + hordeLvlsPerTType[townType][1]);
|
||||
BuildingID dwellingID(BuildingID::DWELL_UP_FIRST + hordeLvlsPerTType[townType.getNum()][1]);
|
||||
|
||||
if(vstd::contains(builtBuildings, dwellingID)) //if upgraded dwelling is built
|
||||
return BuildingID::HORDE_2_UPGR;
|
||||
|
@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class DLL_LINKAGE CBuildingHandler
|
||||
{
|
||||
public:
|
||||
static BuildingID campToERMU(int camp, int townType, const std::set<BuildingID> & builtBuildings);
|
||||
static BuildingID campToERMU(int camp, FactionID townType, const std::set<BuildingID> & builtBuildings);
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -263,7 +263,7 @@ bool CCreature::isDoubleWide() const
|
||||
*/
|
||||
bool CCreature::isGood () const
|
||||
{
|
||||
return VLC->factions()->getByIndex(faction)->getAlignment() == EAlignment::GOOD;
|
||||
return VLC->factions()->getById(faction)->getAlignment() == EAlignment::GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -272,7 +272,7 @@ bool CCreature::isGood () const
|
||||
*/
|
||||
bool CCreature::isEvil () const
|
||||
{
|
||||
return VLC->factions()->getByIndex(faction)->getAlignment() == EAlignment::EVIL;
|
||||
return VLC->factions()->getById(faction)->getAlignment() == EAlignment::EVIL;
|
||||
}
|
||||
|
||||
si32 CCreature::maxAmount(const TResources &res) const //how many creatures can be bought
|
||||
@ -388,7 +388,7 @@ void CCreature::serializeJson(JsonSerializeFormat & handler)
|
||||
if(handler.updating)
|
||||
{
|
||||
cost.serializeJson(handler, "cost");
|
||||
handler.serializeInt("faction", faction);//TODO: unify with deferred resolve
|
||||
handler.serializeId("faction", faction);
|
||||
}
|
||||
|
||||
handler.serializeInt("level", level);
|
||||
@ -1350,34 +1350,23 @@ CCreatureHandler::~CCreatureHandler()
|
||||
|
||||
CreatureID CCreatureHandler::pickRandomMonster(CRandomGenerator & rand, int tier) const
|
||||
{
|
||||
int r = 0;
|
||||
if(tier == -1) //pick any allowed creature
|
||||
std::vector<CreatureID> allowed;
|
||||
for(const auto & creature : objects)
|
||||
{
|
||||
do
|
||||
{
|
||||
r = (*RandomGeneratorUtil::nextItem(objects, rand))->getId();
|
||||
} while (objects[r] && objects[r]->special); // find first "not special" creature
|
||||
if(creature->special)
|
||||
continue;
|
||||
|
||||
if (creature->level == tier || tier == -1)
|
||||
allowed.push_back(creature->getId());
|
||||
}
|
||||
else
|
||||
|
||||
if(allowed.empty())
|
||||
{
|
||||
assert(vstd::iswithin(tier, 1, 7));
|
||||
std::vector<CreatureID> allowed;
|
||||
for(const auto & creature : objects)
|
||||
{
|
||||
if(!creature->special && creature->level == tier)
|
||||
allowed.push_back(creature->getId());
|
||||
}
|
||||
|
||||
if(allowed.empty())
|
||||
{
|
||||
logGlobal->warn("Cannot pick a random creature of tier %d!", tier);
|
||||
return CreatureID::NONE;
|
||||
}
|
||||
|
||||
return *RandomGeneratorUtil::nextItem(allowed, rand);
|
||||
logGlobal->warn("Cannot pick a random creature of tier %d!", tier);
|
||||
return CreatureID::NONE;
|
||||
}
|
||||
assert (r >= 0); //should always be, but it crashed
|
||||
return CreatureID(r);
|
||||
|
||||
return *RandomGeneratorUtil::nextItem(allowed, rand);
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,15 +125,17 @@ SecondarySkill CHeroClass::chooseSecSkill(const std::set<SecondarySkill> & possi
|
||||
{
|
||||
int totalProb = 0;
|
||||
for(const auto & possible : possibles)
|
||||
{
|
||||
totalProb += secSkillProbability[possible];
|
||||
}
|
||||
if (secSkillProbability.count(possible) != 0)
|
||||
totalProb += secSkillProbability.at(possible);
|
||||
|
||||
if (totalProb != 0) // may trigger if set contains only banned skills (0 probability)
|
||||
{
|
||||
auto ran = rand.nextInt(totalProb - 1);
|
||||
for(const auto & possible : possibles)
|
||||
{
|
||||
ran -= secSkillProbability[possible];
|
||||
if (secSkillProbability.count(possible) != 0)
|
||||
ran -= secSkillProbability.at(possible);
|
||||
|
||||
if(ran < 0)
|
||||
{
|
||||
return possible;
|
||||
@ -151,7 +153,7 @@ bool CHeroClass::isMagicHero() const
|
||||
|
||||
EAlignment CHeroClass::getAlignment() const
|
||||
{
|
||||
return VLC->factions()->getByIndex(faction)->getAlignment();
|
||||
return VLC->factions()->getById(faction)->getAlignment();
|
||||
}
|
||||
|
||||
int32_t CHeroClass::getIndex() const
|
||||
@ -209,7 +211,7 @@ CHeroClass::CHeroClass():
|
||||
|
||||
void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill pSkill) const
|
||||
{
|
||||
const auto & skillName = NPrimarySkill::names[static_cast<int>(pSkill)];
|
||||
const auto & skillName = NPrimarySkill::names[pSkill.getNum()];
|
||||
auto currentPrimarySkillValue = static_cast<int>(node["primarySkills"][skillName].Integer());
|
||||
//minimal value is 0 for attack and defense and 1 for spell power and knowledge
|
||||
auto primarySkillLegalMinimum = (pSkill == PrimarySkill::ATTACK || pSkill == PrimarySkill::DEFENSE) ? 0 : 1;
|
||||
@ -271,8 +273,6 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js
|
||||
int probability = static_cast<int>(skillPair.second.Integer());
|
||||
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;
|
||||
});
|
||||
}
|
||||
@ -369,11 +369,11 @@ void CHeroClassHandler::afterLoadFinalization()
|
||||
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
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
if(heroClass->secSkillProbability[skillID] < 0)
|
||||
if(heroClass->secSkillProbability.count(skillID) == 0)
|
||||
{
|
||||
const CSkill * skill = (*VLC->skillh)[SecondarySkill(skillID)];
|
||||
logMod->trace("%s: no probability for %s, using default", heroClass->identifier, skill->getJsonKey());
|
||||
|
@ -157,7 +157,7 @@ public:
|
||||
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> 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
|
||||
|
||||
@ -201,12 +201,6 @@ public:
|
||||
h & imageBattleFemale;
|
||||
h & imageMapMale;
|
||||
h & imageMapFemale;
|
||||
|
||||
if(!h.saving)
|
||||
{
|
||||
for(int & i : secSkillProbability)
|
||||
vstd::amax(i, 0);
|
||||
}
|
||||
}
|
||||
EAlignment getAlignment() const;
|
||||
};
|
||||
|
@ -120,7 +120,7 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInf
|
||||
|
||||
DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill & skill)
|
||||
{
|
||||
out << "Skill(" << (int)skill.id << "," << skill.identifier << "): [";
|
||||
out << "Skill(" << skill.id.getNum() << "," << skill.identifier << "): [";
|
||||
for(int i=0; i < skill.levels.size(); i++)
|
||||
out << (i ? "," : "") << skill.levels[i];
|
||||
return out << "]";
|
||||
@ -233,7 +233,7 @@ CSkill * CSkillHandler::loadFromJson(const std::string & scope, const JsonNode &
|
||||
skillAtLevel.iconMedium = levelNode["images"]["medium"].String();
|
||||
skillAtLevel.iconLarge = levelNode["images"]["large"].String();
|
||||
}
|
||||
logMod->debug("loaded secondary skill %s(%d)", identifier, (int)skill->id);
|
||||
logMod->debug("loaded secondary skill %s(%d)", identifier, skill->id.getNum());
|
||||
|
||||
return skill;
|
||||
}
|
||||
@ -262,23 +262,4 @@ std::vector<bool> CSkillHandler::getDefaultAllowed() const
|
||||
return allowedSkills;
|
||||
}
|
||||
|
||||
si32 CSkillHandler::decodeSkill(const std::string & identifier)
|
||||
{
|
||||
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "skill", identifier);
|
||||
if(rawId)
|
||||
return rawId.value();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string CSkillHandler::encodeSkill(const si32 index)
|
||||
{
|
||||
return (*VLC->skillh)[SecondarySkill(index)]->identifier;
|
||||
}
|
||||
|
||||
std::string CSkillHandler::encodeSkillWithType(const si32 index)
|
||||
{
|
||||
return ModUtility::makeFullIdentifier("", "skill", encodeSkill(index));
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -111,11 +111,6 @@ public:
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
///json serialization helpers
|
||||
static si32 decodeSkill(const std::string & identifier);
|
||||
static std::string encodeSkill(const si32 index);
|
||||
static std::string encodeSkillWithType(const si32 index);
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & objects;
|
||||
|
@ -686,7 +686,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
|
||||
//MODS COMPATIBILITY FOR 0.96
|
||||
if(!ret->produce.nonZero())
|
||||
{
|
||||
switch (ret->bid) {
|
||||
switch (ret->bid.toEnum()) {
|
||||
break; case BuildingID::VILLAGE_HALL: ret->produce[EGameResID::GOLD] = 500;
|
||||
break; case BuildingID::TOWN_HALL : ret->produce[EGameResID::GOLD] = 1000;
|
||||
break; case BuildingID::CITY_HALL : ret->produce[EGameResID::GOLD] = 2000;
|
||||
|
@ -148,11 +148,11 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
|
||||
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const
|
||||
{
|
||||
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++)
|
||||
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)
|
||||
|
@ -113,7 +113,7 @@ namespace JsonRandom
|
||||
if (value.empty() || value[0] != '@')
|
||||
return PrimarySkill(*VLC->identifiers()->getIdentifier(modScope, "primarySkill", value));
|
||||
else
|
||||
return PrimarySkill(loadVariable("primarySkill", value, variables, static_cast<int>(PrimarySkill::NONE)));
|
||||
return PrimarySkill(loadVariable("primarySkill", value, variables, PrimarySkill::NONE.getNum()));
|
||||
}
|
||||
|
||||
/// Method that allows type-specific object filtering
|
||||
@ -322,7 +322,7 @@ namespace JsonRandom
|
||||
for(const auto & pair : value.Struct())
|
||||
{
|
||||
PrimarySkill id = decodeKey<PrimarySkill>(pair.second.meta, pair.first, variables);
|
||||
ret[static_cast<int>(id)] += loadValue(pair.second, rng, variables);
|
||||
ret[id.getNum()] += loadValue(pair.second, rng, variables);
|
||||
}
|
||||
}
|
||||
if(value.isVector())
|
||||
@ -333,7 +333,7 @@ namespace JsonRandom
|
||||
PrimarySkill skillID = *RandomGeneratorUtil::nextItem(potentialPicks, rng);
|
||||
|
||||
defaultSkills.erase(skillID);
|
||||
ret[static_cast<int>(skillID)] += loadValue(element, rng, variables);
|
||||
ret[skillID.getNum()] += loadValue(element, rng, variables);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -114,35 +114,35 @@ std::string MetaString::getLocalString(const std::pair<EMetaText, ui32> & txt) c
|
||||
{
|
||||
case EMetaText::ART_NAMES:
|
||||
{
|
||||
const auto * art = ArtifactID(ser).toArtifact(VLC->artifacts());
|
||||
const auto * art = ArtifactID(ser).toEntity(VLC);
|
||||
if(art)
|
||||
return art->getNameTranslated();
|
||||
return "#!#";
|
||||
}
|
||||
case EMetaText::ART_DESCR:
|
||||
{
|
||||
const auto * art = ArtifactID(ser).toArtifact(VLC->artifacts());
|
||||
const auto * art = ArtifactID(ser).toEntity(VLC);
|
||||
if(art)
|
||||
return art->getDescriptionTranslated();
|
||||
return "#!#";
|
||||
}
|
||||
case EMetaText::ART_EVNTS:
|
||||
{
|
||||
const auto * art = ArtifactID(ser).toArtifact(VLC->artifacts());
|
||||
const auto * art = ArtifactID(ser).toEntity(VLC);
|
||||
if(art)
|
||||
return art->getEventTranslated();
|
||||
return "#!#";
|
||||
}
|
||||
case EMetaText::CRE_PL_NAMES:
|
||||
{
|
||||
const auto * cre = CreatureID(ser).toCreature(VLC->creatures());
|
||||
const auto * cre = CreatureID(ser).toEntity(VLC);
|
||||
if(cre)
|
||||
return cre->getNamePluralTranslated();
|
||||
return "#!#";
|
||||
}
|
||||
case EMetaText::CRE_SING_NAMES:
|
||||
{
|
||||
const auto * cre = CreatureID(ser).toCreature(VLC->creatures());
|
||||
const auto * cre = CreatureID(ser).toEntity(VLC);
|
||||
if(cre)
|
||||
return cre->getNameSingularTranslated();
|
||||
return "#!#";
|
||||
@ -157,7 +157,7 @@ std::string MetaString::getLocalString(const std::pair<EMetaText, ui32> & txt) c
|
||||
}
|
||||
case EMetaText::SPELL_NAME:
|
||||
{
|
||||
const auto * spell = SpellID(ser).toSpell(VLC->spells());
|
||||
const auto * spell = SpellID(ser).toEntity(VLC);
|
||||
if(spell)
|
||||
return spell->getNameTranslated();
|
||||
return "#!#";
|
||||
|
@ -25,19 +25,6 @@ ResourceSet::ResourceSet(const JsonNode & node)
|
||||
container[i] = static_cast<int>(node[GameConstants::RESOURCE_NAMES[i]].Float());
|
||||
}
|
||||
|
||||
ResourceSet::ResourceSet(TResource wood, TResource mercury, TResource ore, TResource sulfur, TResource crystal,
|
||||
TResource gems, TResource gold, TResource mithril)
|
||||
{
|
||||
container[GameResID(EGameResID::WOOD)] = wood;
|
||||
container[GameResID(EGameResID::MERCURY)] = mercury;
|
||||
container[GameResID(EGameResID::ORE)] = ore;
|
||||
container[GameResID(EGameResID::SULFUR)] = sulfur;
|
||||
container[GameResID(EGameResID::CRYSTAL)] = crystal;
|
||||
container[GameResID(EGameResID::GEMS)] = gems;
|
||||
container[GameResID(EGameResID::GOLD)] = gold;
|
||||
container[GameResID(EGameResID::MITHRIL)] = mithril;
|
||||
}
|
||||
|
||||
void ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName)
|
||||
{
|
||||
if(handler.saving && !nonZero())
|
||||
|
@ -26,12 +26,11 @@ class ResourceSet;
|
||||
class ResourceSet
|
||||
{
|
||||
private:
|
||||
std::array<TResource, GameConstants::RESOURCE_QUANTITY> container;
|
||||
std::array<TResource, GameConstants::RESOURCE_QUANTITY> container = {};
|
||||
public:
|
||||
// read resources set from json. Format example: { "gold": 500, "wood":5 }
|
||||
DLL_LINKAGE ResourceSet(const JsonNode & node);
|
||||
DLL_LINKAGE ResourceSet(TResource wood = 0, TResource mercury = 0, TResource ore = 0, TResource sulfur = 0, TResource crystal = 0,
|
||||
TResource gems = 0, TResource gold = 0, TResource mithril = 0);
|
||||
DLL_LINKAGE ResourceSet() = default;
|
||||
|
||||
|
||||
#define scalarOperator(OPSIGN) \
|
||||
|
@ -1155,7 +1155,7 @@ std::pair<const battle::Unit *, BattleHex> CBattleInfoCallback::getNearestStack(
|
||||
|
||||
BattleHex CBattleInfoCallback::getAvaliableHex(const CreatureID & creID, ui8 side, int initialPos) const
|
||||
{
|
||||
bool twoHex = VLC->creh->objects[creID]->isDoubleWide();
|
||||
bool twoHex = VLC->creatures()->getById(creID)->isDoubleWide();
|
||||
|
||||
int pos;
|
||||
if (initialPos > -1)
|
||||
@ -1663,7 +1663,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, c
|
||||
|| !(spellID.toSpell()->canBeCast(this, spells::Mode::CREATURE_ACTIVE, subject)))
|
||||
continue;
|
||||
|
||||
switch (spellID)
|
||||
switch (spellID.toEnum())
|
||||
{
|
||||
case SpellID::SHIELD:
|
||||
case SpellID::FIRE_SHIELD: // not if all enemy units are shooters
|
||||
|
@ -18,7 +18,7 @@ void SideInBattle::init(const CGHeroInstance * Hero, const CArmedInstance * Army
|
||||
hero = Hero;
|
||||
armyObject = Army;
|
||||
|
||||
switch(armyObject->ID)
|
||||
switch(armyObject->ID.toEnum())
|
||||
{
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR2:
|
||||
|
@ -218,7 +218,7 @@ int Unit::getRawSurrenderCost() const
|
||||
void UnitInfo::serializeJson(JsonSerializeFormat & handler)
|
||||
{
|
||||
handler.serializeInt("count", count);
|
||||
handler.serializeId("type", type, CreatureID::NONE);
|
||||
handler.serializeId("type", type, CreatureID(CreatureID::NONE));
|
||||
handler.serializeInt("side", side);
|
||||
handler.serializeInt("position", position);
|
||||
handler.serializeBool("summoned", summoned);
|
||||
|
@ -100,13 +100,13 @@ std::string Bonus::Description(std::optional<si32> customValue) const
|
||||
switch(source)
|
||||
{
|
||||
case BonusSource::ARTIFACT:
|
||||
str << sid.as<ArtifactID>().toArtifact(VLC->artifacts())->getNameTranslated();
|
||||
str << sid.as<ArtifactID>().toEntity(VLC)->getNameTranslated();
|
||||
break;
|
||||
case BonusSource::SPELL_EFFECT:
|
||||
str << sid.as<SpellID>().toSpell(VLC->spells())->getNameTranslated();
|
||||
str << sid.as<SpellID>().toEntity(VLC)->getNameTranslated();
|
||||
break;
|
||||
case BonusSource::CREATURE_ABILITY:
|
||||
str << sid.as<CreatureID>().toCreature(VLC->creatures())->getNamePluralTranslated();
|
||||
str << sid.as<CreatureID>().toEntity(VLC)->getNamePluralTranslated();
|
||||
break;
|
||||
case BonusSource::SECONDARY_SKILL:
|
||||
str << VLC->skills()->getById(sid.as<SecondarySkill>())->getNameTranslated();
|
||||
|
@ -114,7 +114,7 @@ CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature & creature_, bool Inc
|
||||
|
||||
void CCreatureTypeLimiter::setCreature(const CreatureID & id)
|
||||
{
|
||||
creature = VLC->creh->objects[id];
|
||||
creature = id.toCreature();
|
||||
}
|
||||
|
||||
std::string CCreatureTypeLimiter::toString() const
|
||||
@ -317,7 +317,7 @@ ILimiter::EDecision FactionLimiter::limit(const BonusLimitationContext &context)
|
||||
std::string FactionLimiter::toString() const
|
||||
{
|
||||
boost::format fmt("FactionLimiter(faction=%s)");
|
||||
fmt % VLC->factions()->getByIndex(faction)->getJsonKey();
|
||||
fmt % VLC->factions()->getById(faction)->getJsonKey();
|
||||
return fmt.str();
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ JsonNode FactionLimiter::toJsonNode() const
|
||||
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
||||
|
||||
root["type"].String() = "FACTION_LIMITER";
|
||||
root["parameters"].Vector().push_back(JsonUtils::stringNode(VLC->factions()->getByIndex(faction)->getJsonKey()));
|
||||
root["parameters"].Vector().push_back(JsonUtils::stringNode(VLC->factions()->getById(faction)->getJsonKey()));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ ImagePath CampaignRegions::getBackgroundName() const
|
||||
|
||||
Point CampaignRegions::getPosition(CampaignScenarioID which) const
|
||||
{
|
||||
auto const & region = regions[static_cast<int>(which)];
|
||||
auto const & region = regions[which.getNum()];
|
||||
return Point(region.xpos, region.ypos);
|
||||
}
|
||||
|
||||
ImagePath CampaignRegions::getNameFor(CampaignScenarioID which, int colorIndex, std::string type) const
|
||||
{
|
||||
auto const & region = regions[static_cast<int>(which)];
|
||||
auto const & region = regions[which.getNum()];
|
||||
|
||||
static const std::string colors[2][8] =
|
||||
{
|
||||
@ -267,7 +267,7 @@ void CampaignState::setCurrentMapAsConquered(std::vector<CGHeroInstance *> heroe
|
||||
return a->getHeroStrength() > b->getHeroStrength();
|
||||
});
|
||||
|
||||
logGlobal->info("Scenario %d of campaign %s (%s) has been completed", static_cast<int>(*currentMap), getFilename(), getNameTranslated());
|
||||
logGlobal->info("Scenario %d of campaign %s (%s) has been completed", currentMap->getNum(), getFilename(), getNameTranslated());
|
||||
|
||||
mapsConquered.push_back(*currentMap);
|
||||
auto reservedHeroes = getReservedHeroes();
|
||||
@ -320,7 +320,7 @@ std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId) const
|
||||
CMapService mapService;
|
||||
std::string scenarioName = getFilename().substr(0, getFilename().find('.'));
|
||||
boost::to_lower(scenarioName);
|
||||
scenarioName += ':' + std::to_string(static_cast<int>(scenarioId));
|
||||
scenarioName += ':' + std::to_string(scenarioId.getNum());
|
||||
const auto & mapContent = mapPieces.find(scenarioId)->second;
|
||||
return mapService.loadMap(mapContent.data(), mapContent.size(), scenarioName, getModName(), getEncoding());
|
||||
}
|
||||
@ -333,7 +333,7 @@ std::unique_ptr<CMapHeader> CampaignState::getMapHeader(CampaignScenarioID scena
|
||||
CMapService mapService;
|
||||
std::string scenarioName = getFilename().substr(0, getFilename().find('.'));
|
||||
boost::to_lower(scenarioName);
|
||||
scenarioName += ':' + std::to_string(static_cast<int>(scenarioId));
|
||||
scenarioName += ':' + std::to_string(scenarioId.getNum());
|
||||
const auto & mapContent = mapPieces.find(scenarioId)->second;
|
||||
return mapService.loadMapHeader(mapContent.data(), mapContent.size(), scenarioName, getModName(), getEncoding());
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <vcmi/HeroTypeService.h>
|
||||
#include <vcmi/HeroClass.h>
|
||||
#include <vcmi/HeroClassService.h>
|
||||
#include <vcmi/Services.h>
|
||||
|
||||
#include <vcmi/spells/Spell.h>
|
||||
#include <vcmi/spells/Service.h>
|
||||
@ -28,6 +29,7 @@
|
||||
#include "modding/IdentifierStorage.h"
|
||||
#include "modding/ModScope.h"
|
||||
#include "VCMI_Lib.h"
|
||||
#include "CHeroHandler.h"
|
||||
#include "CArtHandler.h"//todo: remove
|
||||
#include "CCreatureHandler.h"//todo: remove
|
||||
#include "spells/CSpellHandler.h" //todo: remove
|
||||
@ -191,12 +193,12 @@ std::string HeroTypeID::entityType()
|
||||
|
||||
const CArtifact * ArtifactIDBase::toArtifact() const
|
||||
{
|
||||
return dynamic_cast<const CArtifact*>(toArtifact(VLC->artifacts()));
|
||||
return dynamic_cast<const CArtifact*>(toEntity(VLC));
|
||||
}
|
||||
|
||||
const Artifact * ArtifactIDBase::toArtifact(const ArtifactService * service) const
|
||||
const Artifact * ArtifactIDBase::toEntity(const Services * services) const
|
||||
{
|
||||
return service->getByIndex(num);
|
||||
return services->artifacts()->getByIndex(num);
|
||||
}
|
||||
|
||||
si32 ArtifactID::decode(const std::string & identifier)
|
||||
@ -237,7 +239,12 @@ const CCreature * CreatureIDBase::toCreature() const
|
||||
return VLC->creh->objects.at(num);
|
||||
}
|
||||
|
||||
const Creature * CreatureIDBase::toCreature(const CreatureService * creatures) const
|
||||
const Creature * CreatureIDBase::toEntity(const Services * services) const
|
||||
{
|
||||
return toEntity(services->creatures());
|
||||
}
|
||||
|
||||
const Creature * CreatureIDBase::toEntity(const CreatureService * creatures) const
|
||||
{
|
||||
return creatures->getByIndex(num);
|
||||
}
|
||||
@ -271,11 +278,26 @@ const CSpell * SpellIDBase::toSpell() const
|
||||
return VLC->spellh->objects[num];
|
||||
}
|
||||
|
||||
const spells::Spell * SpellIDBase::toSpell(const spells::Service * service) const
|
||||
const spells::Spell * SpellIDBase::toEntity(const Services * services) const
|
||||
{
|
||||
return toEntity(services->spells());
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
const HeroType * HeroTypeID::toEntity(const Services * services) const
|
||||
{
|
||||
return services->heroTypes()->getByIndex(num);
|
||||
}
|
||||
|
||||
si32 SpellID::decode(const std::string & identifier)
|
||||
{
|
||||
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
|
||||
@ -369,7 +391,7 @@ si32 FactionID::decode(const std::string & identifier)
|
||||
if(rawId)
|
||||
return rawId.value();
|
||||
else
|
||||
return FactionID::DEFAULT;
|
||||
return FactionID::DEFAULT.getNum();
|
||||
}
|
||||
|
||||
std::string FactionID::encode(const si32 index)
|
||||
|
@ -14,10 +14,14 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class Services;
|
||||
class Artifact;
|
||||
class ArtifactService;
|
||||
class Creature;
|
||||
class CreatureService;
|
||||
class HeroType;
|
||||
class CHero;
|
||||
class HeroTypeService;
|
||||
|
||||
namespace spells
|
||||
{
|
||||
@ -186,6 +190,9 @@ public:
|
||||
DLL_LINKAGE static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
|
||||
const CHero * toHeroType() const;
|
||||
const HeroType * toEntity(const Services * services) const;
|
||||
|
||||
DLL_LINKAGE static const HeroTypeID NONE;
|
||||
DLL_LINKAGE static const HeroTypeID RANDOM;
|
||||
|
||||
@ -401,10 +408,6 @@ class BuildingID : public IdentifierWithEnum<BuildingID, BuildingIDBase>
|
||||
{
|
||||
public:
|
||||
using IdentifierWithEnum<BuildingID, BuildingIDBase>::IdentifierWithEnum;
|
||||
|
||||
DLL_LINKAGE static si32 decode(const std::string & identifier);
|
||||
DLL_LINKAGE static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
};
|
||||
|
||||
class MapObjectBaseID : public IdentifierBase
|
||||
@ -679,7 +682,7 @@ public:
|
||||
};
|
||||
|
||||
DLL_LINKAGE const CArtifact * toArtifact() const;
|
||||
DLL_LINKAGE const Artifact * toArtifact(const ArtifactService * service) const;
|
||||
DLL_LINKAGE const Artifact * toEntity(const Services * service) const;
|
||||
};
|
||||
|
||||
class ArtifactID : public IdentifierWithEnum<ArtifactID, ArtifactIDBase>
|
||||
@ -719,7 +722,8 @@ public:
|
||||
};
|
||||
|
||||
DLL_LINKAGE const CCreature * toCreature() const;
|
||||
DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const;
|
||||
DLL_LINKAGE const Creature * toEntity(const Services * services) const;
|
||||
DLL_LINKAGE const Creature * toEntity(const CreatureService * creatures) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CreatureID : public IdentifierWithEnum<CreatureID, CreatureIDBase>
|
||||
@ -837,7 +841,8 @@ public:
|
||||
};
|
||||
|
||||
const CSpell * toSpell() const; //deprecated
|
||||
const spells::Spell * toSpell(const spells::Service * service) const;
|
||||
const spells::Spell * toEntity(const Services * service) const;
|
||||
const spells::Spell * toEntity(const spells::Service * service) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE SpellID : public IdentifierWithEnum<SpellID, SpellIDBase>
|
||||
|
@ -226,7 +226,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
|
||||
// Explicitly initialize static variables
|
||||
for(auto & elem : players)
|
||||
{
|
||||
CGKeys::playerKeyMap[elem.first] = std::set<ui8>();
|
||||
CGKeys::playerKeyMap[elem.first] = std::set<MapObjectSubID>();
|
||||
}
|
||||
for(auto & elem : teams)
|
||||
{
|
||||
@ -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());
|
||||
CGHeroInstance * hero = dynamic_cast<CGHeroInstance *>(obj);
|
||||
|
||||
@ -630,7 +630,7 @@ void CGameState::initHeroes()
|
||||
|
||||
hero->initHero(getRandomGenerator());
|
||||
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
|
||||
@ -661,7 +661,7 @@ void CGameState::initHeroes()
|
||||
{
|
||||
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
|
||||
hero->initHero(getRandomGenerator());
|
||||
map->allHeroes[hero->getHeroType()] = hero;
|
||||
map->allHeroes[hero->getHeroType().getNum()] = hero;
|
||||
}
|
||||
}
|
||||
|
||||
@ -674,7 +674,7 @@ void CGameState::initHeroes()
|
||||
heroesPool->addHeroToPool(ph);
|
||||
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
|
||||
@ -760,7 +760,7 @@ void CGameState::initStartingBonus()
|
||||
logGlobal->error("Cannot give starting artifact - no heroes!");
|
||||
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);
|
||||
|
||||
CGHeroInstance *hero = elem.second.heroes[0];
|
||||
if(!giveHeroArtifact(hero, toGive->getId()))
|
||||
@ -931,7 +931,7 @@ void CGameState::initMapObjects()
|
||||
if(!obj)
|
||||
continue;
|
||||
|
||||
switch (obj->ID)
|
||||
switch(obj->ID.toEnum())
|
||||
{
|
||||
case Obj::QUEST_GUARD:
|
||||
case Obj::SEER_HUT:
|
||||
|
@ -90,7 +90,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(std::vector<CampaignHeroR
|
||||
.And(Selector::subtype()(BonusSubtypeID(g)))
|
||||
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
|
||||
|
||||
cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g];
|
||||
cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g.getNum()];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -375,7 +375,7 @@ std::vector<CampaignHeroReplacement> CGameStateCampaign::generateCampaignHeroesT
|
||||
auto * heroPlaceholder = dynamic_cast<CGHeroPlaceholder *>(obj.get());
|
||||
|
||||
// only 1 field must be set
|
||||
assert(heroPlaceholder->powerRank != heroPlaceholder->heroType);
|
||||
assert(heroPlaceholder->powerRank.has_value() != heroPlaceholder->heroType.has_value());
|
||||
|
||||
if(heroPlaceholder->powerRank)
|
||||
placeholdersByPower.push_back(heroPlaceholder);
|
||||
@ -498,7 +498,7 @@ void CGameStateCampaign::initStartingResources()
|
||||
std::vector<const PlayerSettings *> people = getHumanPlayerInfo(); //players we will give resource bonus
|
||||
for(const PlayerSettings *ps : people)
|
||||
{
|
||||
std::vector<int> res; //resources we will give
|
||||
std::vector<GameResID> res; //resources we will give
|
||||
switch (chosenBonus->info1)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6:
|
||||
|
@ -285,10 +285,9 @@ void CObjectClassesHandler::loadObject(std::string scope, std::string name, cons
|
||||
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
|
||||
assert(ID < objects.size());
|
||||
assert(objects[ID]);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void CObjectClassesHandler::removeSubObject(si32 ID, si32 subID)
|
||||
void CObjectClassesHandler::removeSubObject(MapObjectID ID, MapObjectSubID subID)
|
||||
{
|
||||
assert(ID < objects.size());
|
||||
assert(objects[ID]);
|
||||
assert(subID < objects[ID]->objects.size());
|
||||
objects[ID]->objects[subID] = nullptr;
|
||||
@ -311,7 +309,7 @@ std::vector<bool> CObjectClassesHandler::getDefaultAllowed() const
|
||||
return std::vector<bool>(); //TODO?
|
||||
}
|
||||
|
||||
TObjectTypeHandler CObjectClassesHandler::getHandlerFor(si32 type, si32 subtype) const
|
||||
TObjectTypeHandler CObjectClassesHandler::getHandlerFor(MapObjectID type, MapObjectSubID subtype) const
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -352,9 +350,9 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(CompoundMapObjectID comp
|
||||
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)
|
||||
if (entry)
|
||||
@ -363,9 +361,9 @@ std::set<si32> CObjectClassesHandler::knownObjects() const
|
||||
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))
|
||||
{
|
||||
@ -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);
|
||||
if (handler && handler->hasNameTextID())
|
||||
@ -470,7 +468,7 @@ std::string CObjectClassesHandler::getObjectName(si32 type, si32 subtype) const
|
||||
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:
|
||||
// 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)
|
||||
subtype = 0;
|
||||
|
||||
assert(type < objects.size());
|
||||
assert(objects[type]);
|
||||
assert(subtype < objects[type]->objects.size());
|
||||
|
||||
return getHandlerFor(type, subtype)->getSounds();
|
||||
}
|
||||
|
||||
std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const
|
||||
std::string CObjectClassesHandler::getObjectHandlerName(MapObjectID type) const
|
||||
{
|
||||
return objects.at(type)->handlerName;
|
||||
}
|
||||
|
||||
std::string CObjectClassesHandler::getJsonKey(si32 type) const
|
||||
std::string CObjectClassesHandler::getJsonKey(MapObjectID type) const
|
||||
{
|
||||
return objects.at(type)->getJsonKey();
|
||||
}
|
||||
|
@ -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, size_t index) override;
|
||||
|
||||
void loadSubObject(const std::string & identifier, JsonNode config, si32 ID, si32 subID);
|
||||
void removeSubObject(si32 ID, si32 subID);
|
||||
void loadSubObject(const std::string & identifier, JsonNode config, MapObjectID ID, MapObjectSubID subID);
|
||||
void removeSubObject(MapObjectID ID, MapObjectSubID subID);
|
||||
|
||||
void beforeValidate(JsonNode & object) override;
|
||||
void afterLoadFinalization() override;
|
||||
@ -114,22 +114,22 @@ public:
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
/// Queries to detect loaded objects
|
||||
std::set<si32> knownObjects() const;
|
||||
std::set<si32> knownSubObjects(si32 primaryID) const;
|
||||
std::set<MapObjectID> knownObjects() const;
|
||||
std::set<MapObjectSubID> knownSubObjects(MapObjectID primaryID) const;
|
||||
|
||||
/// 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(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)
|
||||
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)
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
||||
for(const auto & slot : Slots())
|
||||
{
|
||||
const CStackInstance * inst = slot.second;
|
||||
const CCreature * creature = VLC->creh->objects[inst->getCreatureID()];
|
||||
const auto * creature = inst->getCreatureID().toEntity(VLC);
|
||||
|
||||
factions.insert(creature->getFaction());
|
||||
// Check for undead flag instead of faction (undead mummies are neutral)
|
||||
@ -92,7 +92,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
||||
|
||||
for(auto f : factions)
|
||||
{
|
||||
if (VLC->factions()->getByIndex(f)->getAlignment() != EAlignment::EVIL)
|
||||
if (VLC->factions()->getById(f)->getAlignment() != EAlignment::EVIL)
|
||||
mixableFactions++;
|
||||
}
|
||||
if (mixableFactions > 0)
|
||||
|
@ -137,7 +137,7 @@ void CBank::onHeroVisit(const CGHeroInstance * h) const
|
||||
cb->sendAndApply(&cov);
|
||||
|
||||
int banktext = 0;
|
||||
switch (ID)
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
case Obj::DERELICT_SHIP:
|
||||
banktext = 41;
|
||||
@ -180,7 +180,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
|
||||
if (bc)
|
||||
{
|
||||
switch (ID)
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
case Obj::DERELICT_SHIP:
|
||||
textID = 43;
|
||||
@ -203,7 +203,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ID)
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
case Obj::SHIPWRECK:
|
||||
case Obj::DERELICT_SHIP:
|
||||
@ -216,7 +216,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
gbonus.bonus.sid = BonusSourceID(ID);
|
||||
gbonus.bonus.type = BonusType::MORALE;
|
||||
gbonus.bonus.val = -1;
|
||||
switch (ID)
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
case Obj::SHIPWRECK:
|
||||
textID = 123;
|
||||
@ -271,7 +271,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
loot.appendRawString("%d %s");
|
||||
loot.replaceNumber(bc->resources[it]);
|
||||
loot.replaceLocalString(EMetaText::RES_NAMES, it);
|
||||
cb->giveResource(hero->getOwner(), static_cast<EGameResID>(it), bc->resources[it]);
|
||||
cb->giveResource(hero->getOwner(), it, bc->resources[it]);
|
||||
}
|
||||
}
|
||||
//grant artifacts
|
||||
@ -280,7 +280,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, elem);
|
||||
loot.appendRawString("%s");
|
||||
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
|
||||
if (!iw.components.empty())
|
||||
@ -314,7 +314,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
}
|
||||
for(const SpellID & spellId : bc->spells)
|
||||
{
|
||||
const auto * spell = spellId.toSpell(VLC->spells());
|
||||
const auto * spell = spellId.toEntity(VLC);
|
||||
iw.text.appendLocalString(EMetaText::SPELL_NAME, spellId);
|
||||
if(spell->getLevel() <= hero->maxSpellLevel())
|
||||
{
|
||||
|
@ -161,7 +161,7 @@ CreatureID CGCreature::getCreature() const
|
||||
|
||||
void CGCreature::pickRandomObject(CRandomGenerator & rand)
|
||||
{
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case MapObjectID::RANDOM_MONSTER:
|
||||
subID = VLC->creh->pickRandomMonster(rand);
|
||||
@ -427,7 +427,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
|
||||
if(!upgrades.empty())
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ FactionID CGDwelling::randomizeFaction(CRandomGenerator & rand)
|
||||
|
||||
std::vector<FactionID> potentialPicks;
|
||||
|
||||
for (FactionID faction(0); faction < VLC->townh->size(); ++faction)
|
||||
for (FactionID faction(0); faction < FactionID(VLC->townh->size()); ++faction)
|
||||
if (VLC->factions()->getById(faction)->hasTown())
|
||||
potentialPicks.push_back(faction);
|
||||
|
||||
@ -142,7 +142,7 @@ void CGDwelling::pickRandomObject(CRandomGenerator & rand)
|
||||
{
|
||||
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();
|
||||
@ -170,7 +170,7 @@ void CGDwelling::pickRandomObject(CRandomGenerator & rand)
|
||||
|
||||
void CGDwelling::initObj(CRandomGenerator & rand)
|
||||
{
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
@ -319,7 +319,7 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const
|
||||
else
|
||||
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);
|
||||
if (creaturesAccumulate && ID != Obj::REFUGEE_CAMP) //camp should not try to accumulate different kinds of creatures
|
||||
sac.creatures[i].first += amount;
|
||||
@ -344,7 +344,7 @@ void CGDwelling::updateGuards() const
|
||||
//default condition - creatures are of level 5 or higher
|
||||
for (auto creatureEntry : creatures)
|
||||
{
|
||||
if (VLC->creatures()->getByIndex(creatureEntry.second.at(0))->getLevel() >= 5 && ID != Obj::REFUGEE_CAMP)
|
||||
if (VLC->creatures()->getById(creatureEntry.second.at(0))->getLevel() >= 5 && ID != Obj::REFUGEE_CAMP)
|
||||
{
|
||||
guarded = true;
|
||||
break;
|
||||
@ -355,7 +355,7 @@ void CGDwelling::updateGuards() const
|
||||
{
|
||||
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());
|
||||
|
||||
if (hasStackAtSlot(slot)) //stack already exists, overwrite it
|
||||
@ -488,7 +488,7 @@ void CGDwelling::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer)
|
||||
|
||||
void CGDwelling::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
{
|
||||
switch (ID)
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
case Obj::WAR_MACHINE_FACTORY:
|
||||
case Obj::REFUGEE_CAMP:
|
||||
|
@ -218,7 +218,10 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
|
||||
if (getSecSkillLevel(which) > 0)
|
||||
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 true;
|
||||
@ -1679,7 +1682,7 @@ void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler)
|
||||
{
|
||||
auto addSkill = [this](const std::string & skillId, const std::string & levelId)
|
||||
{
|
||||
const int rawId = CSkillHandler::decodeSkill(skillId);
|
||||
const int rawId = SecondarySkill::decode(skillId);
|
||||
if(rawId < 0)
|
||||
{
|
||||
logGlobal->error("Invalid secondary skill %s", skillId);
|
||||
|
@ -173,7 +173,7 @@ void CGObjectInstance::pickRandomObject(CRandomGenerator & rand)
|
||||
|
||||
void CGObjectInstance::initObj(CRandomGenerator & rand)
|
||||
{
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case Obj::TAVERN:
|
||||
blockVisit = true;
|
||||
@ -302,7 +302,7 @@ std::vector<Component> CGObjectInstance::getPopupComponents(const CGHeroInstance
|
||||
|
||||
void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case Obj::SANCTUARY:
|
||||
{
|
||||
|
@ -257,7 +257,7 @@ void CGPandoraBox::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
const std::string skillName = p.first;
|
||||
const std::string levelId = p.second.String();
|
||||
|
||||
const int rawId = CSkillHandler::decodeSkill(skillName);
|
||||
const int rawId = SecondarySkill::decode(skillName);
|
||||
if(rawId < 0)
|
||||
{
|
||||
logGlobal->error("Invalid secondary skill %s", skillName);
|
||||
|
@ -372,7 +372,7 @@ bool CGTownInstance::isBonusingBuildingAdded(BuildingID bid) const
|
||||
{
|
||||
auto present = std::find_if(bonusingBuildings.begin(), bonusingBuildings.end(), [&](CGTownBuilding* building)
|
||||
{
|
||||
return building->getBuildingType().num == bid;
|
||||
return building->getBuildingType() == bid;
|
||||
});
|
||||
|
||||
return present != bonusingBuildings.end();
|
||||
@ -470,7 +470,7 @@ FactionID CGTownInstance::randomizeFaction(CRandomGenerator & rand)
|
||||
|
||||
std::vector<FactionID> potentialPicks;
|
||||
|
||||
for (FactionID faction(0); faction < VLC->townh->size(); ++faction)
|
||||
for (FactionID faction(0); faction < FactionID(VLC->townh->size()); ++faction)
|
||||
if (VLC->factions()->getById(faction)->hasTown())
|
||||
potentialPicks.push_back(faction);
|
||||
|
||||
@ -584,7 +584,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const
|
||||
|
||||
TQuantity count = creatureGrowth(i);
|
||||
if (!count) // no dwelling
|
||||
count = VLC->creatures()->getByIndex(c)->getGrowth();
|
||||
count = VLC->creatures()->getById(c)->getGrowth();
|
||||
|
||||
{//no lower tiers or above current month
|
||||
|
||||
@ -917,7 +917,7 @@ const CTown * CGTownInstance::getTown() const
|
||||
{
|
||||
if(nullptr == town)
|
||||
{
|
||||
return (*VLC->townh)[subID]->town;
|
||||
return (*VLC->townh)[getFaction()]->town;
|
||||
}
|
||||
else
|
||||
return town;
|
||||
@ -996,9 +996,9 @@ bool CGTownInstance::hasBuilt(const BuildingID & buildingID) const
|
||||
return vstd::contains(builtBuildings, buildingID);
|
||||
}
|
||||
|
||||
bool CGTownInstance::hasBuilt(const BuildingID & buildingID, int townID) const
|
||||
bool CGTownInstance::hasBuilt(const BuildingID & buildingID, FactionID townID) const
|
||||
{
|
||||
if (townID == town->faction->getIndex() || townID == ETownType::ANY)
|
||||
if (townID == town->faction->getId() || townID == FactionID::ANY)
|
||||
return hasBuilt(buildingID);
|
||||
return false;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ public:
|
||||
bool hasBuilt(BuildingSubID::EBuildingSubID buildingID) const;
|
||||
//checks if building is constructed and town has same subID
|
||||
bool hasBuilt(const BuildingID & buildingID) const;
|
||||
bool hasBuilt(const BuildingID & buildingID, int townID) const;
|
||||
bool hasBuilt(const BuildingID & buildingID, FactionID townID) const;
|
||||
|
||||
TResources getBuildingCost(const BuildingID & buildingID) const;
|
||||
TResources dailyIncome() const; //calculates daily income of this town
|
||||
|
@ -34,7 +34,7 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
std::map <PlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
|
||||
std::map <PlayerColor, std::set <MapObjectSubID> > CGKeys::playerKeyMap;
|
||||
|
||||
//TODO: Remove constructor
|
||||
CQuest::CQuest():
|
||||
@ -392,15 +392,15 @@ void CQuest::serializeJson(JsonSerializeFormat & handler, const std::string & fi
|
||||
|
||||
if(missionType == "Hero")
|
||||
{
|
||||
ui32 temp;
|
||||
handler.serializeId<ui32, ui32, HeroTypeID>("hero", temp, 0);
|
||||
HeroTypeID temp;
|
||||
handler.serializeId("hero", temp, HeroTypeID::NONE);
|
||||
mission.heroes.emplace_back(temp);
|
||||
}
|
||||
|
||||
if(missionType == "Player")
|
||||
{
|
||||
ui32 temp;
|
||||
handler.serializeId<ui32, ui32, PlayerColor>("player", temp, PlayerColor::NEUTRAL);
|
||||
PlayerColor temp;
|
||||
handler.serializeId("player", temp, PlayerColor::NEUTRAL);
|
||||
mission.players.emplace_back(temp);
|
||||
}
|
||||
}
|
||||
@ -724,7 +724,7 @@ void CGQuestGuard::init(CRandomGenerator & rand)
|
||||
|
||||
configuration.info.push_back({});
|
||||
configuration.info.back().visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
|
||||
configuration.info.back().reward.removeObject = subID == 0 ? true : false;
|
||||
configuration.info.back().reward.removeObject = subID.getNum() == 0 ? true : false;
|
||||
configuration.canRefuse = true;
|
||||
}
|
||||
|
||||
@ -775,7 +775,7 @@ std::string CGKeys::getHoverText(PlayerColor player) 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
|
||||
@ -810,7 +810,7 @@ void CGBorderGuard::getRolloverText(MetaString &text, bool onHover) const
|
||||
{
|
||||
if (!onHover)
|
||||
{
|
||||
text.appendRawString(VLC->generaltexth->tentColors[subID]);
|
||||
text.appendRawString(VLC->generaltexth->tentColors[subID.getNum()]);
|
||||
text.appendRawString(" ");
|
||||
text.appendRawString(VLC->objtypeh->getObjectName(Obj::KEYMASTER, subID));
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ protected:
|
||||
class DLL_LINKAGE CGKeys : public CGObjectInstance //Base class for Keymaster and guards
|
||||
{
|
||||
public:
|
||||
static std::map <PlayerColor, std::set <ui8> > playerKeyMap; //[players][keysowned]
|
||||
static std::map <PlayerColor, std::set <MapObjectSubID> > playerKeyMap; //[players][keysowned]
|
||||
//SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black
|
||||
|
||||
static void reset();
|
||||
|
@ -119,14 +119,14 @@ void CGMine::initObj(CRandomGenerator & rand)
|
||||
}
|
||||
else
|
||||
{
|
||||
producedResource = GameResID(getObjTypeIndex());
|
||||
producedResource = GameResID(getObjTypeIndex().getNum());
|
||||
}
|
||||
producedQuantity = defaultResProduction();
|
||||
}
|
||||
|
||||
bool CGMine::isAbandoned() const
|
||||
{
|
||||
return (getObjTypeIndex() >= 7);
|
||||
return subID.getNum() >= 7;
|
||||
}
|
||||
|
||||
ResourceSet CGMine::dailyIncome() const
|
||||
@ -147,7 +147,7 @@ std::string CGMine::getHoverText(PlayerColor player) const
|
||||
std::string hoverName = CArmedInstance::getHoverText(player);
|
||||
|
||||
if (tempOwner != PlayerColor::NEUTRAL)
|
||||
hoverName += "\n(" + VLC->generaltexth->restypes[producedResource] + ")";
|
||||
hoverName += "\n(" + VLC->generaltexth->restypes[producedResource.getNum()] + ")";
|
||||
|
||||
if(stacksCount())
|
||||
{
|
||||
@ -252,7 +252,7 @@ GameResID CGResource::resourceID() const
|
||||
|
||||
std::string CGResource::getHoverText(PlayerColor player) const
|
||||
{
|
||||
return VLC->generaltexth->restypes[resourceID()];
|
||||
return VLC->generaltexth->restypes[resourceID().getNum()];
|
||||
}
|
||||
|
||||
void CGResource::pickRandomObject(CRandomGenerator & rand)
|
||||
@ -273,7 +273,7 @@ void CGResource::initObj(CRandomGenerator & rand)
|
||||
|
||||
if(amount == CGResource::RANDOM_AMOUNT)
|
||||
{
|
||||
switch(resourceID())
|
||||
switch(resourceID().toEnum())
|
||||
{
|
||||
case EGameResID::GOLD:
|
||||
amount = rand.nextInt(5, 10) * 100;
|
||||
@ -467,7 +467,7 @@ void CGTeleport::addToChannel(std::map<TeleportChannelID, std::shared_ptr<Telepo
|
||||
}
|
||||
}
|
||||
|
||||
TeleportChannelID CGMonolith::findMeChannel(const std::vector<Obj> & IDs, int SubID) const
|
||||
TeleportChannelID CGMonolith::findMeChannel(const std::vector<Obj> & IDs, MapObjectSubID SubID) const
|
||||
{
|
||||
for(auto obj : cb->gameState()->map->objects)
|
||||
{
|
||||
@ -532,7 +532,7 @@ void CGMonolith::initObj(CRandomGenerator & rand)
|
||||
{
|
||||
std::vector<Obj> IDs;
|
||||
IDs.push_back(ID);
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
|
||||
type = ENTRANCE;
|
||||
@ -723,7 +723,7 @@ ArtifactID CGArtifact::getArtifact() const
|
||||
|
||||
void CGArtifact::pickRandomObject(CRandomGenerator & rand)
|
||||
{
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case MapObjectID::RANDOM_ART:
|
||||
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC);
|
||||
@ -760,7 +760,7 @@ void CGArtifact::initObj(CRandomGenerator & rand)
|
||||
storedArtifact = a;
|
||||
}
|
||||
if(!storedArtifact->artType)
|
||||
storedArtifact->setType(VLC->arth->objects[getArtifact()]);
|
||||
storedArtifact->setType(VLC->arth->objects[getArtifact().getNum()]);
|
||||
}
|
||||
if(ID == Obj::SPELL_SCROLL)
|
||||
subID = 1;
|
||||
@ -773,7 +773,7 @@ void CGArtifact::initObj(CRandomGenerator & rand)
|
||||
|
||||
std::string CGArtifact::getObjectName() const
|
||||
{
|
||||
return VLC->artifacts()->getByIndex(getArtifact())->getNameTranslated();
|
||||
return VLC->artifacts()->getById(getArtifact())->getNameTranslated();
|
||||
}
|
||||
|
||||
void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
@ -786,7 +786,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
if(storedArtifact->artType->canBePutAt(h))
|
||||
{
|
||||
switch (ID)
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
case Obj::ARTIFACT:
|
||||
{
|
||||
@ -821,7 +821,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(ID)
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case Obj::ARTIFACT:
|
||||
{
|
||||
|
@ -225,7 +225,7 @@ public:
|
||||
|
||||
class DLL_LINKAGE CGMonolith : public CGTeleport
|
||||
{
|
||||
TeleportChannelID findMeChannel(const std::vector<Obj> & IDs, int SubID) const;
|
||||
TeleportChannelID findMeChannel(const std::vector<Obj> & IDs, MapObjectSubID SubID) const;
|
||||
|
||||
protected:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
|
@ -71,6 +71,8 @@ void CMapEvent::serializeJson(JsonSerializeFormat & handler)
|
||||
void CCastleEvent::serializeJson(JsonSerializeFormat & handler)
|
||||
{
|
||||
CMapEvent::serializeJson(handler);
|
||||
|
||||
// TODO: handler.serializeIdArray("buildings", buildings);
|
||||
{
|
||||
std::vector<BuildingID> temp(buildings.begin(), buildings.end());
|
||||
auto a = handler.enterArray("buildings");
|
||||
@ -81,6 +83,7 @@ void CCastleEvent::serializeJson(JsonSerializeFormat & handler)
|
||||
buildings.insert(temp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto a = handler.enterArray("creatures");
|
||||
a.syncSize(creatures);
|
||||
@ -253,7 +256,7 @@ void CMap::calculateGuardingGreaturePositions()
|
||||
CGHeroInstance * CMap::getHero(HeroTypeID heroID)
|
||||
{
|
||||
for(auto & elem : heroesOnMap)
|
||||
if(elem->getObjTypeIndex() == heroID.getNum())
|
||||
if(elem->getHeroType() == heroID)
|
||||
return elem;
|
||||
return nullptr;
|
||||
}
|
||||
@ -393,7 +396,7 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(const int3 & pos, Obj type
|
||||
// There is weird bug because of which sometimes heroes will not be found properly despite having correct position
|
||||
// Try to workaround that and find closest object that we can use
|
||||
|
||||
logGlobal->error("Failed to find object of type %d at %s", static_cast<int>(type), pos.toString());
|
||||
logGlobal->error("Failed to find object of type %d at %s", type.getNum(), pos.toString());
|
||||
logGlobal->error("Will try to find closest matching object");
|
||||
|
||||
CGObjectInstance * bestMatch = nullptr;
|
||||
|
@ -883,7 +883,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
|
||||
}
|
||||
map->predefinedHeroes.emplace_back(hero);
|
||||
|
||||
logGlobal->debug("Map '%s': Hero predefined in map: %s", mapName, VLC->heroh->getByIndex(hero->subID)->getJsonKey());
|
||||
logGlobal->debug("Map '%s': Hero predefined in map: %s", mapName, VLC->heroh->getById(hero->getHeroType())->getJsonKey());
|
||||
}
|
||||
}
|
||||
|
||||
@ -926,7 +926,7 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
|
||||
if(artifactID == ArtifactID::NONE)
|
||||
return false;
|
||||
|
||||
const Artifact * art = artifactID.toArtifact(VLC->artifacts());
|
||||
const Artifact * art = artifactID.toEntity(VLC);
|
||||
|
||||
if(!art)
|
||||
{
|
||||
@ -1287,7 +1287,7 @@ CGObjectInstance * CMapLoaderH3M::readResource(const int3 & mapPosition, std::sh
|
||||
readMessageAndGuards(object->message, object, mapPosition);
|
||||
|
||||
object->amount = reader->readUInt32();
|
||||
if(objectTemplate->subid == GameResID(EGameResID::GOLD))
|
||||
if(GameResID(objectTemplate->subid) == GameResID(EGameResID::GOLD))
|
||||
{
|
||||
// Gold is multiplied by 100.
|
||||
object->amount *= 100;
|
||||
@ -1488,7 +1488,7 @@ CGObjectInstance * CMapLoaderH3M::readBank(const int3 & mapPosition, std::shared
|
||||
|
||||
CGObjectInstance * CMapLoaderH3M::readObject(std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & mapPosition, const ObjectInstanceID & objectInstanceID)
|
||||
{
|
||||
switch(objectTemplate->id)
|
||||
switch(objectTemplate->id.toEnum())
|
||||
{
|
||||
case Obj::EVENT:
|
||||
return readEvent(mapPosition, objectInstanceID);
|
||||
@ -1740,7 +1740,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
||||
|
||||
for(auto & elem : map->disposedHeroes)
|
||||
{
|
||||
if(elem.heroId.getNum() == object->subID)
|
||||
if(elem.heroId == object->getHeroType())
|
||||
{
|
||||
object->nameCustomTextId = elem.name;
|
||||
object->customPortraitSource = elem.portrait;
|
||||
@ -1750,7 +1750,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
||||
|
||||
bool hasName = reader->readBool();
|
||||
if(hasName)
|
||||
object->nameCustomTextId = readLocalizedString(TextIdentifier("heroes", object->subID, "name"));
|
||||
object->nameCustomTextId = readLocalizedString(TextIdentifier("heroes", object->getHeroType().getNum(), "name"));
|
||||
|
||||
if(features.levelSOD)
|
||||
{
|
||||
@ -1861,8 +1861,8 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
||||
}
|
||||
}
|
||||
|
||||
if (object->subID != -1)
|
||||
logGlobal->debug("Map '%s': Hero on map: %s at %s, owned by %s", mapName, VLC->heroh->getByIndex(object->subID)->getJsonKey(), mapPosition.toString(), object->getOwner().toString());
|
||||
if (object->subID != MapObjectSubID())
|
||||
logGlobal->debug("Map '%s': Hero on map: %s at %s, owned by %s", mapName, VLC->heroh->getById(object->getHeroType())->getJsonKey(), mapPosition.toString(), object->getOwner().toString());
|
||||
else
|
||||
logGlobal->debug("Map '%s': Hero on map: (random) at %s, owned by %s", mapName, mapPosition.toString(), object->getOwner().toString());
|
||||
|
||||
|
@ -171,10 +171,10 @@ namespace TriggeredEventsDetail
|
||||
case EMetaclass::OBJECT:
|
||||
{
|
||||
//TODO
|
||||
std::set<si32> subtypes = VLC->objtypeh->knownSubObjects(type);
|
||||
auto subtypes = VLC->objtypeh->knownSubObjects(type);
|
||||
if(!subtypes.empty())
|
||||
{
|
||||
si32 subtype = *subtypes.begin();
|
||||
auto subtype = *subtypes.begin();
|
||||
auto handler = VLC->objtypeh->getHandlerFor(type, subtype);
|
||||
identifier = handler->getTypeName();
|
||||
}
|
||||
@ -831,7 +831,7 @@ void CMapFormatJson::serializeOptions(JsonSerializeFormat & handler)
|
||||
|
||||
serializePredefinedHeroes(handler);
|
||||
|
||||
handler.serializeLIC("allowedAbilities", &CSkillHandler::decodeSkill, &CSkillHandler::encodeSkill, VLC->skillh->getDefaultAllowed(), map->allowedAbilities);
|
||||
handler.serializeLIC("allowedAbilities", &SecondarySkill::decode, &SecondarySkill::encode, VLC->skillh->getDefaultAllowed(), map->allowedAbilities);
|
||||
|
||||
handler.serializeLIC("allowedArtifacts", &ArtifactID::decode, &ArtifactID::encode, VLC->arth->getDefaultAllowed(), map->allowedArtifact);
|
||||
|
||||
|
@ -944,7 +944,7 @@ void FoWChange::applyGs(CGameState *gs)
|
||||
const CGObjectInstance *o = elem;
|
||||
if (o)
|
||||
{
|
||||
switch(o->ID)
|
||||
switch(o->ID.toEnum())
|
||||
{
|
||||
case Obj::HERO:
|
||||
case Obj::MINE:
|
||||
@ -2113,7 +2113,7 @@ void BattleStart::applyGs(CGameState * gs) const
|
||||
info->battleID = gs->nextBattleID;
|
||||
info->localInit();
|
||||
|
||||
gs->nextBattleID = vstd::next(gs->nextBattleID, 1);
|
||||
gs->nextBattleID = BattleID(gs->nextBattleID.getNum() + 1);
|
||||
}
|
||||
|
||||
void BattleNextRound::applyGs(CGameState * gs) const
|
||||
|
@ -197,7 +197,7 @@ struct DLL_LINKAGE CPathsInfo
|
||||
STRONG_INLINE
|
||||
CGPathNode * getNode(const int3 & coord, const ELayer layer)
|
||||
{
|
||||
return &nodes[layer][coord.z][coord.x][coord.y];
|
||||
return &nodes[layer.getNum()][coord.z][coord.x][coord.y];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -302,7 +302,7 @@ bool CPathfinder::isLayerTransitionPossible() const
|
||||
if(source.node->action == EPathNodeAction::BATTLE)
|
||||
return false;
|
||||
|
||||
switch(source.node->layer)
|
||||
switch(source.node->layer.toEnum())
|
||||
{
|
||||
case ELayer::LAND:
|
||||
if(destLayer == ELayer::AIR)
|
||||
@ -505,7 +505,7 @@ void CPathfinderHelper::updateTurnInfo(const int Turn)
|
||||
|
||||
bool CPathfinderHelper::isLayerAvailable(const EPathfindingLayer & layer) const
|
||||
{
|
||||
switch(layer)
|
||||
switch(layer.toEnum())
|
||||
{
|
||||
case EPathfindingLayer::AIR:
|
||||
if(!options.useFlying)
|
||||
|
@ -123,7 +123,7 @@ void DestinationActionRule::process(
|
||||
EPathNodeAction action = EPathNodeAction::NORMAL;
|
||||
const auto * hero = pathfinderHelper->hero;
|
||||
|
||||
switch(destination.node->layer)
|
||||
switch(destination.node->layer.toEnum())
|
||||
{
|
||||
case EPathfindingLayer::LAND:
|
||||
if(source.node->layer == EPathfindingLayer::SAIL)
|
||||
@ -290,7 +290,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
||||
if(destination.node->accessible == EPathAccessibility::BLOCKED)
|
||||
return BlockingReason::DESTINATION_BLOCKED;
|
||||
|
||||
switch(destination.node->layer)
|
||||
switch(destination.node->layer.toEnum())
|
||||
{
|
||||
case EPathfindingLayer::LAND:
|
||||
if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord))
|
||||
@ -359,7 +359,7 @@ void LayerTransitionRule::process(
|
||||
if(source.node->layer == destination.node->layer)
|
||||
return;
|
||||
|
||||
switch(source.node->layer)
|
||||
switch(source.node->layer.toEnum())
|
||||
{
|
||||
case EPathfindingLayer::LAND:
|
||||
if(destination.node->layer == EPathfindingLayer::SAIL)
|
||||
|
@ -47,7 +47,7 @@ TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn):
|
||||
|
||||
bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
|
||||
{
|
||||
switch(layer)
|
||||
switch(layer.toEnum())
|
||||
{
|
||||
case EPathfindingLayer::AIR:
|
||||
if(hero && hero->boat && hero->boat->layer == EPathfindingLayer::AIR)
|
||||
|
@ -234,7 +234,7 @@ void Rewardable::Info::configureVariables(Rewardable::Configuration & object, CR
|
||||
value = JsonRandom::loadSpell(input, rng, object.variables.values).getNum();
|
||||
|
||||
if (category.first == "primarySkill")
|
||||
value = static_cast<int>(JsonRandom::loadPrimary(input, rng, object.variables.values));
|
||||
value = JsonRandom::loadPrimary(input, rng, object.variables.values).getNum();
|
||||
|
||||
if (category.first == "secondarySkill")
|
||||
value = JsonRandom::loadSecondary(input, rng, object.variables.values).getNum();
|
||||
|
@ -128,7 +128,7 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
|
||||
|
||||
for(const auto & spell : canLearnSpells)
|
||||
{
|
||||
if (!hero->canLearnSpell(spell.toSpell(VLC->spells()), true))
|
||||
if (!hero->canLearnSpell(spell.toEntity(VLC), true))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ void Rewardable::Limiter::serializeJson(JsonSerializeFormat & handler)
|
||||
std::vector<std::pair<SecondarySkill, si32>> fieldValue(secondary.begin(), secondary.end());
|
||||
a.serializeStruct<std::pair<SecondarySkill, si32>>(fieldValue, [](JsonSerializeFormat & h, std::pair<SecondarySkill, si32> & e)
|
||||
{
|
||||
h.serializeId("skill", e.first, SecondarySkill{}, VLC->skillh->decodeSkill, VLC->skillh->encodeSkill);
|
||||
h.serializeId("skill", e.first, SecondarySkill(SecondarySkill::NONE));
|
||||
h.serializeId("level", e.second, 0, [](const std::string & i){return vstd::find_pos(NSecondarySkill::levels, i);}, [](si32 i){return NSecondarySkill::levels.at(i);});
|
||||
});
|
||||
a.syncSize(fieldValue);
|
||||
|
@ -133,7 +133,7 @@ void Rewardable::Reward::serializeJson(JsonSerializeFormat & handler)
|
||||
std::vector<std::pair<SecondarySkill, si32>> fieldValue(secondary.begin(), secondary.end());
|
||||
a.serializeStruct<std::pair<SecondarySkill, si32>>(fieldValue, [](JsonSerializeFormat & h, std::pair<SecondarySkill, si32> & e)
|
||||
{
|
||||
h.serializeId("skill", e.first, SecondarySkill{}, VLC->skillh->decodeSkill, VLC->skillh->encodeSkill);
|
||||
h.serializeId("skill", e.first);
|
||||
h.serializeId("level", e.second, 0, [](const std::string & i){return vstd::find_pos(NSecondarySkill::levels, i);}, [](si32 i){return NSecondarySkill::levels.at(i);});
|
||||
});
|
||||
a.syncSize(fieldValue);
|
||||
|
@ -144,7 +144,7 @@ void CMapGenOptions::resetPlayersMap()
|
||||
for(const auto & p : players)
|
||||
{
|
||||
auto town = p.second.getStartingTown();
|
||||
if (town != RANDOM_SIZE)
|
||||
if (town != FactionID::RANDOM)
|
||||
rememberTownTypes[p.first] = FactionID(town);
|
||||
rememberTeam[p.first] = p.second.getTeam();
|
||||
}
|
||||
@ -187,7 +187,7 @@ const std::map<PlayerColor, CMapGenOptions::CPlayerSettings> & CMapGenOptions::g
|
||||
return players;
|
||||
}
|
||||
|
||||
void CMapGenOptions::setStartingTownForPlayer(const PlayerColor & color, si32 town)
|
||||
void CMapGenOptions::setStartingTownForPlayer(const PlayerColor & color, FactionID town)
|
||||
{
|
||||
auto it = players.find(color);
|
||||
if(it == players.end()) assert(0);
|
||||
@ -522,17 +522,17 @@ void CMapGenOptions::CPlayerSettings::setColor(const PlayerColor & value)
|
||||
color = value;
|
||||
}
|
||||
|
||||
si32 CMapGenOptions::CPlayerSettings::getStartingTown() const
|
||||
FactionID CMapGenOptions::CPlayerSettings::getStartingTown() const
|
||||
{
|
||||
return startingTown;
|
||||
}
|
||||
|
||||
void CMapGenOptions::CPlayerSettings::setStartingTown(si32 value)
|
||||
void CMapGenOptions::CPlayerSettings::setStartingTown(FactionID value)
|
||||
{
|
||||
assert(value >= -1);
|
||||
if(value >= 0)
|
||||
assert(value >= FactionID::RANDOM);
|
||||
if(value != FactionID::RANDOM)
|
||||
{
|
||||
assert(value < static_cast<int>(VLC->townh->size()));
|
||||
assert(value < FactionID(VLC->townh->size()));
|
||||
assert((*VLC->townh)[value]->town != nullptr);
|
||||
}
|
||||
startingTown = value;
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
|
||||
/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN.
|
||||
/// The default value is RANDOM_TOWN.
|
||||
si32 getStartingTown() const;
|
||||
void setStartingTown(si32 value);
|
||||
FactionID getStartingTown() const;
|
||||
void setStartingTown(FactionID value);
|
||||
|
||||
/// The default value is EPlayerType::AI.
|
||||
EPlayerType getPlayerType() const;
|
||||
@ -55,7 +55,7 @@ public:
|
||||
|
||||
private:
|
||||
PlayerColor color;
|
||||
si32 startingTown;
|
||||
FactionID startingTown;
|
||||
EPlayerType playerType;
|
||||
TeamID team;
|
||||
|
||||
@ -114,7 +114,7 @@ public:
|
||||
/// The first player colors belong to standard players and the last player colors belong to comp only players.
|
||||
/// All standard players are by default of type EPlayerType::AI.
|
||||
const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
|
||||
void setStartingTownForPlayer(const PlayerColor & color, si32 town);
|
||||
void setStartingTownForPlayer(const PlayerColor & color, FactionID town);
|
||||
/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
|
||||
/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
|
||||
void setPlayerTypeForStandardPlayer(const PlayerColor & color, EPlayerType playerType);
|
||||
|
@ -442,7 +442,7 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
||||
{
|
||||
auto player = PlayerColor(*owner - 1);
|
||||
auto playerSettings = map.getMapGenOptions().getPlayersSettings();
|
||||
si32 faction = FactionID::RANDOM;
|
||||
FactionID faction = FactionID::RANDOM;
|
||||
if (vstd::contains(playerSettings, player))
|
||||
faction = playerSettings[player].getStartingTown();
|
||||
else
|
||||
|
@ -556,7 +556,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
|
||||
}
|
||||
}
|
||||
|
||||
switch (instance->object().ID)
|
||||
switch (instance->object().ID.toEnum())
|
||||
{
|
||||
case Obj::RANDOM_TREASURE_ART:
|
||||
case Obj::RANDOM_MINOR_ART: //In OH3 quest artifacts have higher value than normal arts
|
||||
@ -586,7 +586,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
|
||||
case Obj::MONOLITH_ONE_WAY_EXIT:
|
||||
*/
|
||||
|
||||
switch (object.instances().front()->object().ID)
|
||||
switch(object.instances().front()->object().ID.toEnum())
|
||||
{
|
||||
case Obj::WATER_WHEEL:
|
||||
if (auto* m = zone.getModificator<RiverPlacer>())
|
||||
|
@ -53,14 +53,14 @@ struct VectorizedObjectInfo
|
||||
/// Base class for serializers capable of reading or writing data
|
||||
class DLL_LINKAGE CSerializer
|
||||
{
|
||||
template<typename T>
|
||||
static si32 idToNumber(const T &t, typename std::enable_if<std::is_convertible<T,si32>::value>::type * dummy = nullptr)
|
||||
template<typename Numeric, std::enable_if_t<std::is_arithmetic_v<Numeric>, bool> = true>
|
||||
static int32_t idToNumber(const Numeric &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T, typename NT>
|
||||
static NT idToNumber(const IdentifierBase &t)
|
||||
template<typename IdentifierType, std::enable_if_t<std::is_base_of_v<IdentifierBase, IdentifierType>, bool> = true>
|
||||
static int32_t idToNumber(const IdentifierType &t)
|
||||
{
|
||||
return t.getNum();
|
||||
}
|
||||
|
@ -295,14 +295,16 @@ public:
|
||||
}
|
||||
|
||||
///si32-convertible identifier <-> Json string
|
||||
template <typename T, typename U, typename E = T>
|
||||
void serializeId(const std::string & fieldName, T & value, const U & defaultValue)
|
||||
template <typename IdentifierType, typename IdentifierTypeBase = IdentifierType>
|
||||
void serializeId(const std::string & fieldName, IdentifierType & value, const IdentifierTypeBase & defaultValue = IdentifierType::NONE)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IdentifierBase, IdentifierType>, "This method can only serialize Identifier classes!");
|
||||
|
||||
if (saving)
|
||||
{
|
||||
if (value != defaultValue)
|
||||
{
|
||||
std::string fieldValue = E::encode(value);
|
||||
std::string fieldValue = IdentifierType::encode(value.getNum());
|
||||
serializeString(fieldName, fieldValue);
|
||||
}
|
||||
}
|
||||
@ -313,13 +315,13 @@ public:
|
||||
|
||||
if (!fieldValue.empty())
|
||||
{
|
||||
VLC->identifiers()->requestIdentifier(ModScope::scopeGame(), E::entityType(), fieldValue, [&value](int32_t index){
|
||||
value = T(index);
|
||||
VLC->identifiers()->requestIdentifier(ModScope::scopeGame(), IdentifierType::entityType(), fieldValue, [&value](int32_t index){
|
||||
value = IdentifierType(index);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
value = T(defaultValue);
|
||||
value = IdentifierType(defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -333,7 +335,7 @@ public:
|
||||
std::vector<std::string> fieldValue;
|
||||
|
||||
for(const T & vitem : value)
|
||||
fieldValue.push_back(E::encode(vitem));
|
||||
fieldValue.push_back(E::encode(vitem.getNum()));
|
||||
|
||||
serializeInternal(fieldName, fieldValue);
|
||||
}
|
||||
@ -362,7 +364,7 @@ public:
|
||||
std::vector<std::string> fieldValue;
|
||||
|
||||
for(const T & vitem : value)
|
||||
fieldValue.push_back(U::encode(vitem));
|
||||
fieldValue.push_back(U::encode(vitem.getNum()));
|
||||
|
||||
serializeInternal(fieldName, fieldValue);
|
||||
}
|
||||
@ -387,7 +389,24 @@ public:
|
||||
const TDecoder decoder = std::bind(&IInstanceResolver::decode, instanceResolver, _1);
|
||||
const TEncoder encoder = std::bind(&IInstanceResolver::encode, instanceResolver, _1);
|
||||
|
||||
serializeId<T>(fieldName, value, defaultValue, decoder, encoder);
|
||||
if (saving)
|
||||
{
|
||||
if (value != defaultValue)
|
||||
{
|
||||
std::string fieldValue = encoder(value.getNum());
|
||||
serializeString(fieldName, fieldValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fieldValue;
|
||||
serializeString(fieldName, fieldValue);
|
||||
|
||||
if (!fieldValue.empty())
|
||||
value = T(decoder(fieldValue));
|
||||
else
|
||||
value = T(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
///any serializable object <-> Json struct
|
||||
|
@ -717,7 +717,7 @@ IAdventureSpellMechanics::IAdventureSpellMechanics(const CSpell * s)
|
||||
|
||||
std::unique_ptr<IAdventureSpellMechanics> IAdventureSpellMechanics::createMechanics(const CSpell * s)
|
||||
{
|
||||
switch (s->id)
|
||||
switch(s->id.toEnum())
|
||||
{
|
||||
case SpellID::SUMMON_BOAT:
|
||||
return std::make_unique<SummonBoatMechanics>(s);
|
||||
|
@ -23,6 +23,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
struct Query;
|
||||
class IBattleState;
|
||||
class CRandomGenerator;
|
||||
class CreatureService;
|
||||
class CMap;
|
||||
class CGameInfoCallback;
|
||||
class CBattleInfoCallback;
|
||||
@ -32,6 +33,11 @@ class CStack;
|
||||
class CGObjectInstance;
|
||||
class CGHeroInstance;
|
||||
|
||||
namespace spells
|
||||
{
|
||||
class Service;
|
||||
}
|
||||
|
||||
namespace vstd
|
||||
{
|
||||
class RNG;
|
||||
|
@ -49,7 +49,7 @@ void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const Effe
|
||||
break;
|
||||
}
|
||||
|
||||
const auto *creatureType = creature.toCreature(m->creatures());
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
|
||||
int32_t deadCount = targetStack->unitBaseAmount();
|
||||
int32_t deadTotalHealth = targetStack->getTotalHealth();
|
||||
@ -111,7 +111,7 @@ bool DemonSummon::isValidTarget(const Mechanics * m, const battle::Unit * unit)
|
||||
if (unit->isGhost())
|
||||
return false;
|
||||
|
||||
const auto *creatureType = creature.toCreature(m->creatures());
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
|
||||
if (unit->getTotalHealth() < creatureType->getMaxHealth())
|
||||
return false;
|
||||
|
@ -93,7 +93,7 @@ std::shared_ptr<const BonusList> Dispel::getBonuses(const Mechanics * m, const b
|
||||
{
|
||||
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)
|
||||
return false;//error
|
||||
|
||||
|
@ -107,7 +107,7 @@ void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTar
|
||||
|
||||
if(summonByHealth)
|
||||
{
|
||||
const auto *creatureType = creature.toCreature(m->creatures());
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
auto creatureMaxHealth = creatureType->getMaxHealth();
|
||||
amount = static_cast<int32_t>(valueWithBonus / creatureMaxHealth);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
|
||||
if(ins->storedArtifact)
|
||||
{
|
||||
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
|
||||
issues.emplace_back(QString(tr("Spell scroll %1 doesn't have instance assigned and must be removed")).arg(ins->instanceName.c_str()), true);
|
||||
|
@ -323,7 +323,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
|
||||
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE);
|
||||
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)
|
||||
cs.spells.insert(spell->getId());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user