From 713fcd65436e634a2b06e547975d1ba027dc125e Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 30 Sep 2024 02:40:28 +0200 Subject: [PATCH] research per day & seperate config --- client/windows/CCastleInterface.cpp | 21 ++++++++++----------- config/gameConfig.json | 18 ++++++++++++------ config/schemas/gameSettings.json | 6 +++--- lib/GameSettings.cpp | 4 ++-- lib/IGameSettings.h | 4 ++-- lib/mapObjects/CGTownInstance.cpp | 1 - lib/mapObjects/CGTownInstance.h | 4 ++-- lib/networkPacks/NetPacksLib.cpp | 2 +- server/CGameHandler.cpp | 13 ++++++------- 9 files changed, 38 insertions(+), 35 deletions(-) diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 53705a146..95c01ce58 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -2036,22 +2036,21 @@ void CMageGuildScreen::Scroll::clickPressed(const Point & cursorPosition) const CGTownInstance * town = LOCPLINT->cb->getTown(townId); if(LOCPLINT->cb->getSettings().getBoolean(EGameSettings::TOWNS_SPELL_RESEARCH) && town->spellResearchAllowed) { - int daysSinceLastResearch = LOCPLINT->cb->getDate(Date::DAY) - town->lastSpellResearchDay; - if(!daysSinceLastResearch) + int level = -1; + for(int i = 0; i < town->spells.size(); i++) + if(vstd::find_pos(town->spells[i], spell->id) != -1) + level = i; + + int today = LOCPLINT->cb->getDate(Date::DAY); + if(town->spellResearchActionsPerDay.find(today) == town->spellResearchActionsPerDay.end() || town->spellResearchActionsPerDay.at(today) >= LOCPLINT->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_PER_DAY).Vector()[level].Float()) { LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.spellResearch.comeAgain")); return; } - int level = -1; - for(int i = 0; i < town->spells.size(); i++) - if(vstd::find_pos(town->spells[i], spell->id) != -1) - level = i; - - auto costBase = TResources(LOCPLINT->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_BASE)); - auto costPerLevel = TResources(LOCPLINT->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_PER_LEVEL)); - auto costExponent = LOCPLINT->cb->getSettings().getDouble(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH); - auto cost = (costBase + costPerLevel * (level + 1)) * std::pow(town->spellResearchCounter + 1, costExponent); + auto costBase = TResources(LOCPLINT->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST).Vector()[level]); + auto costExponent = LOCPLINT->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH).Vector()[level].Float(); + auto cost = costBase * std::pow(town->spellResearchCounter + 1, costExponent); std::vector> resComps; resComps.push_back(std::make_shared(ComponentType::SPELL, town->spells[level].at(town->spellsAtLevel(level, false)))); diff --git a/config/gameConfig.json b/config/gameConfig.json index a2330ec2b..a7a80d2a0 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -314,12 +314,18 @@ "startingDwellingChances": [100, 50], // Enable spell research in mage guild "spellResearch": false, - // Base cost for an spell research - "spellResearchCostBase": { "gold": 1000 }, - // Costs depends on level for an spell research - "spellResearchCostPerLevel": { "wood" : 2, "mercury": 2, "ore": 2, "sulfur": 2, "crystal": 2, "gems": 2 }, - // Exponent for increasing cost for each research - "spellResearchCostExponentPerResearch": 1.25 + // Cost for an spell research (array index is spell tier) + "spellResearchCost": [ + { "gold": 1000, "wood" : 2, "mercury": 2, "ore": 2, "sulfur": 2, "crystal": 2, "gems": 2 }, + { "gold": 1000, "wood" : 4, "mercury": 4, "ore": 4, "sulfur": 4, "crystal": 4, "gems": 4 }, + { "gold": 1000, "wood" : 6, "mercury": 6, "ore": 6, "sulfur": 6, "crystal": 6, "gems": 6 }, + { "gold": 1000, "wood" : 8, "mercury": 8, "ore": 8, "sulfur": 8, "crystal": 8, "gems": 8 }, + { "gold": 1000, "wood" : 10, "mercury": 10, "ore": 10, "sulfur": 10, "crystal": 10, "gems": 10 } + ], + // How much researchs/skips per day are possible? (array index is spell tier) + "spellResearchPerDay": [ 2, 2, 2, 2, 1 ], + // Exponent for increasing cost for each research (factor 1 disables this; array index is spell tier) + "spellResearchCostExponentPerResearch": [ 1.25, 1.25, 1.25, 1.25, 1.25 ] }, "combat": diff --git a/config/schemas/gameSettings.json b/config/schemas/gameSettings.json index da113f7f1..6d0fd4670 100644 --- a/config/schemas/gameSettings.json +++ b/config/schemas/gameSettings.json @@ -54,9 +54,9 @@ "buildingsPerTurnCap" : { "type" : "number" }, "startingDwellingChances" : { "type" : "array" }, "spellResearch" : { "type" : "boolean" }, - "spellResearchCostBase" : { "type" : "object" }, - "spellResearchCostPerLevel" : { "type" : "object" }, - "spellResearchCostExponentPerResearch" : { "type" : "number" } + "spellResearchCost" : { "type" : "array" }, + "spellResearchPerDay" : { "type" : "array" }, + "spellResearchCostExponentPerResearch" : { "type" : "array" } } }, "combat": { diff --git a/lib/GameSettings.cpp b/lib/GameSettings.cpp index fee70455e..8ea0228b1 100644 --- a/lib/GameSettings.cpp +++ b/lib/GameSettings.cpp @@ -102,8 +102,8 @@ const std::vector GameSettings::settingProperties = {EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP, "towns", "buildingsPerTurnCap" }, {EGameSettings::TOWNS_STARTING_DWELLING_CHANCES, "towns", "startingDwellingChances" }, {EGameSettings::TOWNS_SPELL_RESEARCH, "towns", "spellResearch" }, - {EGameSettings::TOWNS_SPELL_RESEARCH_COST_BASE, "towns", "spellResearchCostBase" }, - {EGameSettings::TOWNS_SPELL_RESEARCH_COST_PER_LEVEL, "towns", "spellResearchCostPerLevel" }, + {EGameSettings::TOWNS_SPELL_RESEARCH_COST, "towns", "spellResearchCost" }, + {EGameSettings::TOWNS_SPELL_RESEARCH_PER_DAY, "towns", "spellResearchPerDay" }, {EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH, "towns", "spellResearchCostExponentPerResearch" }, }; diff --git a/lib/IGameSettings.h b/lib/IGameSettings.h index 12dc351c7..fdde0da27 100644 --- a/lib/IGameSettings.h +++ b/lib/IGameSettings.h @@ -80,8 +80,8 @@ enum class EGameSettings TOWNS_BUILDINGS_PER_TURN_CAP, TOWNS_STARTING_DWELLING_CHANCES, TOWNS_SPELL_RESEARCH, - TOWNS_SPELL_RESEARCH_COST_BASE, - TOWNS_SPELL_RESEARCH_COST_PER_LEVEL, + TOWNS_SPELL_RESEARCH_COST, + TOWNS_SPELL_RESEARCH_PER_DAY, TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH, OPTIONS_COUNT, diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index fbd2a76c6..76dc2a254 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -269,7 +269,6 @@ CGTownInstance::CGTownInstance(IGameCallback *cb): destroyed(0), identifier(0), alignmentToPlayer(PlayerColor::NEUTRAL), - lastSpellResearchDay(0), spellResearchCounter(0), spellResearchAllowed(true) { diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index fb5eb0af7..6e4bc7af3 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -73,7 +73,7 @@ public: std::vector > spells; //spells[level] -> vector of spells, first will be available in guild std::vector events; std::pair bonusValue;//var to store town bonuses (rampart = resources from mystic pond, factory = save debts); - int lastSpellResearchDay; + std::map spellResearchActionsPerDay; int spellResearchCounter; bool spellResearchAllowed; @@ -98,7 +98,7 @@ public: if (h.version >= Handler::Version::SPELL_RESEARCH) { - h & lastSpellResearchDay; + h & spellResearchActionsPerDay; h & spellResearchCounter; h & spellResearchAllowed; } diff --git a/lib/networkPacks/NetPacksLib.cpp b/lib/networkPacks/NetPacksLib.cpp index 785052430..fb37de483 100644 --- a/lib/networkPacks/NetPacksLib.cpp +++ b/lib/networkPacks/NetPacksLib.cpp @@ -944,7 +944,7 @@ void SetResearchedSpells::applyGs(CGameState *gs) CGTownInstance *town = gs->getTown(tid); town->spells[level] = spells; - town->lastSpellResearchDay = gs->getDate(Date::DAY); + town->spellResearchActionsPerDay[gs->getDate(Date::DAY)]++; if(accepted) town->spellResearchCounter++; } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index b295a897d..44fe7e06d 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2260,8 +2260,9 @@ bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot, bool auto spells = t->spells.at(level); - int daysSinceLastResearch = gs->getDate(Date::DAY) - t->lastSpellResearchDay; - if(!daysSinceLastResearch && complain("Already researched today!")) + int today = getDate(Date::DAY); + bool researchLimitExceeded = t->spellResearchActionsPerDay.find(today) == t->spellResearchActionsPerDay.end() || t->spellResearchActionsPerDay.at(today) >= getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_PER_DAY).Vector()[level].Float(); + if(researchLimitExceeded && complain("Already researched today!")) return false; if(!accepted) @@ -2272,11 +2273,9 @@ bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot, bool return true; } - auto costBase = TResources(getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_BASE)); - auto costPerLevel = TResources(getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_PER_LEVEL)); - auto costExponent = getSettings().getDouble(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH); - - auto cost = (costBase + costPerLevel * (level + 1)) * std::pow(t->spellResearchCounter + 1, costExponent); + auto costBase = TResources(getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST).Vector()[level]); + auto costExponent = getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH).Vector()[level].Float(); + auto cost = costBase * std::pow(t->spellResearchCounter + 1, costExponent); if(!getPlayerState(t->getOwner())->resources.canAfford(cost) && complain("Spell replacement cannot be afforded!")) return false;