diff --git a/config/gameConfig.json b/config/gameConfig.json index 9692abfaf..d60e144c9 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -488,6 +488,20 @@ // if enabled flying will work like in original game, otherwise nerf similar to HotA flying is applied "originalFlyRules" : true }, + + "resources" : { + // H3 mechanics - AI receives bonus (or malus, on easy) to his resource income + // AI will receive specified values as percentage of his weekly income + // So, "gems" : 200 will give AI player 200% of his daily income of gems over week, or, in other words, + // giving AI player 2 additional gems per week for every owned Gem Pond + "weeklyBonusesAI" : { + "pawn" : { "gold" : -175 }, + "knight": {}, + "rook" : {}, + "queen" : { "wood" : 275 , "mercury" : 100, "ore" : 275, "sulfur" : 100, "crystal" : 100, "gems" : 100, "gold" : 175}, + "king" : { "wood" : 375 , "mercury" : 200, "ore" : 375, "sulfur" : 200, "crystal" : 200, "gems" : 200, "gold" : 350} + } + } "spells": { diff --git a/config/schemas/gameSettings.json b/config/schemas/gameSettings.json index bf68e6087..9d1b55b1e 100644 --- a/config/schemas/gameSettings.json +++ b/config/schemas/gameSettings.json @@ -133,6 +133,14 @@ "originalFlyRules" : { "type" : "boolean" } } }, + "resources": { + "type" : "object", + "additionalProperties" : false, + "properties" : { + "weeklyBonusesAI" : { "type" : "object" } + } + }, + "spells": { "type" : "object", "additionalProperties" : false, diff --git a/lib/GameSettings.cpp b/lib/GameSettings.cpp index 563520cb6..2e177d8ef 100644 --- a/lib/GameSettings.cpp +++ b/lib/GameSettings.cpp @@ -89,6 +89,7 @@ const std::vector GameSettings::settingProperties = {EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE, "pathfinder", "useMonolithOneWayUnique" }, {EGameSettings::PATHFINDER_USE_MONOLITH_TWO_WAY, "pathfinder", "useMonolithTwoWay" }, {EGameSettings::PATHFINDER_USE_WHIRLPOOL, "pathfinder", "useWhirlpool" }, + {EGameSettings::RESOURCES_WEEKLY_BONUSES_AI, "resources", "weeklyBonusesAI" }, {EGameSettings::TEXTS_ARTIFACT, "textData", "artifact" }, {EGameSettings::TEXTS_CREATURE, "textData", "creature" }, {EGameSettings::TEXTS_FACTION, "textData", "faction" }, diff --git a/lib/IGameSettings.h b/lib/IGameSettings.h index 9922294af..0fcae51f5 100644 --- a/lib/IGameSettings.h +++ b/lib/IGameSettings.h @@ -67,6 +67,7 @@ enum class EGameSettings PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE, PATHFINDER_USE_MONOLITH_TWO_WAY, PATHFINDER_USE_WHIRLPOOL, + RESOURCES_WEEKLY_BONUSES_AI, TEXTS_ARTIFACT, TEXTS_CREATURE, TEXTS_FACTION, diff --git a/server/processors/NewTurnProcessor.cpp b/server/processors/NewTurnProcessor.cpp index dd94a0af5..b1eea0998 100644 --- a/server/processors/NewTurnProcessor.cpp +++ b/server/processors/NewTurnProcessor.cpp @@ -18,6 +18,7 @@ #include "../../lib/IGameSettings.h" #include "../../lib/StartInfo.h" #include "../../lib/TerrainHandler.h" +#include "../../lib/constants/StringConstants.h" #include "../../lib/entities/building/CBuilding.h" #include "../../lib/entities/faction/CTownHandler.h" #include "../../lib/gameState/CGameState.h" @@ -240,46 +241,22 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne if (!state.isHuman()) { // Initialize bonuses for different resources - std::array weeklyBonuses = {}; - - // Calculate weekly bonuses based on difficulty - if (gameHandler->gameState()->getStartInfo()->difficulty == 0) - { - weeklyBonuses[EGameResID::GOLD] = static_cast(std::round(incomeHandicapped[EGameResID::GOLD] * (0.75 - 1) * 7)); - } - else if (gameHandler->gameState()->getStartInfo()->difficulty == 3) - { - weeklyBonuses[EGameResID::GOLD] = static_cast(std::round(incomeHandicapped[EGameResID::GOLD] * 0.25 * 7)); - weeklyBonuses[EGameResID::WOOD] = static_cast(std::round(incomeHandicapped[EGameResID::WOOD] * 0.39 * 7)); - weeklyBonuses[EGameResID::ORE] = static_cast(std::round(incomeHandicapped[EGameResID::ORE] * 0.39 * 7)); - weeklyBonuses[EGameResID::MERCURY] = static_cast(std::round(incomeHandicapped[EGameResID::MERCURY] * 0.14 * 7)); - weeklyBonuses[EGameResID::CRYSTAL] = static_cast(std::round(incomeHandicapped[EGameResID::CRYSTAL] * 0.14 * 7)); - weeklyBonuses[EGameResID::SULFUR] = static_cast(std::round(incomeHandicapped[EGameResID::SULFUR] * 0.14 * 7)); - weeklyBonuses[EGameResID::GEMS] = static_cast(std::round(incomeHandicapped[EGameResID::GEMS] * 0.14 * 7)); - } - else if (gameHandler->gameState()->getStartInfo()->difficulty == 4) - { - weeklyBonuses[EGameResID::GOLD] = static_cast(std::round(incomeHandicapped[EGameResID::GOLD] * 0.5 * 7)); - weeklyBonuses[EGameResID::WOOD] = static_cast(std::round(incomeHandicapped[EGameResID::WOOD] * 0.53 * 7)); - weeklyBonuses[EGameResID::ORE] = static_cast(std::round(incomeHandicapped[EGameResID::ORE] * 0.53 * 7)); - weeklyBonuses[EGameResID::MERCURY] = static_cast(std::round(incomeHandicapped[EGameResID::MERCURY] * 0.28 * 7)); - weeklyBonuses[EGameResID::CRYSTAL] = static_cast(std::round(incomeHandicapped[EGameResID::CRYSTAL] * 0.28 * 7)); - weeklyBonuses[EGameResID::SULFUR] = static_cast(std::round(incomeHandicapped[EGameResID::SULFUR] * 0.28 * 7)); - weeklyBonuses[EGameResID::GEMS] = static_cast(std::round(incomeHandicapped[EGameResID::GEMS] * 0.28 * 7)); - } + int difficultyIndex = gameHandler->gameState()->getStartInfo()->difficulty; + const std::string & difficultyName = GameConstants::DIFFICULTY_NAMES[difficultyIndex]; + const JsonNode & weeklyBonusesConfig = gameHandler->gameState()->getSettings().getValue(EGameSettings::RESOURCES_WEEKLY_BONUSES_AI); + const JsonNode & difficultyConfig = weeklyBonusesConfig[difficultyName]; // Distribute weekly bonuses over 7 days, depending on the current day of the week - for (int i = 0; i < GameResID::COUNT; ++i) + for (GameResID i : GameResID::ALL_RESOURCES()) { - int dailyBonus = weeklyBonuses[i] / 7; - int remainderBonus = weeklyBonuses[i] % 7; - - // Apply the daily bonus for each day, and distribute the remainder accordingly - incomeHandicapped[static_cast(i)] += dailyBonus; - if (gameHandler->gameState()->getDate(Date::DAY_OF_WEEK) - 1 < remainderBonus) - { - incomeHandicapped[static_cast(i)] += 1; - } + const std::string & name = GameConstants::RESOURCE_NAMES[i]; + int weeklyBonus = difficultyConfig[name].Integer(); + int dayOfWeek = gameHandler->gameState()->getDate(Date::DAY_OF_WEEK); + int dailyIncome = incomeHandicapped[i]; + int amountTillToday = dailyIncome * weeklyBonus * (dayOfWeek-1) / 7 / 100; + int amountAfterToday = dailyIncome * weeklyBonus * dayOfWeek / 7 / 100; + int dailyBonusToday = amountAfterToday - amountTillToday; + incomeHandicapped[static_cast(i)] += dailyBonusToday; } }