mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Merge pull request #5952 from IvanSavenko/spell_ban_fix
Fix artifacts providing hero with banned spells
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