mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
new dialog
This commit is contained in:
parent
d929bfb9d1
commit
f94f0a3274
@ -61,7 +61,10 @@
|
||||
|
||||
"vcmi.spellResearch.canNotAfford" : "You can't afford to research a spell.",
|
||||
"vcmi.spellResearch.comeAgain" : "Research has already been done today. Come back tomorrow.",
|
||||
"vcmi.spellResearch.pay" : "Would you like to research this new spell and replace the old one?",
|
||||
"vcmi.spellResearch.pay" : "Would you like to research this new spell and replace the old one or skip this spell?",
|
||||
"vcmi.spellResearch.research" : "Research this Spell",
|
||||
"vcmi.spellResearch.skip" : "Skip this Spell",
|
||||
"vcmi.spellResearch.abort" : "Abort",
|
||||
|
||||
"vcmi.mainMenu.serverConnecting" : "Connecting...",
|
||||
"vcmi.mainMenu.serverAddressEnter" : "Enter address:",
|
||||
|
@ -60,7 +60,10 @@
|
||||
|
||||
"vcmi.spellResearch.canNotAfford" : "Ihr könnt es Euch nicht leisten, einen Zauberspruch zu erforschen.",
|
||||
"vcmi.spellResearch.comeAgain" : "Die Forschung wurde heute bereits abgeschlossen. Kommt morgen wieder.",
|
||||
"vcmi.spellResearch.pay" : "Möchtet Ihr diesen neuen Zauberspruch erforschen und den alten ersetzen?",
|
||||
"vcmi.spellResearch.pay" : "Möchtet Ihr diesen neuen Zauberspruch erforschen und den alten ersetzen oder diesen überspringen?",
|
||||
"vcmi.spellResearch.research" : "Erforsche diesen Zauberspruch",
|
||||
"vcmi.spellResearch.skip" : "Überspringe diesen Zauberspruch",
|
||||
"vcmi.spellResearch.abort" : "Abbruch",
|
||||
|
||||
"vcmi.mainMenu.serverConnecting" : "Verbinde...",
|
||||
"vcmi.mainMenu.serverAddressEnter" : "Addresse eingeben:",
|
||||
|
@ -2047,7 +2047,8 @@ void CMageGuildScreen::Scroll::clickPressed(const Point & cursorPosition)
|
||||
|
||||
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 cost = (costBase + costPerLevel * (level + 1)) * (town->spellResearchCounter + 1);
|
||||
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);
|
||||
|
||||
std::vector<std::shared_ptr<CComponent>> resComps;
|
||||
resComps.push_back(std::make_shared<CComponent>(ComponentType::SPELL, town->spells[level].at(town->spellsAtLevel(level, false))));
|
||||
@ -2057,10 +2058,28 @@ void CMageGuildScreen::Scroll::clickPressed(const Point & cursorPosition)
|
||||
resComps.push_back(std::make_shared<CComponent>(ComponentType::RESOURCE, i->resType, i->resVal, CComponent::ESize::medium));
|
||||
}
|
||||
|
||||
if(LOCPLINT->cb->getResourceAmount().canAfford(cost))
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.spellResearch.pay"), [this, town](){ LOCPLINT->cb->spellResearch(town, spell->id, true); }, nullptr, resComps);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.spellResearch.canNotAfford"), resComps);
|
||||
auto showSpellResearchDialog = [this, resComps, town, cost](){
|
||||
std::vector<std::pair<AnimationPath, CFunctionList<void()>>> pom;
|
||||
pom.emplace_back(AnimationPath::builtin("ibuy30.DEF"), nullptr);
|
||||
pom.emplace_back(AnimationPath::builtin("hsbtns4.DEF"), nullptr);
|
||||
pom.emplace_back(AnimationPath::builtin("ICANCEL.DEF"), nullptr);
|
||||
auto temp = std::make_shared<CInfoWindow>(CGI->generaltexth->translate("vcmi.spellResearch.pay"), LOCPLINT->playerID, resComps, pom);
|
||||
|
||||
temp->buttons[0]->addCallback([this, resComps, town, cost](){
|
||||
if(LOCPLINT->cb->getResourceAmount().canAfford(cost))
|
||||
LOCPLINT->cb->spellResearch(town, spell->id, true);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.spellResearch.canNotAfford"), resComps);
|
||||
});
|
||||
temp->buttons[0]->addPopupCallback([](){ CRClickPopup::createAndPush(CGI->generaltexth->translate("vcmi.spellResearch.research")); });
|
||||
temp->buttons[1]->addCallback([this, town](){ LOCPLINT->cb->spellResearch(town, spell->id, false); });
|
||||
temp->buttons[1]->addPopupCallback([](){ CRClickPopup::createAndPush(CGI->generaltexth->translate("vcmi.spellResearch.skip")); });
|
||||
temp->buttons[2]->addPopupCallback([](){ CRClickPopup::createAndPush(CGI->generaltexth->translate("vcmi.spellResearch.abort")); });
|
||||
|
||||
GH.windows().pushWindow(temp);
|
||||
};
|
||||
|
||||
showSpellResearchDialog();
|
||||
}
|
||||
else
|
||||
LOCPLINT->showInfoDialog(spell->getDescriptionTranslated(0), std::make_shared<CComponent>(ComponentType::SPELL, spell->id));
|
||||
|
@ -318,8 +318,8 @@
|
||||
"spellResearchCostBase": { "gold": 1000 },
|
||||
// Costs depends on level for an spell research
|
||||
"spellResearchCostPerLevel": { "wood" : 2, "mercury": 2, "ore": 2, "sulfur": 2, "crystal": 2, "gems": 2 },
|
||||
// Factor for increasing cost for each research
|
||||
"spellResearchCostFactorPerResearch": 2.0
|
||||
// Exponent for increasing cost for each research
|
||||
"spellResearchCostExponentPerResearch": 1.5
|
||||
},
|
||||
|
||||
"combat":
|
||||
|
@ -51,12 +51,12 @@
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"buildingsPerTurnCap" : { "type" : "number" },
|
||||
"startingDwellingChances" : { "type" : "array" },
|
||||
"spellResearch" : { "type" : "boolean" },
|
||||
"spellResearchCostBase" : { "type" : "object" },
|
||||
"spellResearchCostPerLevel" : { "type" : "object" },
|
||||
"spellResearchCostFactorPerResearch" : { "type" : "number" }
|
||||
"buildingsPerTurnCap" : { "type" : "number" },
|
||||
"startingDwellingChances" : { "type" : "array" },
|
||||
"spellResearch" : { "type" : "boolean" },
|
||||
"spellResearchCostBase" : { "type" : "object" },
|
||||
"spellResearchCostPerLevel" : { "type" : "object" },
|
||||
"spellResearchCostExponentPerResearch" : { "type" : "number" }
|
||||
}
|
||||
},
|
||||
"combat": {
|
||||
|
@ -37,74 +37,74 @@ GameSettings::GameSettings() = default;
|
||||
GameSettings::~GameSettings() = default;
|
||||
|
||||
const std::vector<GameSettings::SettingOption> GameSettings::settingProperties = {
|
||||
{EGameSettings::BANKS_SHOW_GUARDS_COMPOSITION, "banks", "showGuardsComposition" },
|
||||
{EGameSettings::BONUSES_GLOBAL, "bonuses", "global" },
|
||||
{EGameSettings::BONUSES_PER_HERO, "bonuses", "perHero" },
|
||||
{EGameSettings::COMBAT_AREA_SHOT_CAN_TARGET_EMPTY_HEX, "combat", "areaShotCanTargetEmptyHex" },
|
||||
{EGameSettings::COMBAT_ATTACK_POINT_DAMAGE_FACTOR, "combat", "attackPointDamageFactor" },
|
||||
{EGameSettings::COMBAT_ATTACK_POINT_DAMAGE_FACTOR_CAP, "combat", "attackPointDamageFactorCap" },
|
||||
{EGameSettings::COMBAT_BAD_LUCK_DICE, "combat", "badLuckDice" },
|
||||
{EGameSettings::COMBAT_BAD_MORALE_DICE, "combat", "badMoraleDice" },
|
||||
{EGameSettings::COMBAT_DEFENSE_POINT_DAMAGE_FACTOR, "combat", "defensePointDamageFactor" },
|
||||
{EGameSettings::COMBAT_DEFENSE_POINT_DAMAGE_FACTOR_CAP, "combat", "defensePointDamageFactorCap" },
|
||||
{EGameSettings::COMBAT_GOOD_LUCK_DICE, "combat", "goodLuckDice" },
|
||||
{EGameSettings::COMBAT_GOOD_MORALE_DICE, "combat", "goodMoraleDice" },
|
||||
{EGameSettings::COMBAT_LAYOUTS, "combat", "layouts" },
|
||||
{EGameSettings::COMBAT_ONE_HEX_TRIGGERS_OBSTACLES, "combat", "oneHexTriggersObstacles" },
|
||||
{EGameSettings::CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH, "creatures", "allowAllForDoubleMonth" },
|
||||
{EGameSettings::CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS, "creatures", "allowRandomSpecialWeeks" },
|
||||
{EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE, "creatures", "dailyStackExperience" },
|
||||
{EGameSettings::CREATURES_WEEKLY_GROWTH_CAP, "creatures", "weeklyGrowthCap" },
|
||||
{EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT, "creatures", "weeklyGrowthPercent" },
|
||||
{EGameSettings::DIMENSION_DOOR_EXPOSES_TERRAIN_TYPE, "spells", "dimensionDoorExposesTerrainType" },
|
||||
{EGameSettings::DIMENSION_DOOR_FAILURE_SPENDS_POINTS, "spells", "dimensionDoorFailureSpendsPoints" },
|
||||
{EGameSettings::DIMENSION_DOOR_ONLY_TO_UNCOVERED_TILES, "spells", "dimensionDoorOnlyToUncoveredTiles" },
|
||||
{EGameSettings::DIMENSION_DOOR_TOURNAMENT_RULES_LIMIT, "spells", "dimensionDoorTournamentRulesLimit" },
|
||||
{EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS, "spells", "dimensionDoorTriggersGuards" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL, "dwellings", "accumulateWhenNeutral" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED, "dwellings", "accumulateWhenOwned" },
|
||||
{EGameSettings::DWELLINGS_MERGE_ON_RECRUIT, "dwellings", "mergeOnRecruit" },
|
||||
{EGameSettings::HEROES_BACKPACK_CAP, "heroes", "backpackSize" },
|
||||
{EGameSettings::HEROES_MINIMAL_PRIMARY_SKILLS, "heroes", "minimalPrimarySkills" },
|
||||
{EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP, "heroes", "perPlayerOnMapCap" },
|
||||
{EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP, "heroes", "perPlayerTotalCap" },
|
||||
{EGameSettings::HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, "heroes", "retreatOnWinWithoutTroops" },
|
||||
{EGameSettings::HEROES_STARTING_STACKS_CHANCES, "heroes", "startingStackChances" },
|
||||
{EGameSettings::HEROES_TAVERN_INVITE, "heroes", "tavernInvite" },
|
||||
{EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE, "mapFormat", "armageddonsBlade" },
|
||||
{EGameSettings::MAP_FORMAT_CHRONICLES, "mapFormat", "chronicles" },
|
||||
{EGameSettings::MAP_FORMAT_HORN_OF_THE_ABYSS, "mapFormat", "hornOfTheAbyss" },
|
||||
{EGameSettings::MAP_FORMAT_IN_THE_WAKE_OF_GODS, "mapFormat", "inTheWakeOfGods" },
|
||||
{EGameSettings::MAP_FORMAT_JSON_VCMI, "mapFormat", "jsonVCMI" },
|
||||
{EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA, "mapFormat", "restorationOfErathia" },
|
||||
{EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH, "mapFormat", "shadowOfDeath" },
|
||||
{EGameSettings::MARKETS_BLACK_MARKET_RESTOCK_PERIOD, "markets", "blackMarketRestockPeriod" },
|
||||
{EGameSettings::MODULE_COMMANDERS, "modules", "commanders" },
|
||||
{EGameSettings::MODULE_STACK_ARTIFACT, "modules", "stackArtifact" },
|
||||
{EGameSettings::MODULE_STACK_EXPERIENCE, "modules", "stackExperience" },
|
||||
{EGameSettings::PATHFINDER_IGNORE_GUARDS, "pathfinder", "ignoreGuards" },
|
||||
{EGameSettings::PATHFINDER_ORIGINAL_FLY_RULES, "pathfinder", "originalFlyRules" },
|
||||
{EGameSettings::PATHFINDER_USE_BOAT, "pathfinder", "useBoat" },
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_RANDOM, "pathfinder", "useMonolithOneWayRandom" },
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE, "pathfinder", "useMonolithOneWayUnique" },
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_TWO_WAY, "pathfinder", "useMonolithTwoWay" },
|
||||
{EGameSettings::PATHFINDER_USE_WHIRLPOOL, "pathfinder", "useWhirlpool" },
|
||||
{EGameSettings::TEXTS_ARTIFACT, "textData", "artifact" },
|
||||
{EGameSettings::TEXTS_CREATURE, "textData", "creature" },
|
||||
{EGameSettings::TEXTS_FACTION, "textData", "faction" },
|
||||
{EGameSettings::TEXTS_HERO, "textData", "hero" },
|
||||
{EGameSettings::TEXTS_HERO_CLASS, "textData", "heroClass" },
|
||||
{EGameSettings::TEXTS_OBJECT, "textData", "object" },
|
||||
{EGameSettings::TEXTS_RIVER, "textData", "river" },
|
||||
{EGameSettings::TEXTS_ROAD, "textData", "road" },
|
||||
{EGameSettings::TEXTS_SPELL, "textData", "spell" },
|
||||
{EGameSettings::TEXTS_TERRAIN, "textData", "terrain" },
|
||||
{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_FACTOR_PER_RESEARCH, "towns", "spellResearchCostFactorPerResearch" },
|
||||
{EGameSettings::BANKS_SHOW_GUARDS_COMPOSITION, "banks", "showGuardsComposition" },
|
||||
{EGameSettings::BONUSES_GLOBAL, "bonuses", "global" },
|
||||
{EGameSettings::BONUSES_PER_HERO, "bonuses", "perHero" },
|
||||
{EGameSettings::COMBAT_AREA_SHOT_CAN_TARGET_EMPTY_HEX, "combat", "areaShotCanTargetEmptyHex" },
|
||||
{EGameSettings::COMBAT_ATTACK_POINT_DAMAGE_FACTOR, "combat", "attackPointDamageFactor" },
|
||||
{EGameSettings::COMBAT_ATTACK_POINT_DAMAGE_FACTOR_CAP, "combat", "attackPointDamageFactorCap" },
|
||||
{EGameSettings::COMBAT_BAD_LUCK_DICE, "combat", "badLuckDice" },
|
||||
{EGameSettings::COMBAT_BAD_MORALE_DICE, "combat", "badMoraleDice" },
|
||||
{EGameSettings::COMBAT_DEFENSE_POINT_DAMAGE_FACTOR, "combat", "defensePointDamageFactor" },
|
||||
{EGameSettings::COMBAT_DEFENSE_POINT_DAMAGE_FACTOR_CAP, "combat", "defensePointDamageFactorCap" },
|
||||
{EGameSettings::COMBAT_GOOD_LUCK_DICE, "combat", "goodLuckDice" },
|
||||
{EGameSettings::COMBAT_GOOD_MORALE_DICE, "combat", "goodMoraleDice" },
|
||||
{EGameSettings::COMBAT_LAYOUTS, "combat", "layouts" },
|
||||
{EGameSettings::COMBAT_ONE_HEX_TRIGGERS_OBSTACLES, "combat", "oneHexTriggersObstacles" },
|
||||
{EGameSettings::CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH, "creatures", "allowAllForDoubleMonth" },
|
||||
{EGameSettings::CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS, "creatures", "allowRandomSpecialWeeks" },
|
||||
{EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE, "creatures", "dailyStackExperience" },
|
||||
{EGameSettings::CREATURES_WEEKLY_GROWTH_CAP, "creatures", "weeklyGrowthCap" },
|
||||
{EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT, "creatures", "weeklyGrowthPercent" },
|
||||
{EGameSettings::DIMENSION_DOOR_EXPOSES_TERRAIN_TYPE, "spells", "dimensionDoorExposesTerrainType" },
|
||||
{EGameSettings::DIMENSION_DOOR_FAILURE_SPENDS_POINTS, "spells", "dimensionDoorFailureSpendsPoints" },
|
||||
{EGameSettings::DIMENSION_DOOR_ONLY_TO_UNCOVERED_TILES, "spells", "dimensionDoorOnlyToUncoveredTiles" },
|
||||
{EGameSettings::DIMENSION_DOOR_TOURNAMENT_RULES_LIMIT, "spells", "dimensionDoorTournamentRulesLimit" },
|
||||
{EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS, "spells", "dimensionDoorTriggersGuards" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL, "dwellings", "accumulateWhenNeutral" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED, "dwellings", "accumulateWhenOwned" },
|
||||
{EGameSettings::DWELLINGS_MERGE_ON_RECRUIT, "dwellings", "mergeOnRecruit" },
|
||||
{EGameSettings::HEROES_BACKPACK_CAP, "heroes", "backpackSize" },
|
||||
{EGameSettings::HEROES_MINIMAL_PRIMARY_SKILLS, "heroes", "minimalPrimarySkills" },
|
||||
{EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP, "heroes", "perPlayerOnMapCap" },
|
||||
{EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP, "heroes", "perPlayerTotalCap" },
|
||||
{EGameSettings::HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, "heroes", "retreatOnWinWithoutTroops" },
|
||||
{EGameSettings::HEROES_STARTING_STACKS_CHANCES, "heroes", "startingStackChances" },
|
||||
{EGameSettings::HEROES_TAVERN_INVITE, "heroes", "tavernInvite" },
|
||||
{EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE, "mapFormat", "armageddonsBlade" },
|
||||
{EGameSettings::MAP_FORMAT_CHRONICLES, "mapFormat", "chronicles" },
|
||||
{EGameSettings::MAP_FORMAT_HORN_OF_THE_ABYSS, "mapFormat", "hornOfTheAbyss" },
|
||||
{EGameSettings::MAP_FORMAT_IN_THE_WAKE_OF_GODS, "mapFormat", "inTheWakeOfGods" },
|
||||
{EGameSettings::MAP_FORMAT_JSON_VCMI, "mapFormat", "jsonVCMI" },
|
||||
{EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA, "mapFormat", "restorationOfErathia" },
|
||||
{EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH, "mapFormat", "shadowOfDeath" },
|
||||
{EGameSettings::MARKETS_BLACK_MARKET_RESTOCK_PERIOD, "markets", "blackMarketRestockPeriod" },
|
||||
{EGameSettings::MODULE_COMMANDERS, "modules", "commanders" },
|
||||
{EGameSettings::MODULE_STACK_ARTIFACT, "modules", "stackArtifact" },
|
||||
{EGameSettings::MODULE_STACK_EXPERIENCE, "modules", "stackExperience" },
|
||||
{EGameSettings::PATHFINDER_IGNORE_GUARDS, "pathfinder", "ignoreGuards" },
|
||||
{EGameSettings::PATHFINDER_ORIGINAL_FLY_RULES, "pathfinder", "originalFlyRules" },
|
||||
{EGameSettings::PATHFINDER_USE_BOAT, "pathfinder", "useBoat" },
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_RANDOM, "pathfinder", "useMonolithOneWayRandom" },
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE, "pathfinder", "useMonolithOneWayUnique" },
|
||||
{EGameSettings::PATHFINDER_USE_MONOLITH_TWO_WAY, "pathfinder", "useMonolithTwoWay" },
|
||||
{EGameSettings::PATHFINDER_USE_WHIRLPOOL, "pathfinder", "useWhirlpool" },
|
||||
{EGameSettings::TEXTS_ARTIFACT, "textData", "artifact" },
|
||||
{EGameSettings::TEXTS_CREATURE, "textData", "creature" },
|
||||
{EGameSettings::TEXTS_FACTION, "textData", "faction" },
|
||||
{EGameSettings::TEXTS_HERO, "textData", "hero" },
|
||||
{EGameSettings::TEXTS_HERO_CLASS, "textData", "heroClass" },
|
||||
{EGameSettings::TEXTS_OBJECT, "textData", "object" },
|
||||
{EGameSettings::TEXTS_RIVER, "textData", "river" },
|
||||
{EGameSettings::TEXTS_ROAD, "textData", "road" },
|
||||
{EGameSettings::TEXTS_SPELL, "textData", "spell" },
|
||||
{EGameSettings::TEXTS_TERRAIN, "textData", "terrain" },
|
||||
{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_EXPONENT_PER_RESEARCH, "towns", "spellResearchCostExponentPerResearch" },
|
||||
};
|
||||
|
||||
void GameSettings::loadBase(const JsonNode & input)
|
||||
|
@ -82,7 +82,7 @@ enum class EGameSettings
|
||||
TOWNS_SPELL_RESEARCH,
|
||||
TOWNS_SPELL_RESEARCH_COST_BASE,
|
||||
TOWNS_SPELL_RESEARCH_COST_PER_LEVEL,
|
||||
TOWNS_SPELL_RESEARCH_COST_FACTOR_PER_RESEARCH,
|
||||
TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH,
|
||||
|
||||
OPTIONS_COUNT,
|
||||
OPTIONS_BEGIN = BONUSES_GLOBAL
|
||||
|
@ -310,7 +310,7 @@ struct DLL_LINKAGE SpellResearch : public CPackForServer
|
||||
{
|
||||
SpellResearch() = default;
|
||||
SpellResearch(const ObjectInstanceID & TID, SpellID spellAtSlot, bool accepted)
|
||||
: tid(TID), spellAtSlot(spellAtSlot)
|
||||
: tid(TID), spellAtSlot(spellAtSlot), accepted(accepted)
|
||||
{
|
||||
}
|
||||
ObjectInstanceID tid;
|
||||
|
@ -2257,22 +2257,32 @@ bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot, bool
|
||||
|
||||
if(level == -1 && complain("Spell for replacement not found!"))
|
||||
return false;
|
||||
|
||||
auto spells = t->spells.at(level);
|
||||
|
||||
int daysSinceLastResearch = gs->getDate(Date::DAY) - t->lastSpellResearchDay;
|
||||
if(!daysSinceLastResearch && complain("Already researched today!"))
|
||||
return false;
|
||||
|
||||
if(!accepted)
|
||||
{
|
||||
auto it = spells.begin() + t->spellsAtLevel(level, false);
|
||||
std::rotate(it, it + 1, spells.end()); // move to end
|
||||
setResearchedSpells(t, level, spells, accepted);
|
||||
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 cost = (costBase + costPerLevel * (level + 1)) * (t->spellResearchCounter + 1);
|
||||
auto costExponent = getSettings().getDouble(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH);
|
||||
|
||||
auto cost = (costBase + costPerLevel * (level + 1)) * std::pow(t->spellResearchCounter + 1, costExponent);
|
||||
|
||||
if(!getPlayerState(t->getOwner())->resources.canAfford(cost) && complain("Spell replacement cannot be afforded!"))
|
||||
return false;
|
||||
|
||||
giveResources(t->getOwner(), -cost);
|
||||
|
||||
auto spells = t->spells.at(level);
|
||||
|
||||
std::swap(spells.at(t->spellsAtLevel(level, false)), spells.at(vstd::find_pos(spells, spellAtSlot)));
|
||||
auto it = spells.begin() + t->spellsAtLevel(level, false);
|
||||
std::rotate(it, it + 1, spells.end()); // move to end
|
||||
|
Loading…
Reference in New Issue
Block a user