From e5e14adb5105d56dffb42eb8216fe21aaffee08a Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 1 Apr 2024 21:52:11 +0200 Subject: [PATCH] Add setting for HD mod tournament rules dimension door limit --- config/gameConfig.json | 4 +++- lib/GameSettings.cpp | 1 + lib/GameSettings.h | 1 + lib/constants/NumericConstants.h | 1 + lib/spells/AdventureSpellMechanics.cpp | 14 +++++++++++++- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/config/gameConfig.json b/config/gameConfig.json index 0d0bd4f0c..37ecb4f34 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -396,7 +396,9 @@ // if enabled, dimension door will hint regarding tile being incompatible terrain type, unlike H3 (water/land) "dimensionDoorExposesTerrainType" : false, // if enabled, dimension door will initiate a fight upon landing on tile adjacent to neutral creature - "dimensionDoorTriggersGuards" : false + "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 }, "bonuses" : diff --git a/lib/GameSettings.cpp b/lib/GameSettings.cpp index 3dc1ab737..9c59b87e1 100644 --- a/lib/GameSettings.cpp +++ b/lib/GameSettings.cpp @@ -106,6 +106,7 @@ void GameSettings::load(const JsonNode & input) {EGameSettings::DIMENSION_DOOR_ONLY_TO_UNCOVERED_TILES, "spells", "dimensionDoorOnlyToUncoveredTiles"}, {EGameSettings::DIMENSION_DOOR_EXPOSES_TERRAIN_TYPE, "spells", "dimensionDoorExposesTerrainType" }, {EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS, "spells", "dimensionDoorTriggersGuards" }, + {EGameSettings::DIMENSION_DOOR_TOURNAMENT_RULES_LIMIT, "spells", "dimensionDoorTournamentRulesLimit"}, {EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP, "towns", "buildingsPerTurnCap" }, {EGameSettings::TOWNS_STARTING_DWELLING_CHANCES, "towns", "startingDwellingChances" }, }; diff --git a/lib/GameSettings.h b/lib/GameSettings.h index a8dc8ec74..10b42dc82 100644 --- a/lib/GameSettings.h +++ b/lib/GameSettings.h @@ -73,6 +73,7 @@ enum class EGameSettings DIMENSION_DOOR_ONLY_TO_UNCOVERED_TILES, DIMENSION_DOOR_EXPOSES_TERRAIN_TYPE, DIMENSION_DOOR_TRIGGERS_GUARDS, + DIMENSION_DOOR_TOURNAMENT_RULES_LIMIT, OPTIONS_COUNT }; diff --git a/lib/constants/NumericConstants.h b/lib/constants/NumericConstants.h index fc6def5ab..b25d2c551 100644 --- a/lib/constants/NumericConstants.h +++ b/lib/constants/NumericConstants.h @@ -52,6 +52,7 @@ namespace GameConstants constexpr ui32 BASE_MOVEMENT_COST = 100; //default cost for non-diagonal movement constexpr int64_t PLAYER_RESOURCES_CAP = 1000 * 1000 * 1000; constexpr int ALTAR_ARTIFACTS_SLOTS = 22; + constexpr int TOURNAMENT_RULES_DD_MAP_TILES_THRESHOLD = 41472; //map tiles count threshold for 2 dimension door casts with tournament rules } VCMI_LIB_NAMESPACE_END diff --git a/lib/spells/AdventureSpellMechanics.cpp b/lib/spells/AdventureSpellMechanics.cpp index c2a5d2712..98fd74c92 100644 --- a/lib/spells/AdventureSpellMechanics.cpp +++ b/lib/spells/AdventureSpellMechanics.cpp @@ -345,7 +345,19 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm std::stringstream cachingStr; cachingStr << "source_" << vstd::to_underlying(BonusSource::SPELL_EFFECT) << "id_" << owner->id.num; - if(parameters.caster->getHeroCaster()->getBonuses(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(owner->id)), Selector::all, cachingStr.str())->size() >= owner->getLevelPower(schoolLevel)) //limit casts per turn + int castsAlreadyPerformedThisTurn = parameters.caster->getHeroCaster()->getBonuses(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(owner->id)), Selector::all, cachingStr.str())->size(); + int castsLimit = owner->getLevelPower(schoolLevel); + + bool isTournamentRulesLimitEnabled = VLC->settings()->getBoolean(EGameSettings::DIMENSION_DOOR_TOURNAMENT_RULES_LIMIT); + if(isTournamentRulesLimitEnabled) + { + bool meetsTournamentRulesTwoCastsRequirements = env->getMap()->width * env->getMap()->height * env->getMap()->levels() >= GameConstants::TOURNAMENT_RULES_DD_MAP_TILES_THRESHOLD + && schoolLevel == MasteryLevel::EXPERT; + + castsLimit = meetsTournamentRulesTwoCastsRequirements ? 2 : 1; + } + + if(castsAlreadyPerformedThisTurn >= castsLimit) //limit casts per turn { InfoWindow iw; iw.player = parameters.caster->getCasterOwner();