mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Fix artifacts providing hero with banned spells
Tomes of X Spells and Spellbinder's Hat (and any other sources for such bonuses from mods) will no longer provide spells that are banned on map. Option is only active for random maps and for HotA h3m's. RoE-SoD .h3m's work as before. If needed, behavior can be changed in config
This commit is contained in:
@@ -154,6 +154,11 @@
|
||||
"restorationOfErathia" : {
|
||||
"supported" : true,
|
||||
"iconIndex" : 0,
|
||||
"settings": {
|
||||
"spells": {
|
||||
"tomesGrantBannedSpells" : true
|
||||
}
|
||||
},
|
||||
"buildingsCommon": {
|
||||
"townHall" : 0,
|
||||
"cityHall" : 1,
|
||||
@@ -476,7 +481,12 @@
|
||||
"iconIndex" : 3
|
||||
},
|
||||
"hornOfTheAbyss" : {
|
||||
"supported" : false
|
||||
"supported" : false,
|
||||
"settings": {
|
||||
"spells": {
|
||||
"tomesGrantBannedSpells" : false
|
||||
}
|
||||
}
|
||||
},
|
||||
"inTheWakeOfGods" : {
|
||||
"supported" : false
|
||||
@@ -750,16 +760,12 @@
|
||||
|
||||
"spells":
|
||||
{
|
||||
// if enabled, dimension work doesn't work into tiles under Fog of War
|
||||
"dimensionDoorOnlyToUncoveredTiles" : false,
|
||||
// if enabled, dimension door will hint regarding tile being incompatible terrain type, unlike H3 (water/land)
|
||||
"dimensionDoorExposesTerrainType" : false,
|
||||
// if enabled, attempt to use dimension door on incompatible terrain (water/land) will result in spending of mana, movement and casts per day (H3 behavior)
|
||||
"dimensionDoorFailureSpendsPoints" : true,
|
||||
// if enabled, dimension door will initiate a fight upon landing on tile adjacent to neutral creature
|
||||
"dimensionDoorTriggersGuards" : false,
|
||||
// if enabled, dimension door can be used 1x per day, exception being 2x per day for XL+U or bigger maps (41472 tiles) + hero having expert air magic
|
||||
"dimensionDoorTournamentRulesLimit" : false
|
||||
// if enabled, SPELLS_OF_SCHOOL bonus (Tomes of Water/Air/Earth/Fire Magic)
|
||||
// and SPELLS_OF_LEVEL bonus (Spellbinder Hat) will grant spells that are banned on map (SoD behavior)
|
||||
// NOTE: this value only affects random maps and .vmap's. For h3m's value is loaded from map format configuration
|
||||
"tomesGrantBannedSpells" : false
|
||||
},
|
||||
|
||||
"bonuses" :
|
||||
|
@@ -167,11 +167,8 @@
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"dimensionDoorOnlyToUncoveredTiles" : { "type" : "boolean" },
|
||||
"dimensionDoorExposesTerrainType" : { "type" : "boolean" },
|
||||
"dimensionDoorFailureSpendsPoints" : { "type" : "boolean" },
|
||||
"dimensionDoorTriggersGuards" : { "type" : "boolean" },
|
||||
"dimensionDoorTournamentRulesLimit" : { "type" : "boolean" }
|
||||
"tomesGrantBannedSpells" : { "type" : "boolean" }
|
||||
}
|
||||
},
|
||||
"bonuses": {
|
||||
|
@@ -68,7 +68,6 @@ const std::vector<GameSettings::SettingOption> GameSettings::settingProperties =
|
||||
{EGameSettings::CREATURES_JOINING_PERCENTAGE, "creatures", "joiningPercentage" },
|
||||
{EGameSettings::CREATURES_WEEKLY_GROWTH_CAP, "creatures", "weeklyGrowthCap" },
|
||||
{EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT, "creatures", "weeklyGrowthPercent" },
|
||||
{EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS, "spells", "dimensionDoorTriggersGuards" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL, "dwellings", "accumulateWhenNeutral" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED, "dwellings", "accumulateWhenOwned" },
|
||||
{EGameSettings::DWELLINGS_MERGE_ON_RECRUIT, "dwellings", "mergeOnRecruit" },
|
||||
@@ -106,6 +105,8 @@ const std::vector<GameSettings::SettingOption> GameSettings::settingProperties =
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_TWO_WAY, "pathfinder", "useMonolithTwoWay" },
|
||||
{EGameSettings::PATHFINDER_USE_WHIRLPOOL, "pathfinder", "useWhirlpool" },
|
||||
{EGameSettings::RESOURCES_WEEKLY_BONUSES_AI, "resources", "weeklyBonusesAI" },
|
||||
{EGameSettings::SPELLS_DIMENSION_DOOR_TRIGGERS_GUARDS, "spells", "dimensionDoorTriggersGuards" },
|
||||
{EGameSettings::SPELLS_TOMES_GRANT_BANNED_SPELLS, "spells", "tomesGrantBannedSpells" },
|
||||
{EGameSettings::TEXTS_ARTIFACT, "textData", "artifact" },
|
||||
{EGameSettings::TEXTS_CREATURE, "textData", "creature" },
|
||||
{EGameSettings::TEXTS_FACTION, "textData", "faction" },
|
||||
|
@@ -41,7 +41,6 @@ enum class EGameSettings
|
||||
CREATURES_JOINING_PERCENTAGE,
|
||||
CREATURES_WEEKLY_GROWTH_CAP,
|
||||
CREATURES_WEEKLY_GROWTH_PERCENT,
|
||||
DIMENSION_DOOR_TRIGGERS_GUARDS,
|
||||
DWELLINGS_ACCUMULATE_WHEN_NEUTRAL,
|
||||
DWELLINGS_ACCUMULATE_WHEN_OWNED,
|
||||
DWELLINGS_MERGE_ON_RECRUIT,
|
||||
@@ -80,6 +79,8 @@ enum class EGameSettings
|
||||
PATHFINDER_USE_MONOLITH_TWO_WAY,
|
||||
PATHFINDER_USE_WHIRLPOOL,
|
||||
RESOURCES_WEEKLY_BONUSES_AI,
|
||||
SPELLS_DIMENSION_DOOR_TRIGGERS_GUARDS,
|
||||
SPELLS_TOMES_GRANT_BANNED_SPELLS,
|
||||
TEXTS_ARTIFACT,
|
||||
TEXTS_CREATURE,
|
||||
TEXTS_FACTION,
|
||||
|
@@ -1250,15 +1250,20 @@ std::vector<BonusSourceID> CGHeroInstance::getSourcesForSpell(const SpellID & sp
|
||||
for(const auto & bonus : *getBonusesOfType(BonusType::SPELL, spellId))
|
||||
sources.emplace_back(bonus->sid);
|
||||
|
||||
const auto spell = spellId.toSpell();
|
||||
spell->forEachSchool([this, &sources](const SpellSchool & cnf, bool & stop)
|
||||
{
|
||||
for(const auto & bonus : *getBonusesOfType(BonusType::SPELLS_OF_SCHOOL, cnf))
|
||||
sources.emplace_back(bonus->sid);
|
||||
});
|
||||
bool tomesGrantBannedSpells = cb->getSettings().getBoolean(EGameSettings::SPELLS_TOMES_GRANT_BANNED_SPELLS);
|
||||
|
||||
for(const auto & bonus : *getBonusesOfType(BonusType::SPELLS_OF_LEVEL, BonusCustomSubtype::spellLevel(spell->getLevel())))
|
||||
sources.emplace_back(bonus->sid);
|
||||
if (tomesGrantBannedSpells || cb->isAllowed(spellId))
|
||||
{
|
||||
const auto spell = spellId.toSpell();
|
||||
spell->forEachSchool([this, &sources](const SpellSchool & cnf, bool & stop)
|
||||
{
|
||||
for(const auto & bonus : *getBonusesOfType(BonusType::SPELLS_OF_SCHOOL, cnf))
|
||||
sources.emplace_back(bonus->sid);
|
||||
});
|
||||
|
||||
for(const auto & bonus : *getBonusesOfType(BonusType::SPELLS_OF_LEVEL, BonusCustomSubtype::spellLevel(spell->getLevel())))
|
||||
sources.emplace_back(bonus->sid);
|
||||
}
|
||||
|
||||
return sources;
|
||||
}
|
||||
|
@@ -743,6 +743,9 @@ void CMapLoaderH3M::readMapOptions()
|
||||
logGlobal->warn("Map '%s': option to ban hero recruitment for %s is not implemented!!", mapName, PlayerColor(i).toString());
|
||||
}
|
||||
}
|
||||
|
||||
const MapIdentifiersH3M & identifierMapper = LIBRARY->mapFormat->getMapping(mapHeader->version);
|
||||
map->overrideGameSettings(identifierMapper.getFormatSettings());
|
||||
}
|
||||
|
||||
void CMapLoaderH3M::readAllowedArtifacts()
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "../entities/faction/CFaction.h"
|
||||
#include "../entities/faction/CTownHandler.h"
|
||||
#include "../filesystem/Filesystem.h"
|
||||
#include "../json/JsonUtils.h"
|
||||
#include "../mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../mapObjects/ObjectTemplate.h"
|
||||
@@ -39,6 +40,10 @@ void MapIdentifiersH3M::loadMapping(const JsonNode & mapping)
|
||||
if (!mapping["supported"].Bool())
|
||||
throw std::runtime_error("Unsupported map format!");
|
||||
|
||||
formatSettings.Struct(); // change type
|
||||
if (!mapping["settings"].isNull())
|
||||
JsonUtils::inherit(formatSettings, mapping["settings"]);
|
||||
|
||||
for (auto entryFaction : mapping["buildings"].Struct())
|
||||
{
|
||||
FactionID factionID (*LIBRARY->identifiers()->getIdentifier(entryFaction.second.getModScope(), "faction", entryFaction.first));
|
||||
|
@@ -12,10 +12,10 @@
|
||||
|
||||
#include "../GameConstants.h"
|
||||
#include "../filesystem/ResourcePath.h"
|
||||
#include "../json/JsonNode.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class JsonNode;
|
||||
class ObjectTemplate;
|
||||
|
||||
struct ObjectTypeIdentifier
|
||||
@@ -50,6 +50,8 @@ class DLL_LINKAGE MapIdentifiersH3M
|
||||
std::map<AnimationPath, AnimationPath> mappingObjectTemplate;
|
||||
std::map<ObjectTypeIdentifier, ObjectTypeIdentifier> mappingObjectIndex;
|
||||
|
||||
JsonNode formatSettings;
|
||||
|
||||
template<typename IdentifierID>
|
||||
void loadMapping(std::map<IdentifierID, IdentifierID> & result, const JsonNode & mapping, const std::string & identifierName);
|
||||
public:
|
||||
@@ -70,6 +72,8 @@ public:
|
||||
SecondarySkill remap(SecondarySkill input) const;
|
||||
CampaignRegionID remap(CampaignRegionID input) const;
|
||||
|
||||
const JsonNode & getFormatSettings() const { return formatSettings; }
|
||||
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -34,7 +34,7 @@ DimensionDoorEffect::DimensionDoorEffect(const CSpell * s, const JsonNode & conf
|
||||
|
||||
std::string DimensionDoorEffect::getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
||||
{
|
||||
if(!cb->getSettings().getBoolean(EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS))
|
||||
if(!cb->getSettings().getBoolean(EGameSettings::SPELLS_DIMENSION_DOOR_TRIGGERS_GUARDS))
|
||||
return cursor;
|
||||
|
||||
if (!exposeFow && !cb->isVisibleFor(pos, caster->getCasterOwner()))
|
||||
|
@@ -1021,7 +1021,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
if (blockingVisit()) // e.g. hero on the other side of teleporter
|
||||
return true;
|
||||
|
||||
EGuardLook guardsCheck = (gameInfo().getSettings().getBoolean(EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS) && movementMode == EMovementMode::DIMENSION_DOOR)
|
||||
EGuardLook guardsCheck = (gameInfo().getSettings().getBoolean(EGameSettings::SPELLS_DIMENSION_DOOR_TRIGGERS_GUARDS) && movementMode == EMovementMode::DIMENSION_DOOR)
|
||||
? CHECK_FOR_GUARDS
|
||||
: IGNORE_GUARDS;
|
||||
|
||||
@@ -1034,10 +1034,8 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
if (const auto * town = dynamic_cast<const CGTownInstance *>(objectToVisit))
|
||||
objectVisited(town, h);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//still here? it is standard movement!
|
||||
{
|
||||
|
Reference in New Issue
Block a user