diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 1af8a3547..8fd9f2d16 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -11,6 +11,7 @@ #include "../../lib/ArtifactUtils.h" #include "../../lib/UnlockGuard.h" +#include "../../lib/StartInfo.h" #include "../../lib/mapObjects/MapObjects.h" #include "../../lib/mapObjects/ObjectTemplate.h" #include "../../lib/mapObjects/CGHeroInstance.h" @@ -750,7 +751,7 @@ void AIGateway::showGarrisonDialog(const CArmedInstance * up, const CGHeroInstan //you can't request action from action-response thread requestActionASAP([=]() { - if(removableUnits && up->tempOwner == down->tempOwner) + if(removableUnits && up->tempOwner == down->tempOwner && nullkiller->settings->isGarrisonTroopsUsageAllowed() && !cb->getStartInfo()->isSteadwickFallCampaignMission()) { pickBestCreatures(down, up); } diff --git a/AI/Nullkiller/Engine/Settings.cpp b/AI/Nullkiller/Engine/Settings.cpp index e9d42b458..d10bb0048 100644 --- a/AI/Nullkiller/Engine/Settings.cpp +++ b/AI/Nullkiller/Engine/Settings.cpp @@ -18,7 +18,7 @@ #include "../../../lib/modding/CModHandler.h" #include "../../../lib/VCMI_Lib.h" #include "../../../lib/filesystem/Filesystem.h" -#include "../../../lib/json/JsonNode.h" +#include "../../../lib/json/JsonUtils.h" namespace NKAI { @@ -28,29 +28,11 @@ namespace NKAI scoutHeroTurnDistanceLimit(5), maxGoldPressure(0.3f), maxpass(10), - allowObjectGraph(false) + allowObjectGraph(false), + useTroopsFromGarrisons(false) { - ResourcePath resource("config/ai/nkai/nkai-settings", EResType::JSON); + JsonNode node = JsonUtils::assembleFromFiles("config/ai/nkai/nkai-settings"); - loadFromMod("core", resource); - - for(const auto & modName : VLC->modh->getActiveMods()) - { - if(CResourceHandler::get(modName)->existsResource(resource)) - loadFromMod(modName, resource); - } - } - - void Settings::loadFromMod(const std::string & modName, const ResourcePath & resource) - { - if(!CResourceHandler::get(modName)->existsResource(resource)) - { - logGlobal->error("Failed to load font %s from mod %s", resource.getName(), modName); - return; - } - - JsonNode node(JsonPath::fromResource(resource), modName); - if(node.Struct()["maxRoamingHeroes"].isNumber()) { maxRoamingHeroes = node.Struct()["maxRoamingHeroes"].Integer(); @@ -80,5 +62,10 @@ namespace NKAI { allowObjectGraph = node.Struct()["allowObjectGraph"].Bool(); } + + if(!node.Struct()["useTroopsFromGarrisons"].isNull()) + { + useTroopsFromGarrisons = node.Struct()["useTroopsFromGarrisons"].Bool(); + } } -} \ No newline at end of file +} diff --git a/AI/Nullkiller/Engine/Settings.h b/AI/Nullkiller/Engine/Settings.h index 881dc436f..381493889 100644 --- a/AI/Nullkiller/Engine/Settings.h +++ b/AI/Nullkiller/Engine/Settings.h @@ -27,6 +27,7 @@ namespace NKAI int maxpass; float maxGoldPressure; bool allowObjectGraph; + bool useTroopsFromGarrisons; public: Settings(); @@ -37,8 +38,6 @@ namespace NKAI int getMainHeroTurnDistanceLimit() const { return mainHeroTurnDistanceLimit; } int getScoutHeroTurnDistanceLimit() const { return scoutHeroTurnDistanceLimit; } bool isObjectGraphAllowed() const { return allowObjectGraph; } - - private: - void loadFromMod(const std::string & modName, const ResourcePath & resource); + bool isGarrisonTroopsUsageAllowed() const { return useTroopsFromGarrisons; } }; -} \ No newline at end of file +} diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 4c9ba1c7d..e395f1b3c 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -16,6 +16,7 @@ #include "../../lib/ArtifactUtils.h" #include "../../lib/UnlockGuard.h" +#include "../../lib/StartInfo.h" #include "../../lib/mapObjects/MapObjects.h" #include "../../lib/mapObjects/ObjectTemplate.h" #include "../../lib/CConfigHandler.h" @@ -732,7 +733,7 @@ void VCAI::showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * //you can't request action from action-response thread requestActionASAP([=]() { - if(removableUnits) + if(removableUnits && !cb->getStartInfo()->isSteadwickFallCampaignMission()) pickBestCreatures(down, up); answerQuery(queryID, 0); diff --git a/config/ai/nkai/nkai-settings.json b/config/ai/nkai/nkai-settings.json index 3dedd8f22..a7dd1ec08 100644 --- a/config/ai/nkai/nkai-settings.json +++ b/config/ai/nkai/nkai-settings.json @@ -3,5 +3,6 @@ "maxpass" : 30, "mainHeroTurnDistanceLimit" : 10, "scoutHeroTurnDistanceLimit" : 5, - "maxGoldPressure" : 0.3 + "maxGoldPressure" : 0.3, + "useTroopsFromGarrisons" : true } \ No newline at end of file diff --git a/lib/StartInfo.cpp b/lib/StartInfo.cpp index 73b896716..e9f9c40bb 100644 --- a/lib/StartInfo.cpp +++ b/lib/StartInfo.cpp @@ -89,6 +89,20 @@ std::string StartInfo::getCampaignName() const return VLC->generaltexth->allTexts[508]; } +bool StartInfo::isSteadwickFallCampaignMission() const +{ + if (!campState) + return false; + + if (campState->getFilename() != "DATA/EVIL1") + return false; + + if (campState->currentScenario() != CampaignScenarioID(2)) + return false; + + return true; +} + void LobbyInfo::verifyStateBeforeStart(bool ignoreNoHuman) const { if(!mi || !mi->mapHeader) diff --git a/lib/StartInfo.h b/lib/StartInfo.h index 4067124a8..c221e4521 100644 --- a/lib/StartInfo.h +++ b/lib/StartInfo.h @@ -136,6 +136,9 @@ struct DLL_LINKAGE StartInfo // TODO: Must be client-side std::string getCampaignName() const; + /// Controls hardcoded check for "Steadwick's Fall" scenario from "Dungeon and Devils" campaign + bool isSteadwickFallCampaignMission() const; + template void serialize(Handler &h) {