diff --git a/config/difficulty.json b/config/difficulty.json new file mode 100644 index 000000000..97d7dbe0d --- /dev/null +++ b/config/difficulty.json @@ -0,0 +1,89 @@ +// Starting resources, ordered by difficulty level (0 to 4) +{ + "startres": + [ + { + "human": { "wood" : 30, "mercury": 15, "ore": 30, "sulfur": 15, "crystal": 15, "gems": 15, "gold": 30000, "mithril": 0 }, + "ai": { "wood" : 5, "mercury": 2, "ore": 5, "sulfur": 2, "crystal": 2, "gems": 2, "gold": 5000, "mithril": 0 } + }, + + { + "human": { "wood" : 20, "mercury": 10, "ore": 20, "sulfur": 10, "crystal": 10, "gems": 10, "gold": 20000, "mithril": 0 }, + "ai": { "wood" : 10, "mercury": 4, "ore": 10, "sulfur": 4, "crystal": 4, "gems": 4, "gold": 7500, "mithril": 0 } + }, + + { + "human": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 15000, "mithril": 0 }, + "ai": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 10000, "mithril": 0 } + }, + + { + "human": { "wood" : 10, "mercury": 4, "ore": 10, "sulfur": 4, "crystal": 4, "gems": 4, "gold": 10000, "mithril": 0 }, + "ai": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 10000, "mithril": 0 } + }, + + { + "human": { "wood" : 0, "mercury": 0, "ore": 0 , "sulfur": 0, "crystal": 0, "gems": 0, "gold": 0, "mithril": 0 }, + "ai": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 10000, "mithril": 0 } + } + ], + "battleBonus": + [ + { + }, + + { + "ai": + [ + { + "type" : "STACK_HEALTH", + "val" : 50, + "valueType" : "PERCENT_TO_ALL", + "duration" : "ONE_BATTLE", + "sourceType" : "OTHER" + } + ], + }, + + { + "ai": + [ + { + "type" : "STACK_HEALTH", + "val" : 100, + "valueType" : "PERCENT_TO_ALL", + "duration" : "ONE_BATTLE", + "sourceType" : "OTHER" + } + ], + }, + + { + "ai": + [ + { + "type" : "STACK_HEALTH", + "val" : 150, + "valueType" : "PERCENT_TO_ALL", + "duration" : "ONE_BATTLE", + "sourceType" : "OTHER" + }, + ], + }, + + { + "ai": + [ + { + "type" : "STACK_HEALTH", + "val" : 200, + "valueType" : "PERCENT_TO_ALL", + "duration" : "ONE_BATTLE", + "sourceType" : "OTHER" + }, + + ], + }, + ] +} + diff --git a/config/startres.json b/config/startres.json deleted file mode 100644 index dc96714e1..000000000 --- a/config/startres.json +++ /dev/null @@ -1,31 +0,0 @@ -// Starting resources, ordered by difficulty level (0 to 4) -{ - "difficulty": - [ - { - "human": { "wood" : 30, "mercury": 15, "ore": 30, "sulfur": 15, "crystal": 15, "gems": 15, "gold": 30000, "mithril": 0 }, - "ai": { "wood" : 5, "mercury": 2, "ore": 5, "sulfur": 2, "crystal": 2, "gems": 2, "gold": 5000, "mithril": 0 } - }, - - { - "human": { "wood" : 20, "mercury": 10, "ore": 20, "sulfur": 10, "crystal": 10, "gems": 10, "gold": 20000, "mithril": 0 }, - "ai": { "wood" : 10, "mercury": 4, "ore": 10, "sulfur": 4, "crystal": 4, "gems": 4, "gold": 7500, "mithril": 0 } - }, - - { - "human": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 15000, "mithril": 0 }, - "ai": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 10000, "mithril": 0 } - }, - - { - "human": { "wood" : 10, "mercury": 4, "ore": 10, "sulfur": 4, "crystal": 4, "gems": 4, "gold": 10000, "mithril": 0 }, - "ai": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 10000, "mithril": 0 } - }, - - { - "human": { "wood" : 0, "mercury": 0, "ore": 0 , "sulfur": 0, "crystal": 0, "gems": 0, "gold": 0, "mithril": 0 }, - "ai": { "wood" : 15, "mercury": 7, "ore": 15, "sulfur": 7, "crystal": 7, "gems": 7, "gold": 10000, "mithril": 0 } - } - ] -} - diff --git a/lib/CPlayerState.h b/lib/CPlayerState.h index ac8c1d4c6..b870359df 100644 --- a/lib/CPlayerState.h +++ b/lib/CPlayerState.h @@ -37,6 +37,7 @@ public: std::vector > towns; std::vector > dwellings; //used for town growth std::vector quests; //store info about all received quests + std::vector battleBonuses; //additional bonuses to be added during battle with neutrals bool enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory EPlayerStatus status; @@ -82,6 +83,7 @@ public: h & visitedObjects; h & status; h & daysWithoutCastle; + h & battleBonuses; h & enteredLosingCheatCode; h & enteredWinningCheatCode; h & static_cast(*this); diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index d51e36c66..3ceaf136d 100644 --- a/lib/gameState/CGameState.cpp +++ b/lib/gameState/CGameState.cpp @@ -450,6 +450,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog initPlayerStates(); if (campaign) campaign->placeCampaignHeroes(); + initBattleBonuses(); removeHeroPlaceholders(); initGrailPosition(); initRandomFactionsForPlayers(); @@ -657,6 +658,31 @@ void CGameState::initGlobalBonuses() VLC->creh->loadCrExpBon(globalEffects); } +void CGameState::initBattleBonuses() +{ + logGlobal->debug("\tLoading battle bonuses up resources"); + const JsonNode config(JsonPath::builtin("config/difficulty.json")); + const JsonVector &vector = config["battleBonus"].Vector(); + const JsonNode &level = vector[scenarioOps->difficulty]; + const JsonNode & bonusesAI(level["ai"]); + const JsonNode & bonusesHuman(level["human"]); + + for (auto & elem : players) + { + PlayerState &p = elem.second; + if(p.human) + { + for(auto & jsonBonus : bonusesHuman.Vector()) + p.battleBonuses.push_back(*JsonUtils::parseBonus(jsonBonus)); + } + else + { + for(auto & jsonBonus : bonusesAI.Vector()) + p.battleBonuses.push_back(*JsonUtils::parseBonus(jsonBonus)); + } + } +} + void CGameState::initGrailPosition() { logGlobal->debug("\tPicking grail position"); @@ -816,8 +842,8 @@ void CGameState::removeHeroPlaceholders() void CGameState::initStartingResources() { logGlobal->debug("\tSetting up resources"); - const JsonNode config(JsonPath::builtin("config/startres.json")); - const JsonVector &vector = config["difficulty"].Vector(); + const JsonNode config(JsonPath::builtin("config/difficulty.json")); + const JsonVector &vector = config["startres"].Vector(); const JsonNode &level = vector[scenarioOps->difficulty]; TResources startresAI(level["ai"]); diff --git a/lib/gameState/CGameState.h b/lib/gameState/CGameState.h index 63123b5d9..23c2f2803 100644 --- a/lib/gameState/CGameState.h +++ b/lib/gameState/CGameState.h @@ -184,6 +184,7 @@ private: void initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking); void checkMapChecksum(); void initGlobalBonuses(); + void initBattleBonuses(); void initGrailPosition(); void initRandomFactionsForPlayers(); void randomizeMapObjects(); diff --git a/server/battles/BattleProcessor.cpp b/server/battles/BattleProcessor.cpp index ea03a3433..19fd0426b 100644 --- a/server/battles/BattleProcessor.cpp +++ b/server/battles/BattleProcessor.cpp @@ -24,6 +24,7 @@ #include "../../lib/gameState/CGameState.h" #include "../../lib/mapping/CMap.h" #include "../../lib/modding/IdentifierStorage.h" +#include "../../lib/CPlayerState.h" BattleProcessor::BattleProcessor(CGameHandler * gameHandler) : gameHandler(gameHandler) @@ -113,6 +114,19 @@ void BattleProcessor::startBattlePrimary(const CArmedInstance *army1, const CArm const auto * battle = gameHandler->gameState()->getBattle(battleID); assert(battle); + + //add battle bonuses based from player state only when attacks neutral creatures + const auto * attackerInfo = gameHandler->getPlayerState(army1->getOwner(), false); + if(attackerInfo && army2->getOwner() == PlayerColor::NEUTRAL) + { + for(auto bonus : attackerInfo->battleBonuses) + { + GiveBonus giveBonus(GiveBonus::ETarget::HERO); + giveBonus.id = hero1->id.getNum(); + giveBonus.bonus = bonus; + gameHandler->sendAndApply(&giveBonus); + } + } auto lastBattleQuery = std::dynamic_pointer_cast(gameHandler->queries->topQuery(battle->sides[0].color));