1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-19 12:02:24 +02:00

Avoid crash in case if Witch Hut or Shrine is not a rewardable object

This commit is contained in:
Ivan Savenko 2023-12-13 16:52:44 +02:00
parent 76cb5387c5
commit 337e090ee9

View File

@ -1145,42 +1145,47 @@ CGObjectInstance * CMapLoaderH3M::readWitchHut(const int3 & position, std::share
auto * object = readGeneric(position, objectTemplate); auto * object = readGeneric(position, objectTemplate);
auto * rewardable = dynamic_cast<CRewardableObject*>(object); auto * rewardable = dynamic_cast<CRewardableObject*>(object);
assert(rewardable);
// AB and later maps have allowed abilities defined in H3M // AB and later maps have allowed abilities defined in H3M
if(features.levelAB) if(features.levelAB)
{ {
std::set<SecondarySkill> allowedAbilities; std::set<SecondarySkill> allowedAbilities;
reader->readBitmaskSkills(allowedAbilities, false); reader->readBitmaskSkills(allowedAbilities, false);
if(allowedAbilities.size() != 1) if (rewardable)
{ {
auto defaultAllowed = VLC->skillh->getDefaultAllowed(); if(allowedAbilities.size() != 1)
{
auto defaultAllowed = VLC->skillh->getDefaultAllowed();
for(int skillID = features.skillsCount; skillID < defaultAllowed.size(); ++skillID) for(int skillID = features.skillsCount; skillID < defaultAllowed.size(); ++skillID)
if(defaultAllowed.count(skillID)) if(defaultAllowed.count(skillID))
allowedAbilities.insert(SecondarySkill(skillID)); allowedAbilities.insert(SecondarySkill(skillID));
} }
JsonNode variable; JsonNode variable;
if (allowedAbilities.size() == 1) if (allowedAbilities.size() == 1)
{ {
variable.String() = VLC->skills()->getById(*allowedAbilities.begin())->getJsonKey(); variable.String() = VLC->skills()->getById(*allowedAbilities.begin())->getJsonKey();
}
else
{
JsonVector anyOfList;
for (auto const & skill : allowedAbilities)
{
JsonNode entry;
entry.String() = VLC->skills()->getById(skill)->getJsonKey();
anyOfList.push_back(entry);
}
variable["anyOf"].Vector() = anyOfList;
}
variable.setMeta(ModScope::scopeGame()); // list may include skills from all mods
rewardable->configuration.presetVariable("secondarySkill", "gainedSkill", variable);
} }
else else
{ {
JsonVector anyOfList; logGlobal->warn("Failed to set allowed secondary skills to a Witch Hut! Object is not rewardable!");
for (auto const & skill : allowedAbilities)
{
JsonNode entry;
entry.String() = VLC->skills()->getById(skill)->getJsonKey();
anyOfList.push_back(entry);
}
variable["anyOf"].Vector() = anyOfList;
} }
variable.setMeta(ModScope::scopeGame()); // list may include skills from all mods
rewardable->configuration.presetVariable("secondarySkill", "gainedSkill", variable);
} }
return object; return object;
} }
@ -1362,16 +1367,21 @@ CGObjectInstance * CMapLoaderH3M::readShrine(const int3 & position, std::shared_
auto * object = readGeneric(position, objectTemplate); auto * object = readGeneric(position, objectTemplate);
auto * rewardable = dynamic_cast<CRewardableObject*>(object); auto * rewardable = dynamic_cast<CRewardableObject*>(object);
assert(rewardable);
SpellID spell = reader->readSpell32(); SpellID spell = reader->readSpell32();
if(spell != SpellID::NONE) if (rewardable)
{ {
JsonNode variable; if(spell != SpellID::NONE)
variable.String() = VLC->spells()->getById(spell)->getJsonKey(); {
variable.setMeta(ModScope::scopeGame()); // list may include spells from all mods JsonNode variable;
rewardable->configuration.presetVariable("spell", "gainedSpell", variable); variable.String() = VLC->spells()->getById(spell)->getJsonKey();
variable.setMeta(ModScope::scopeGame()); // list may include spells from all mods
rewardable->configuration.presetVariable("spell", "gainedSpell", variable);
}
}
else
{
logGlobal->warn("Failed to set selected spell to a Shrine!. Object is not rewardable!");
} }
return object; return object;
} }