Browse Source

research per day & seperate config

Laserlicht 1 year ago
parent
commit
713fcd6543

+ 10 - 11
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)
-		{
-			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;
+				
+		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;
+		}
 
-		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<std::shared_ptr<CComponent>> resComps;
 		resComps.push_back(std::make_shared<CComponent>(ComponentType::SPELL, town->spells[level].at(town->spellsAtLevel(level, false))));

+ 12 - 6
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":

+ 3 - 3
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": {

+ 2 - 2
lib/GameSettings.cpp

@@ -102,8 +102,8 @@ const std::vector<GameSettings::SettingOption> 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" },
 	};
 

+ 2 - 2
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,

+ 0 - 1
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)
 {

+ 2 - 2
lib/mapObjects/CGTownInstance.h

@@ -73,7 +73,7 @@ public:
 	std::vector<std::vector<SpellID> > spells; //spells[level] -> vector of spells, first will be available in guild
 	std::vector<CCastleEvent> events;
 	std::pair<si32, si32> bonusValue;//var to store town bonuses (rampart = resources from mystic pond, factory = save debts);
-	int lastSpellResearchDay;
+	std::map<int, int> 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;
 		}

+ 1 - 1
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++;
 }

+ 6 - 7
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;