diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index 5bfb3b8e8..edae26500 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -11,6 +11,7 @@ #include "CKingdomInterface.h" #include "CCastleInterface.h" +#include "CPlayerState.h" #include "InfoWindows.h" #include "../CGameInfo.h" @@ -577,9 +578,9 @@ void CKingdomInterface::generateMinesList(const std::vector heroes = LOCPLINT->cb->getHeroesInfo(true); - for(auto & heroe : heroes) + for(auto & hero : heroes) { - totalIncome += heroe->valOfBonuses(Selector::typeSubtype(BonusType::GENERATE_RESOURCE, BonusSubtypeID(GameResID(EGameResID::GOLD)))); + totalIncome += hero->valOfBonuses(Selector::typeSubtype(BonusType::GENERATE_RESOURCE, BonusSubtypeID(GameResID(EGameResID::GOLD)))); } //Add town income of all towns @@ -588,6 +589,11 @@ void CKingdomInterface::generateMinesList(const std::vectordailyIncome()[EGameResID::GOLD]; } + + //if player has some modded boosts we want to show that as well + totalIncome += LOCPLINT->cb->getPlayerState(LOCPLINT->playerID)->valOfBonuses(BonusType::RESOURCES_CONSTANT_BOOST, BonusSubtypeID(GameResID(EGameResID::GOLD))); + totalIncome += LOCPLINT->cb->getPlayerState(LOCPLINT->playerID)->valOfBonuses(BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST, BonusSubtypeID(GameResID(EGameResID::GOLD))) * towns.size(); + for(int i=0; i<7; i++) { std::string value = std::to_string(minesCount[i]); diff --git a/docs/modders/Bonus/Bonus_Types.md b/docs/modders/Bonus/Bonus_Types.md index 3e2540e2f..07872071c 100644 --- a/docs/modders/Bonus/Bonus_Types.md +++ b/docs/modders/Bonus/Bonus_Types.md @@ -33,6 +33,24 @@ On each turn, hides area in fog of war around affected town for all players othe - val: radius in tiles +# Player bonuses + +Intended to be setup as global effect, AI cheat etc. + +### RESOURCES_CONSTANT_BOOST + +Bonus that does not account for propagation and gives specific amount of extra resources per day + +- subtype: resource identifier +- val: - resource amount + +### RESOURCES_TOWN_MULTIPLYING_BOOST + +Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns + +- subtype: resource identifier +- val: - base resource amount to be multipled times number of owned towns + # Hero bonuses ### MOVEMENT diff --git a/lib/bonuses/BonusEnum.h b/lib/bonuses/BonusEnum.h index 328e286c0..524dcd9fd 100644 --- a/lib/bonuses/BonusEnum.h +++ b/lib/bonuses/BonusEnum.h @@ -176,6 +176,8 @@ class JsonNode; BONUS_NAME(FEROCITY) /*extra attacks, only if at least some creatures killed while attacking target unit, val = amount of additional attacks, additional info = amount of creatures killed to trigger (default 1)*/ \ BONUS_NAME(ENEMY_ATTACK_REDUCTION) /*in % (value) eg. Nix (HotA)*/ \ BONUS_NAME(REVENGE) /*additional damage based on how many units in stack died - formula: sqrt((number of creatures at battle start + 1) * creature health) / (total health now + 1 creature health) - 1) * 100% */ \ + BONUS_NAME(RESOURCES_CONSTANT_BOOST) /*Bonus that does not account for propagation and gives extra resources per day. val - resource amount, subtype - resource type*/ \ + BONUS_NAME(RESOURCES_TOWN_MULTIPLYING_BOOST) /*Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns. val - base resource amount to be multipled times number of owned towns, subtype - resource type*/ \ /* end of list */ diff --git a/lib/json/JsonBonus.cpp b/lib/json/JsonBonus.cpp index 1b89a7823..5eb43642b 100644 --- a/lib/json/JsonBonus.cpp +++ b/lib/json/JsonBonus.cpp @@ -151,6 +151,8 @@ static void loadBonusSubtype(BonusSubtypeID & subtype, BonusType type, const Jso break; } case BonusType::GENERATE_RESOURCE: + case BonusType::RESOURCES_CONSTANT_BOOST: + case BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST: { VLC->identifiers()->requestIdentifier( "resource", node, [&subtype](int32_t identifier) { diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index f7481887c..d89e77c33 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -751,25 +751,20 @@ void CGameHandler::onNewTurn() n.res[elem.first] = elem.second.resources; - if(!firstTurn && newWeek) //weekly crystal generation if 1 or more crystal dragons in any hero army or town garrison + if(!firstTurn) { - bool hasCrystalGenCreature = false; - for(CGHeroInstance * hero : elem.second.heroes) + for (GameResID k = GameResID::WOOD; k < GameResID::COUNT; k++) { - for(auto stack : hero->stacks) - { - if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION)) - { - hasCrystalGenCreature = true; - break; - } - } + n.res[elem.first][k] += elem.second.valOfBonuses(BonusType::RESOURCES_CONSTANT_BOOST, BonusSubtypeID(k)); + n.res[elem.first][k] += elem.second.valOfBonuses(BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST, BonusSubtypeID(k)) * elem.second.towns.size(); } - if(!hasCrystalGenCreature) //not found in armies, check towns + + if(newWeek) //weekly crystal generation if 1 or more crystal dragons in any hero army or town garrison { - for(CGTownInstance * town : elem.second.towns) + bool hasCrystalGenCreature = false; + for(CGHeroInstance * hero : elem.second.heroes) { - for(auto stack : town->stacks) + for(auto stack : hero->stacks) { if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION)) { @@ -778,9 +773,23 @@ void CGameHandler::onNewTurn() } } } + if(!hasCrystalGenCreature) //not found in armies, check towns + { + for(CGTownInstance * town : elem.second.towns) + { + for(auto stack : town->stacks) + { + if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION)) + { + hasCrystalGenCreature = true; + break; + } + } + } + } + if(hasCrystalGenCreature) + n.res[elem.first][EGameResID::CRYSTAL] += 3; } - if(hasCrystalGenCreature) - n.res[elem.first][EGameResID::CRYSTAL] += 3; } for (CGHeroInstance *h : (elem).second.heroes)