mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge pull request #1693 from IvanSavenko/game_settings_overrides
Game settings overrides
This commit is contained in:
commit
ecbbbeda9b
@ -13,7 +13,7 @@
|
||||
#include "../../lib/mapObjects/MapObjects.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/CGameState.h"
|
||||
#include "../../lib/NetPacks.h"
|
||||
#include "../../lib/serializer/CTypeList.h"
|
||||
@ -1072,7 +1072,7 @@ bool AIGateway::canRecruitAnyHero(const CGTownInstance * t) const
|
||||
return false;
|
||||
if(cb->getHeroesInfo().size() >= ALLOWED_ROAMING_HEROES)
|
||||
return false;
|
||||
if(cb->getHeroesInfo().size() >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)
|
||||
if(cb->getHeroesInfo().size() >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP))
|
||||
return false;
|
||||
if(!cb->getAvailableHeroes(t).size())
|
||||
return false;
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "../../lib/mapObjects/MapObjects.h"
|
||||
#include "../../lib/mapping/CMapDefines.h"
|
||||
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
|
||||
namespace NKAI
|
||||
{
|
||||
@ -445,7 +445,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
|
||||
case Obj::MAGIC_WELL:
|
||||
return h->mana < h->manaLimit();
|
||||
case Obj::PRISON:
|
||||
return ai->cb->getHeroesInfo().size() < VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER;
|
||||
return ai->cb->getHeroesInfo().size() < VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP);
|
||||
case Obj::TAVERN:
|
||||
case Obj::EYE_OF_MAGI:
|
||||
case Obj::BOAT:
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "../../lib/mapObjects/MapObjects.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/CGameState.h"
|
||||
#include "../../lib/NetPacksBase.h"
|
||||
#include "../../lib/NetPacks.h"
|
||||
@ -1318,7 +1318,7 @@ bool VCAI::canRecruitAnyHero(const CGTownInstance * t) const
|
||||
return false;
|
||||
if(cb->getHeroesInfo().size() >= ALLOWED_ROAMING_HEROES)
|
||||
return false;
|
||||
if(cb->getHeroesInfo().size() >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)
|
||||
if(cb->getHeroesInfo().size() >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP))
|
||||
return false;
|
||||
if(!cb->getAvailableHeroes(t).size())
|
||||
return false;
|
||||
@ -2851,12 +2851,12 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
||||
case Obj::MAGIC_WELL:
|
||||
return h->mana < h->manaLimit();
|
||||
case Obj::PRISON:
|
||||
return ai->myCb->getHeroesInfo().size() < VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER;
|
||||
return ai->myCb->getHeroesInfo().size() < VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP);
|
||||
case Obj::TAVERN:
|
||||
{
|
||||
//TODO: make AI actually recruit heroes
|
||||
//TODO: only on request
|
||||
if(ai->myCb->getHeroesInfo().size() >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)
|
||||
if(ai->myCb->getHeroesInfo().size() >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP))
|
||||
return false;
|
||||
else if(ai->ah->freeGold() < GameConstants::HERO_GOLD_COST)
|
||||
return false;
|
||||
|
@ -55,6 +55,7 @@
|
||||
"author" : "Abel Rivas",
|
||||
"modType" : "Gráfico",
|
||||
|
||||
"skipValidation" : true,
|
||||
"translations" : [
|
||||
"config/vcmi/spanish.json"
|
||||
]
|
||||
|
@ -94,6 +94,11 @@ const ObstacleService * CGameInfo::obstacles() const
|
||||
return globalServices->obstacles();
|
||||
}
|
||||
|
||||
const IGameSettings * CGameInfo::settings() const
|
||||
{
|
||||
return globalServices->settings();
|
||||
}
|
||||
|
||||
void CGameInfo::updateEntity(Metatype metatype, int32_t index, const JsonNode & data)
|
||||
{
|
||||
logGlobal->error("CGameInfo::updateEntity call is not expected.");
|
||||
|
@ -71,13 +71,13 @@ public:
|
||||
const SkillService * skills() const override;
|
||||
const BattleFieldService * battlefields() const override;
|
||||
const ObstacleService * obstacles() const override;
|
||||
const IGameSettings * settings() const override;
|
||||
|
||||
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
||||
|
||||
const spells::effects::Registry * spellEffects() const override;
|
||||
spells::effects::Registry * spellEffects() override;
|
||||
|
||||
|
||||
ConstTransitivePtr<CModHandler> modh; //public?
|
||||
ConstTransitivePtr<BattleFieldHandler> battleFieldHandler;
|
||||
ConstTransitivePtr<CHeroHandler> heroh;
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "../lib/mapping/CMapInfo.h"
|
||||
#include "../lib/mapObjects/MiscObjects.h"
|
||||
#include "../lib/rmg/CMapGenOptions.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "../lib/serializer/CMemorySerializer.h"
|
||||
|
@ -10,30 +10,27 @@
|
||||
#include "StdInc.h"
|
||||
#include "Client.h"
|
||||
|
||||
#include "../CCallback.h"
|
||||
#include "adventureMap/CAdvMapInt.h"
|
||||
#include "mapView/mapHandler.h"
|
||||
#include "CGameInfo.h"
|
||||
#include "../lib/CGameState.h"
|
||||
#include "CPlayerInterface.h"
|
||||
#include "../lib/StartInfo.h"
|
||||
#include "../lib/battle/BattleInfo.h"
|
||||
#include "../lib/serializer/CTypeList.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "ClientNetPackVisitors.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
#include "../lib/mapping/CMap.h"
|
||||
#include "../lib/mapping/CMapService.h"
|
||||
#include "../lib/JsonNode.h"
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "battle/BattleInterface.h"
|
||||
#include "../lib/CThreadHelper.h"
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "gui/CGuiHandler.h"
|
||||
#include "CServerHandler.h"
|
||||
#include "serializer/BinaryDeserializer.h"
|
||||
#include "ClientNetPackVisitors.h"
|
||||
#include "adventureMap/CAdvMapInt.h"
|
||||
#include "battle/BattleInterface.h"
|
||||
#include "gui/CGuiHandler.h"
|
||||
#include "mapView/mapHandler.h"
|
||||
|
||||
#include "../CCallback.h"
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "../lib/CGameState.h"
|
||||
#include "../lib/CThreadHelper.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
#include "../lib/battle/BattleInfo.h"
|
||||
#include "../lib/serializer/BinaryDeserializer.h"
|
||||
#include "../lib/mapping/CMapService.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
#include "../lib/registerTypes/RegisterTypes.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
|
||||
#include <vcmi/events/EventBus.h>
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "render/CAnimation.h"
|
||||
#include "../CCallback.h"
|
||||
#include "../lib/CGeneralTextHandler.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
#include "../lib/CHeroHandler.h"
|
||||
#include "../lib/CModHandler.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
@ -283,7 +284,7 @@ std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
|
||||
|
||||
void CTownList::CTownItem::update()
|
||||
{
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||
|
||||
picture->setFrame(iconIndex + 2);
|
||||
redraw();
|
||||
|
@ -232,5 +232,6 @@ void CMinimap::updateTile(const int3 &pos)
|
||||
{
|
||||
if(minimap)
|
||||
minimap->refreshTile(pos);
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "../../lib/rmg/CMapGenOptions.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/rmg/CRmgTemplateStorage.h"
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
#include "../../lib/RoadHandler.h"
|
||||
|
||||
RandomMapTab::RandomMapTab():
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "../../lib/NetPacksLobby.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
#include "../../lib/mapping/CMapInfo.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
@ -538,7 +539,7 @@ void SelectionTab::parseMaps(const std::unordered_set<ResourceID> & files)
|
||||
|
||||
// ignore unsupported map versions (e.g. WoG maps without WoG)
|
||||
// but accept VCMI maps
|
||||
if((mapInfo->mapHeader->version >= EMapFormat::VCMI) || (mapInfo->mapHeader->version <= CGI->modh->settings.data["textData"]["mapVersion"].Float()))
|
||||
if((mapInfo->mapHeader->version >= EMapFormat::VCMI) || (mapInfo->mapHeader->version <= CGI->settings()->getInteger(EGameSettings::TEXTS_MAP_VERSION)))
|
||||
allItems.push_back(mapInfo);
|
||||
}
|
||||
catch(std::exception & e)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../../lib/TextOperations.h"
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
#include "../../lib/vcmi_endian.h"
|
||||
#include "../../lib/VCMI_Lib.h"
|
||||
|
||||
#include <SDL_surface.h>
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "../../lib/CGameState.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/TextOperations.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
@ -328,7 +329,7 @@ void CTownTooltip::init(const InfoAboutTown & town)
|
||||
|
||||
assert(town.tType);
|
||||
|
||||
size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
|
||||
size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||
|
||||
build = std::make_shared<CAnimImage>("itpt", iconIndex, 0, 3, 2);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "../../lib/CCreatureHandler.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/spells/CSpellHandler.h"
|
||||
#include "../../lib/CTownHandler.h"
|
||||
#include "../../lib/GameConstants.h"
|
||||
@ -407,7 +408,7 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
|
||||
bool allow = true;
|
||||
if(upg) //moving hero out of town - check if it is allowed
|
||||
{
|
||||
if(!hero && LOCPLINT->cb->howManyHeroes(false) >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)
|
||||
if(!hero && LOCPLINT->cb->howManyHeroes(false) >= CGI->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP))
|
||||
{
|
||||
std::string tmp = CGI->generaltexth->allTexts[18]; //You already have %d adventuring heroes under your command.
|
||||
boost::algorithm::replace_first(tmp,"%d",std::to_string(LOCPLINT->cb->howManyHeroes(false)));
|
||||
@ -1269,7 +1270,7 @@ void CCastleInterface::removeBuilding(BuildingID bid)
|
||||
void CCastleInterface::recreateIcons()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||
|
||||
icon->setFrame(iconIndex);
|
||||
TResources townIncome = town->dailyIncome();
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "../../lib/CBonusTypeHandler.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CGameState.h"
|
||||
#include "../../lib/TextOperations.h"
|
||||
@ -777,8 +778,8 @@ void CStackWindow::initSections()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
|
||||
bool showArt = CGI->modh->modules.STACK_ARTIFACT && info->commander == nullptr && info->stackNode;
|
||||
bool showExp = (CGI->modh->modules.STACK_EXP || info->commander != nullptr) && info->stackNode;
|
||||
bool showArt = CGI->settings()->getBoolean(EGameSettings::MODULE_STACK_ARTIFACT) && info->commander == nullptr && info->stackNode;
|
||||
bool showExp = (CGI->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE) || info->commander != nullptr) && info->stackNode;
|
||||
|
||||
mainSection = std::make_shared<MainSection>(this, pos.h, showExp, showArt);
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CModHandler.h"
|
||||
#include "../../lib/GameSettings.h"
|
||||
#include "../../lib/CSkillHandler.h"
|
||||
#include "../../lib/CTownHandler.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
@ -778,7 +779,7 @@ CTownItem::CTownItem(const CGTownInstance * Town)
|
||||
garr = std::make_shared<CGarrisonInt>(313, 3, 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, true);
|
||||
heroes = std::make_shared<HeroSlots>(town, Point(244,6), Point(475,6), garr, false);
|
||||
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||
|
||||
picture = std::make_shared<CAnimImage>("ITPT", iconIndex, 0, 5, 6);
|
||||
openTown = std::make_shared<LRClickableAreaOpenTown>(Rect(5, 6, 58, 64), town);
|
||||
|
@ -52,9 +52,11 @@
|
||||
#include "../lib/CGeneralTextHandler.h"
|
||||
#include "../lib/CHeroHandler.h"
|
||||
#include "../lib/CModHandler.h"
|
||||
#include "../lib/GameSettings.h"
|
||||
#include "../lib/CondSh.h"
|
||||
#include "../lib/CSkillHandler.h"
|
||||
#include "../lib/spells/CSpellHandler.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
#include "../lib/CStopWatch.h"
|
||||
#include "../lib/CTownHandler.h"
|
||||
#include "../lib/GameConstants.h"
|
||||
@ -466,13 +468,13 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj)
|
||||
recruit->addHoverText(CButton::NORMAL, CGI->generaltexth->tavernInfo[0]); //Cannot afford a Hero
|
||||
recruit->block(true);
|
||||
}
|
||||
else if(LOCPLINT->cb->howManyHeroes(true) >= VLC->modh->settings.MAX_HEROES_AVAILABLE_PER_PLAYER)
|
||||
else if(LOCPLINT->cb->howManyHeroes(true) >= CGI->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP))
|
||||
{
|
||||
//Cannot recruit. You already have %d Heroes.
|
||||
recruit->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->tavernInfo[1]) % LOCPLINT->cb->howManyHeroes(true)));
|
||||
recruit->block(true);
|
||||
}
|
||||
else if(LOCPLINT->cb->howManyHeroes(false) >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)
|
||||
else if(LOCPLINT->cb->howManyHeroes(false) >= CGI->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP))
|
||||
{
|
||||
//Cannot recruit. You already have %d Heroes.
|
||||
recruit->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->tavernInfo[1]) % LOCPLINT->cb->howManyHeroes(false)));
|
||||
|
@ -182,6 +182,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/CThreadHelper.cpp
|
||||
${MAIN_LIB_DIR}/CTownHandler.cpp
|
||||
${MAIN_LIB_DIR}/GameConstants.cpp
|
||||
${MAIN_LIB_DIR}/GameSettings.cpp
|
||||
${MAIN_LIB_DIR}/HeroBonus.cpp
|
||||
${MAIN_LIB_DIR}/IGameCallback.cpp
|
||||
${MAIN_LIB_DIR}/IHandlerBase.cpp
|
||||
@ -426,6 +427,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/CTownHandler.h
|
||||
${MAIN_LIB_DIR}/FunctionList.h
|
||||
${MAIN_LIB_DIR}/GameConstants.h
|
||||
${MAIN_LIB_DIR}/GameSettings.h
|
||||
${MAIN_LIB_DIR}/HeroBonus.h
|
||||
${MAIN_LIB_DIR}/IBonusTypeHandler.h
|
||||
${MAIN_LIB_DIR}/IGameCallback.h
|
||||
|
@ -1,102 +0,0 @@
|
||||
// default configuration for mod system loaded at launch
|
||||
|
||||
{
|
||||
"textData" :
|
||||
{
|
||||
"heroClass" : 18,
|
||||
"artifact" : 144,
|
||||
"creature" : 150,
|
||||
"faction" : 9,
|
||||
"hero" : 156,
|
||||
"spell" : 81,
|
||||
"object" : 256,
|
||||
"terrain" : 10,
|
||||
"river" : 5,
|
||||
"road" : 4,
|
||||
"mapVersion" : 28 // max supported version, SoD
|
||||
},
|
||||
|
||||
"hardcodedFeatures" :
|
||||
{
|
||||
"CREEP_SIZE": 4000,
|
||||
"WEEKLY_GROWTH_PERCENT" : 10,
|
||||
"NEUTRAL_STACK_EXP_DAILY" : 500,
|
||||
"MAX_BUILDING_PER_TURN" : 1,
|
||||
"DWELLINGS_ACCUMULATE_CREATURES" : false,
|
||||
"ALL_CREATURES_GET_DOUBLE_MONTHS" : false,
|
||||
"NEGATIVE_LUCK" : false,
|
||||
"MAX_HEROES_AVAILABLE_PER_PLAYER" : 16,
|
||||
"MAX_HEROES_ON_MAP_PER_PLAYER" : 8,
|
||||
"WINNING_HERO_WITH_NO_TROOPS_RETREATS": true,
|
||||
"BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE": true,
|
||||
"NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS": false,
|
||||
"ATTACK_POINT_DMG_MULTIPLIER": 0.05, //every 1 attack point damage influence in battle when attack points > defense points during creature attack
|
||||
"ATTACK_POINTS_DMG_MULTIPLIER_CAP": 4.0, //limit of damage increase that can be achieved by overpowering attack points
|
||||
"DEFENSE_POINT_DMG_MULTIPLIER": 0.025, //every 1 defense point damage influence in battle when defense points > attack points during creature attack
|
||||
"DEFENSE_POINTS_DMG_MULTIPLIER_CAP": 0.7, //limit of damage reduction that can be achieved by overpowering defense points
|
||||
//chances for new hero units count - technically random number 1-100, first element in list below generated number sets count, if none then result is number of elements + 1
|
||||
"HERO_STARTING_ARMY_STACKS_COUNT_CHANCES": [10, 80], //example: [10,80] gives 10% chance for 1 stack, 70% for 2, 20% for 3. Additionally you can add -1 as last special value to start counting from 0 and allowing empty armies
|
||||
"DEFAULT_BUILDING_SET_DWELLING_CHANCES": [100, 50] //percent chance for dwellings to appear - for example [30,10,0,100] means 30% chance for 1st level dwelling, 10% for 2nd, 0% for 3rd, and guaranteed 4th level, no 5th, no 6th, no 7th
|
||||
},
|
||||
"modules":
|
||||
{
|
||||
"STACK_EXPERIENCE": false,
|
||||
"STACK_ARTIFACTS": false,
|
||||
"COMMANDERS": false,
|
||||
"MITHRIL": false //so far unused
|
||||
},
|
||||
"baseBonuses" : [
|
||||
{
|
||||
"type" : "SPELL_DAMAGE", //Default spell damage
|
||||
"val" : 100,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"type" : "MAX_LEARNABLE_SPELL_LEVEL", //Hero can always learn level 1 and 2 spells
|
||||
"val" : 2,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"heroBaseBonuses":
|
||||
[
|
||||
{
|
||||
"type" : "MANA_REGENERATION", //default mana regeneration
|
||||
"val" : 1,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"type" : "SIGHT_RADIUS", //default sight radius
|
||||
"val" : 5,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"type" : "HERO_EXPERIENCE_GAIN_PERCENT", //default hero xp
|
||||
"val" : 100,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"type" : "MANA_PER_KNOWLEDGE", //10 knowledge to 100 mana is default
|
||||
"val" : 10,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
{
|
||||
"type" : "MOVEMENT", //Basic land movement
|
||||
"subtype" : 1,
|
||||
"val" : 1300,
|
||||
"valueType" : "BASE_NUMBER",
|
||||
"updater" : {
|
||||
"type" : "ARMY_MOVEMENT", //Enable army movement bonus
|
||||
"parameters" : [20, //Movement points for lowest speed numerator
|
||||
3, //Movement points for lowest speed denominator
|
||||
10, //Resulting improper fraction will be multiplied by this number
|
||||
700] //All army movement bonus cannot be higher than this value (so, max movement will be 1300 + 700 for this settings)
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "MOVEMENT", //Basic sea movement
|
||||
"subtype" : 0,
|
||||
"val" : 1500,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
]
|
||||
}
|
@ -104,5 +104,172 @@
|
||||
"obstacles":
|
||||
[
|
||||
"config/obstacles.json"
|
||||
]
|
||||
],
|
||||
|
||||
"settings":
|
||||
{
|
||||
// Number of entries of each type to load from Heroes III text files
|
||||
"textData" :
|
||||
{
|
||||
"heroClass" : 18,
|
||||
"artifact" : 144,
|
||||
"creature" : 150,
|
||||
"faction" : 9,
|
||||
"hero" : 156,
|
||||
"spell" : 81,
|
||||
"object" : 256,
|
||||
"terrain" : 10,
|
||||
"river" : 5,
|
||||
"road" : 4,
|
||||
"mapVersion" : 28 // max supported version, SoD
|
||||
},
|
||||
|
||||
"heroes" :
|
||||
{
|
||||
// number of heroes that player can have active on map at the same time
|
||||
"perPlayerOnMapCap" : 8,
|
||||
// number of heroes that player can have in total, including garrisoned
|
||||
"perPlayerTotalCap" : 16,
|
||||
// if enabled, hero that wins a battle without any non-summoned troops left will retreat and become available in tavern instead of being lost
|
||||
"retreatOnWinWithoutTroops" : true,
|
||||
// Chances for a hero with default army to receive corresponding stack out of his predefined starting troops
|
||||
"startingStackChances": [ 100, 88, 25]
|
||||
},
|
||||
|
||||
"towns":
|
||||
{
|
||||
// How many new building can be built in a town per day
|
||||
"buildingsPerTurnCap" : 1,
|
||||
// Chances for a town with default buildings to receive corresponding dwelling level built in start
|
||||
"startingDwellingChances": [100, 50]
|
||||
},
|
||||
|
||||
"combat":
|
||||
{
|
||||
// defines dice size of a morale roll, based on creature's morale.
|
||||
// Resulting chance is 1/(value). If list contains 0 values, option will be disabled
|
||||
"goodMoraleDice" : [ 24, 12, 8 ],
|
||||
"badMoraleDice" : [ 12, 6, 4],
|
||||
|
||||
// defines dice size of a luck roll, based on creature's luck
|
||||
"goodLuckDice" : [ 24, 12, 8 ],
|
||||
"badLuckDice" : [],
|
||||
|
||||
// every 1 attack point damage influence in battle when attack points > defense points during creature attack
|
||||
"attackPointDamageFactor": 0.05,
|
||||
// limit of damage increase that can be achieved by overpowering attack points
|
||||
"attackPointDamageFactorCap": 4.0,
|
||||
// every 1 defense point damage influence in battle when defense points > attack points during creature attack
|
||||
"defensePointDamageFactor": 0.025,
|
||||
// limit of damage reduction that can be achieved by overpowering defense points
|
||||
"defensePointDamageFactorCap": 0.7
|
||||
},
|
||||
|
||||
"creatures":
|
||||
{
|
||||
// creatures on map will grow by specified percentage each week
|
||||
"weeklyGrowthPercent" : 10,
|
||||
// creatures on map will not grow if their quantity is greater than this value
|
||||
"weeklyGrowthCap" : 4000,
|
||||
// if stack experience is on, creatures on map will get specified amount of experience daily
|
||||
"dailyStackExperience" : 100,
|
||||
// if enabled, double growth, plague and creature weeks can happen randomly. Has no effect on weeks by "Deity of Fire"
|
||||
"allowRandomSpecialWeeks" : true,
|
||||
// if enabled, every creature can get double growth month, ignoring predefined list
|
||||
"allowAllForDoubleMonth" : false
|
||||
},
|
||||
|
||||
"dwellings" :
|
||||
{
|
||||
// if enabled, neutral dwellings will accumulate creatures
|
||||
"accumulateWhenNeutral" : false,
|
||||
// if enabled, dwellings owned by players will accumulate creatures
|
||||
"accumulateWhenOwned" : false
|
||||
},
|
||||
|
||||
"markets" :
|
||||
{
|
||||
// period between restocking of "Black Market" object found on adventure map
|
||||
"blackMarketRestockPeriod" : 0
|
||||
},
|
||||
|
||||
"modules":
|
||||
{
|
||||
// if enabled, creatures may collect experience (WoG feature)
|
||||
"stackExperience": false,
|
||||
// if enabled, certain artifacts can be granted to creatures (WoG feature)
|
||||
"stackArtifact": false,
|
||||
// if enabled, all heroes gain commander creature in battle (WoG feature)
|
||||
"commanders": false
|
||||
},
|
||||
|
||||
"bonuses" :
|
||||
{
|
||||
"global" :
|
||||
{
|
||||
"spellDamage" :
|
||||
{
|
||||
"type" : "SPELL_DAMAGE",
|
||||
"val" : 100,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"wisdom" :
|
||||
{
|
||||
"type" : "MAX_LEARNABLE_SPELL_LEVEL", //Hero can always learn level 1 and 2 spells
|
||||
"val" : 2,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
},
|
||||
"perHero":
|
||||
{
|
||||
"manaRegeneration" :
|
||||
{
|
||||
"type" : "MANA_REGENERATION", //default mana regeneration
|
||||
"val" : 1,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"sightRadius" :
|
||||
{
|
||||
"type" : "SIGHT_RADIUS", //default sight radius
|
||||
"val" : 5,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"experienceGain" :
|
||||
{
|
||||
"type" : "HERO_EXPERIENCE_GAIN_PERCENT", //default hero xp
|
||||
"val" : 100,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"manaPerKnowledge" :
|
||||
{
|
||||
"type" : "MANA_PER_KNOWLEDGE", //10 mana per knowledge
|
||||
"val" : 10,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"landMovement" :
|
||||
{
|
||||
"type" : "MOVEMENT", //Basic land movement
|
||||
"subtype" : 1,
|
||||
"val" : 1300,
|
||||
"valueType" : "BASE_NUMBER",
|
||||
"updater" : {
|
||||
"type" : "ARMY_MOVEMENT", //Enable army movement bonus
|
||||
"parameters" : [
|
||||
20, // Movement points for lowest speed numerator
|
||||
3, // Movement points for lowest speed denominator
|
||||
10, // Resulting value, rounded down, will be multiplied by this number
|
||||
700 // All army movement bonus cannot be higher than this value (so, max movement will be 1300 + 700 for this settings)
|
||||
]
|
||||
}
|
||||
},
|
||||
"seaMovement" :
|
||||
{
|
||||
"type" : "MOVEMENT", //Basic sea movement
|
||||
"subtype" : 0,
|
||||
"val" : 1500,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@
|
||||
"language" : {
|
||||
"type":"string",
|
||||
"description": "Base language of the mod, before applying localizations. By default vcmi assumes English",
|
||||
"enum" : [ "chinese", "english", "korean", "german", "polish", "russian", "ukrainian" ],
|
||||
"enum" : [ "chinese", "english", "korean", "german", "polish", "russian", "spanish", "ukrainian" ],
|
||||
},
|
||||
"depends": {
|
||||
"type":"array",
|
||||
@ -143,6 +143,9 @@
|
||||
"russian" : {
|
||||
"$ref" : "#/definitions/localizable"
|
||||
},
|
||||
"spanish" : {
|
||||
"$ref" : "#/definitions/localizable"
|
||||
},
|
||||
"ukrainian" : {
|
||||
"$ref" : "#/definitions/localizable"
|
||||
},
|
||||
@ -243,6 +246,17 @@
|
||||
"items" : { "type":"string" }
|
||||
}
|
||||
},
|
||||
|
||||
"settings" : {
|
||||
"type":"object",
|
||||
"description": "List of changed game settings by mod",
|
||||
"additionalProperties" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"type" : "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"filesystem": {
|
||||
"type":"object",
|
||||
|
@ -64,12 +64,12 @@
|
||||
},
|
||||
"language" : {
|
||||
"type":"string",
|
||||
"enum" : [ "chinese", "english", "german", "polish", "russian", "ukrainian" ],
|
||||
"enum" : [ "chinese", "english", "german", "polish", "russian", "spanish", "ukrainian" ],
|
||||
"default" : "english"
|
||||
},
|
||||
"gameDataLanguage" : {
|
||||
"type":"string",
|
||||
"enum" : [ "auto", "chinese", "english", "german", "korean", "polish", "russian", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
|
||||
"enum" : [ "auto", "chinese", "english", "german", "korean", "polish", "russian", "spanish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
|
||||
"default" : "auto"
|
||||
},
|
||||
"lastSave" : {
|
||||
|
@ -23,6 +23,7 @@ class SkillService;
|
||||
class JsonNode;
|
||||
class BattleFieldService;
|
||||
class ObstacleService;
|
||||
class IGameSettings;
|
||||
|
||||
namespace spells
|
||||
{
|
||||
@ -58,6 +59,7 @@ public:
|
||||
virtual const SkillService * skills() const = 0;
|
||||
virtual const BattleFieldService * battlefields() const = 0;
|
||||
virtual const ObstacleService * obstacles() const = 0;
|
||||
virtual const IGameSettings * settings() const = 0;
|
||||
|
||||
virtual void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) = 0;
|
||||
|
||||
|
@ -56,7 +56,9 @@ set(launcher_TS
|
||||
translation/german.ts
|
||||
translation/polish.ts
|
||||
translation/russian.ts
|
||||
translation/ukrainian.ts)
|
||||
translation/spanish.ts
|
||||
translation/ukrainian.ts
|
||||
)
|
||||
|
||||
if(APPLE_IOS)
|
||||
list(APPEND launcher_SRCS
|
||||
|
@ -41,7 +41,7 @@ BattleFieldInfo * BattleFieldHandler::loadFromJson(const std::string & scope, co
|
||||
return info;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> BattleFieldHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> BattleFieldHandler::loadLegacyData()
|
||||
{
|
||||
return std::vector<JsonNode>();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
size_t index) override;
|
||||
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "VCMI_Lib.h"
|
||||
#include "CModHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "CCreatureHandler.h"
|
||||
#include "spells/CSpellHandler.h"
|
||||
#include "mapObjects/MapObjects.h"
|
||||
@ -219,8 +220,10 @@ void CGrowingArtifact::levelUpArtifact (CArtifactInstance * art)
|
||||
|
||||
CArtHandler::~CArtHandler() = default;
|
||||
|
||||
std::vector<JsonNode> CArtHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CArtHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_ARTIFACT);
|
||||
|
||||
objects.resize(dataSize);
|
||||
std::vector<JsonNode> h3Data;
|
||||
h3Data.reserve(dataSize);
|
||||
@ -300,7 +303,7 @@ CArtifact * CArtHandler::loadFromJson(const std::string & scope, const JsonNode
|
||||
|
||||
CArtifact * art = nullptr;
|
||||
|
||||
if(!VLC->modh->modules.COMMANDERS || node["growing"].isNull())
|
||||
if(!VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS) || node["growing"].isNull())
|
||||
{
|
||||
art = new CArtifact();
|
||||
}
|
||||
@ -604,12 +607,23 @@ bool CArtHandler::legalArtifact(const ArtifactID & id)
|
||||
{
|
||||
auto art = objects[id];
|
||||
//assert ( (!art->constituents) || art->constituents->size() ); //artifacts is not combined or has some components
|
||||
return ((!art->possibleSlots[ArtBearer::HERO].empty() ||
|
||||
(!art->possibleSlots[ArtBearer::COMMANDER].empty() && VLC->modh->modules.COMMANDERS) ||
|
||||
(!art->possibleSlots[ArtBearer::CREATURE].empty() && VLC->modh->modules.STACK_ARTIFACT)) &&
|
||||
!(art->constituents) && //no combo artifacts spawning
|
||||
art->aClass >= CArtifact::ART_TREASURE &&
|
||||
art->aClass <= CArtifact::ART_RELIC);
|
||||
|
||||
if(art->constituents)
|
||||
return false; //no combo artifacts spawning
|
||||
|
||||
if(art->aClass < CArtifact::ART_TREASURE || art->aClass > CArtifact::ART_RELIC)
|
||||
return false; // invalid class
|
||||
|
||||
if(!art->possibleSlots[ArtBearer::HERO].empty())
|
||||
return true;
|
||||
|
||||
if(!art->possibleSlots[ArtBearer::CREATURE].empty() && VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_ARTIFACT))
|
||||
return true;
|
||||
|
||||
if(!art->possibleSlots[ArtBearer::COMMANDER].empty() && VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CArtHandler::initAllowedArtifactsList(const std::vector<bool> &allowed)
|
||||
|
@ -261,7 +261,7 @@ public:
|
||||
|
||||
~CArtHandler();
|
||||
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "CGameState.h"
|
||||
#include "CTownHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "StringConstants.h"
|
||||
#include "serializer/JsonDeserializer.h"
|
||||
#include "serializer/JsonUpdater.h"
|
||||
@ -512,8 +513,10 @@ void CCreatureHandler::loadBonuses(JsonNode & creature, std::string bonuses) con
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<JsonNode> CCreatureHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CCreatureHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_CREATURE);
|
||||
|
||||
objects.resize(dataSize);
|
||||
std::vector<JsonNode> h3Data;
|
||||
h3Data.reserve(dataSize);
|
||||
@ -677,7 +680,7 @@ std::vector<bool> CCreatureHandler::getDefaultAllowed() const
|
||||
|
||||
void CCreatureHandler::loadCrExpBon()
|
||||
{
|
||||
if (VLC->modh->modules.STACK_EXP) //reading default stack experience bonuses
|
||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE)) //reading default stack experience bonuses
|
||||
{
|
||||
CLegacyConfigParser parser("DATA/CREXPBON.TXT");
|
||||
|
||||
@ -793,7 +796,7 @@ void CCreatureHandler::loadAnimationInfo(std::vector<JsonNode> &h3Data) const
|
||||
parser.endLine(); // header
|
||||
parser.endLine();
|
||||
|
||||
for(int dd=0; dd<VLC->modh->settings.data["textData"]["creature"].Float(); ++dd)
|
||||
for(int dd = 0; dd < VLC->settings()->getInteger(EGameSettings::TEXTS_CREATURE); ++dd)
|
||||
{
|
||||
while (parser.isNextEntryEmpty() && parser.endLine()) // skip empty lines
|
||||
;
|
||||
|
@ -317,7 +317,7 @@ public:
|
||||
|
||||
void afterLoadFinalization() override;
|
||||
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "CCreatureHandler.h"
|
||||
#include "VCMI_Lib.h"
|
||||
#include "CModHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "mapObjects/CGHeroInstance.h"
|
||||
#include "IGameCallback.h"
|
||||
#include "CGameState.h"
|
||||
@ -421,7 +422,7 @@ void CCreatureSet::setStackCount(const SlotID & slot, TQuantity count)
|
||||
{
|
||||
assert(hasStackAtSlot(slot));
|
||||
assert(stacks[slot]->count + count > 0);
|
||||
if (VLC->modh->modules.STACK_EXP && count > stacks[slot]->count)
|
||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE) && count > stacks[slot]->count)
|
||||
stacks[slot]->experience = static_cast<TExpType>(stacks[slot]->experience * (count / static_cast<double>(stacks[slot]->count)));
|
||||
stacks[slot]->count = count;
|
||||
armyChanged();
|
||||
@ -703,7 +704,7 @@ CCreature::CreatureQuantityId CStackInstance::getQuantityID() const
|
||||
|
||||
int CStackInstance::getExpRank() const
|
||||
{
|
||||
if (!VLC->modh->modules.STACK_EXP)
|
||||
if (!VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
return 0;
|
||||
int tier = type->level;
|
||||
if (vstd::iswithin(tier, 1, 7))
|
||||
@ -765,7 +766,7 @@ void CStackInstance::setType(const CCreature *c)
|
||||
if(type)
|
||||
{
|
||||
detachFrom(const_cast<CCreature&>(*type));
|
||||
if (type->isMyUpgrade(c) && VLC->modh->modules.STACK_EXP)
|
||||
if (type->isMyUpgrade(c) && VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
experience = static_cast<TExpType>(experience * VLC->creh->expAfterUpgrade / 100.0);
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "battle/BattleInfo.h" // for BattleInfo
|
||||
#include "NetPacks.h" // for InfoWindow
|
||||
#include "CModHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "TerrainHandler.h"
|
||||
#include "spells/CSpellHandler.h"
|
||||
#include "mapping/CMap.h"
|
||||
@ -603,7 +604,7 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
|
||||
if (!t->genBuildingRequirements(ID).test(buildTest))
|
||||
return EBuildingState::PREREQUIRES;
|
||||
|
||||
if(t->builded >= VLC->modh->settings.MAX_BUILDING_PER_TURN)
|
||||
if(t->builded >= VLC->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP))
|
||||
return EBuildingState::CANT_BUILD_TODAY; //building limit
|
||||
|
||||
//checking resources
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "CHeroHandler.h"
|
||||
#include "mapObjects/CObjectHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "TerrainHandler.h"
|
||||
#include "CSkillHandler.h"
|
||||
#include "mapping/CMap.h"
|
||||
@ -948,11 +949,11 @@ void CGameState::checkMapChecksum()
|
||||
|
||||
void CGameState::initGlobalBonuses()
|
||||
{
|
||||
const JsonNode & baseBonuses = VLC->modh->settings.data["baseBonuses"];
|
||||
const JsonNode & baseBonuses = VLC->settings()->getValue(EGameSettings::BONUSES_GLOBAL);
|
||||
logGlobal->debug("\tLoading global bonuses");
|
||||
for(const auto & b : baseBonuses.Vector())
|
||||
for(const auto & b : baseBonuses.Struct())
|
||||
{
|
||||
auto bonus = JsonUtils::parseBonus(b);
|
||||
auto bonus = JsonUtils::parseBonus(b.second);
|
||||
bonus->source = Bonus::GLOBAL;//for all
|
||||
bonus->sid = -1; //there is one global object
|
||||
globalEffects.addNewBonus(bonus);
|
||||
@ -1747,7 +1748,7 @@ void CGameState::initTowns()
|
||||
if(vti->tempOwner != PlayerColor::NEUTRAL)
|
||||
vti->builtBuildings.insert(BuildingID::TAVERN);
|
||||
|
||||
auto definesBuildingsChances = VLC->modh->settings.DEFAULT_BUILDING_SET_DWELLING_CHANCES;
|
||||
auto definesBuildingsChances = VLC->settings()->getVector(EGameSettings::TOWNS_STARTING_DWELLING_CHANCES);
|
||||
|
||||
BuildingID basicDwellings[] = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7 };
|
||||
|
||||
|
@ -52,7 +52,9 @@ public:
|
||||
{
|
||||
std::vector<si32> primskills;
|
||||
si32 mana, manaLimit, luck, morale;
|
||||
} *details;
|
||||
};
|
||||
|
||||
Details * details = nullptr;
|
||||
|
||||
const CHeroClass *hclass;
|
||||
int portrait;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "filesystem/Filesystem.h"
|
||||
#include "CConfigHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "mapObjects/CQuest.h"
|
||||
#include "VCMI_Lib.h"
|
||||
#include "Languages.h"
|
||||
@ -555,7 +556,7 @@ CGeneralTextHandler::CGeneralTextHandler():
|
||||
scenariosCountPerCampaign.push_back(region);
|
||||
}
|
||||
}
|
||||
if (VLC->modh->modules.COMMANDERS)
|
||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS))
|
||||
{
|
||||
if(CResourceHandler::get()->existsResource(ResourceID("DATA/ZNPC00.TXT", EResType::TEXT)))
|
||||
readToVector("vcmi.znpc00", "DATA/ZNPC00.TXT" );
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "StringConstants.h"
|
||||
#include "battle/BattleHex.h"
|
||||
#include "CCreatureHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "CModHandler.h"
|
||||
#include "CTownHandler.h"
|
||||
#include "mapObjects/CObjectHandler.h" //for hero specialty
|
||||
@ -309,8 +310,10 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js
|
||||
return heroClass;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> CHeroClassHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CHeroClassHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_HERO_CLASS);
|
||||
|
||||
objects.resize(dataSize);
|
||||
std::vector<JsonNode> h3Data;
|
||||
h3Data.reserve(dataSize);
|
||||
@ -777,8 +780,10 @@ static std::string genRefName(std::string input)
|
||||
return input;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> CHeroHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CHeroHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_HERO);
|
||||
|
||||
objects.resize(dataSize);
|
||||
std::vector<JsonNode> h3Data;
|
||||
h3Data.reserve(dataSize);
|
||||
|
@ -223,7 +223,7 @@ class DLL_LINKAGE CHeroClassHandler : public CHandlerBase<HeroClassID, HeroClass
|
||||
void fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill) const;
|
||||
|
||||
public:
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
void afterLoadFinalization() override;
|
||||
|
||||
@ -264,7 +264,7 @@ public:
|
||||
ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount
|
||||
ui64 reqExp(ui32 level) const; //calculates experience required for given level
|
||||
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
void beforeValidate(JsonNode & object) override;
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "filesystem/FileStream.h"
|
||||
#include "filesystem/AdapterLoaders.h"
|
||||
#include "filesystem/CFilesystemLoader.h"
|
||||
#include "filesystem/Filesystem.h"
|
||||
|
||||
#include "CCreatureHandler.h"
|
||||
#include "CArtHandler.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "Languages.h"
|
||||
#include "ScriptHandler.h"
|
||||
#include "RoadHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "RiverHandler.h"
|
||||
#include "TerrainHandler.h"
|
||||
#include "BattleFieldHandler.h"
|
||||
@ -343,7 +345,7 @@ void CIdentifierStorage::finalize()
|
||||
ContentTypeHandler::ContentTypeHandler(IHandlerBase * handler, const std::string & objectName):
|
||||
handler(handler),
|
||||
objectName(objectName),
|
||||
originalData(handler->loadLegacyData(static_cast<size_t>(VLC->modh->settings.data["textData"][objectName].Float())))
|
||||
originalData(handler->loadLegacyData())
|
||||
{
|
||||
for(auto & node : originalData)
|
||||
{
|
||||
@ -729,10 +731,6 @@ void CModInfo::setEnabled(bool on)
|
||||
|
||||
CModHandler::CModHandler() : content(std::make_shared<CContentHandler>())
|
||||
{
|
||||
modules.COMMANDERS = false;
|
||||
modules.STACK_ARTIFACT = false;
|
||||
modules.STACK_EXP = false;
|
||||
modules.MITHRIL = false;
|
||||
for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)
|
||||
{
|
||||
identifiers.registerObject(CModHandler::scopeBuiltin(), "resource", GameConstants::RESOURCE_NAMES[i], i);
|
||||
@ -745,72 +743,6 @@ CModHandler::CModHandler() : content(std::make_shared<CContentHandler>())
|
||||
}
|
||||
}
|
||||
|
||||
void CModHandler::loadConfigFromFile(const std::string & name)
|
||||
{
|
||||
std::string paths;
|
||||
for(const auto & p : CResourceHandler::get()->getResourceNames(ResourceID("config/" + name)))
|
||||
{
|
||||
paths += p.string() + ", ";
|
||||
}
|
||||
paths = paths.substr(0, paths.size() - 2);
|
||||
logMod->debug("Loading hardcoded features settings from [%s], result:", paths);
|
||||
settings.data = JsonUtils::assembleFromFiles("config/" + name);
|
||||
const JsonNode & hardcodedFeatures = settings.data["hardcodedFeatures"];
|
||||
settings.MAX_HEROES_AVAILABLE_PER_PLAYER = static_cast<int>(hardcodedFeatures["MAX_HEROES_AVAILABLE_PER_PLAYER"].Integer());
|
||||
logMod->debug("\tMAX_HEROES_AVAILABLE_PER_PLAYER\t%d", settings.MAX_HEROES_AVAILABLE_PER_PLAYER);
|
||||
settings.MAX_HEROES_ON_MAP_PER_PLAYER = static_cast<int>(hardcodedFeatures["MAX_HEROES_ON_MAP_PER_PLAYER"].Integer());
|
||||
logMod->debug("\tMAX_HEROES_ON_MAP_PER_PLAYER\t%d", settings.MAX_HEROES_ON_MAP_PER_PLAYER);
|
||||
settings.CREEP_SIZE = static_cast<int>(hardcodedFeatures["CREEP_SIZE"].Integer());
|
||||
logMod->debug("\tCREEP_SIZE\t%d", settings.CREEP_SIZE);
|
||||
settings.WEEKLY_GROWTH = static_cast<int>(hardcodedFeatures["WEEKLY_GROWTH_PERCENT"].Integer());
|
||||
logMod->debug("\tWEEKLY_GROWTH\t%d", settings.WEEKLY_GROWTH);
|
||||
settings.NEUTRAL_STACK_EXP = static_cast<int>(hardcodedFeatures["NEUTRAL_STACK_EXP_DAILY"].Integer());
|
||||
logMod->debug("\tNEUTRAL_STACK_EXP\t%d", settings.NEUTRAL_STACK_EXP);
|
||||
settings.MAX_BUILDING_PER_TURN = static_cast<int>(hardcodedFeatures["MAX_BUILDING_PER_TURN"].Integer());
|
||||
logMod->debug("\tMAX_BUILDING_PER_TURN\t%d", settings.MAX_BUILDING_PER_TURN);
|
||||
settings.DWELLINGS_ACCUMULATE_CREATURES = hardcodedFeatures["DWELLINGS_ACCUMULATE_CREATURES"].Bool();
|
||||
logMod->debug("\tDWELLINGS_ACCUMULATE_CREATURES\t%d", static_cast<int>(settings.DWELLINGS_ACCUMULATE_CREATURES));
|
||||
settings.ALL_CREATURES_GET_DOUBLE_MONTHS = hardcodedFeatures["ALL_CREATURES_GET_DOUBLE_MONTHS"].Bool();
|
||||
logMod->debug("\tALL_CREATURES_GET_DOUBLE_MONTHS\t%d", static_cast<int>(settings.ALL_CREATURES_GET_DOUBLE_MONTHS));
|
||||
settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS = hardcodedFeatures["WINNING_HERO_WITH_NO_TROOPS_RETREATS"].Bool();
|
||||
logMod->debug("\tWINNING_HERO_WITH_NO_TROOPS_RETREATS\t%d", static_cast<int>(settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS));
|
||||
settings.BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE = hardcodedFeatures["BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE"].Bool();
|
||||
logMod->debug("\tBLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE\t%d", static_cast<int>(settings.BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE));
|
||||
settings.NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS = hardcodedFeatures["NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS"].Bool();
|
||||
logMod->debug("\tNO_RANDOM_SPECIAL_WEEKS_AND_MONTHS\t%d", static_cast<int>(settings.NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS));
|
||||
settings.ATTACK_POINT_DMG_MULTIPLIER = hardcodedFeatures["ATTACK_POINT_DMG_MULTIPLIER"].Float();
|
||||
logMod->debug("\tATTACK_POINT_DMG_MULTIPLIER\t%f", settings.ATTACK_POINT_DMG_MULTIPLIER);
|
||||
settings.ATTACK_POINTS_DMG_MULTIPLIER_CAP = hardcodedFeatures["ATTACK_POINTS_DMG_MULTIPLIER_CAP"].Float();
|
||||
logMod->debug("\tATTACK_POINTS_DMG_MULTIPLIER_CAP\t%f", settings.ATTACK_POINTS_DMG_MULTIPLIER_CAP);
|
||||
settings.DEFENSE_POINT_DMG_MULTIPLIER = hardcodedFeatures["DEFENSE_POINT_DMG_MULTIPLIER"].Float();
|
||||
logMod->debug("\tDEFENSE_POINT_DMG_MULTIPLIER\t%f", settings.DEFENSE_POINT_DMG_MULTIPLIER);
|
||||
settings.DEFENSE_POINTS_DMG_MULTIPLIER_CAP = hardcodedFeatures["DEFENSE_POINTS_DMG_MULTIPLIER_CAP"].Float();
|
||||
logMod->debug("\tDEFENSE_POINTS_DMG_MULTIPLIER_CAP\t%f", settings.DEFENSE_POINTS_DMG_MULTIPLIER_CAP);
|
||||
|
||||
settings.HERO_STARTING_ARMY_STACKS_COUNT_CHANCES = hardcodedFeatures["HERO_STARTING_ARMY_STACKS_COUNT_CHANCES"].convertTo<std::vector<int32_t>>();
|
||||
for (auto const & entry : settings.HERO_STARTING_ARMY_STACKS_COUNT_CHANCES)
|
||||
logMod->debug("\tHERO_STARTING_ARMY_STACKS_COUNT_CHANCES\t%d", entry);
|
||||
|
||||
settings.DEFAULT_BUILDING_SET_DWELLING_CHANCES = hardcodedFeatures["DEFAULT_BUILDING_SET_DWELLING_CHANCES"].convertTo<std::vector<int32_t>>();
|
||||
for (auto const & entry : settings.DEFAULT_BUILDING_SET_DWELLING_CHANCES)
|
||||
logMod->debug("\tDEFAULT_BUILDING_SET_DWELLING_CHANCES\t%d", entry);
|
||||
|
||||
const JsonNode & gameModules = settings.data["modules"];
|
||||
modules.STACK_EXP = gameModules["STACK_EXPERIENCE"].Bool();
|
||||
logMod->debug("\tSTACK_EXP\t%d", static_cast<int>(modules.STACK_EXP));
|
||||
modules.STACK_ARTIFACT = gameModules["STACK_ARTIFACTS"].Bool();
|
||||
logMod->debug("\tSTACK_ARTIFACT\t%d", static_cast<int>(modules.STACK_ARTIFACT));
|
||||
modules.COMMANDERS = gameModules["COMMANDERS"].Bool();
|
||||
logMod->debug("\tCOMMANDERS\t%d", static_cast<int>(modules.COMMANDERS));
|
||||
modules.MITHRIL = gameModules["MITHRIL"].Bool();
|
||||
logMod->debug("\tMITHRIL\t%d", static_cast<int>(modules.MITHRIL));
|
||||
|
||||
const JsonNode & baseBonuses = VLC->modh->settings.data["heroBaseBonuses"];
|
||||
logMod->debug("\tLoading base hero bonuses");
|
||||
for(const auto & b : baseBonuses.Vector())
|
||||
heroBaseBonuses.emplace_back(JsonUtils::parseBonus(b));
|
||||
}
|
||||
|
||||
// currentList is passed by value to get current list of depending mods
|
||||
bool CModHandler::hasCircularDependency(const TModID & modID, std::set<TModID> currentList) const
|
||||
{
|
||||
@ -1127,7 +1059,14 @@ std::set<TModID> CModHandler::getModDependencies(const TModID & modId, bool & is
|
||||
|
||||
void CModHandler::initializeConfig()
|
||||
{
|
||||
loadConfigFromFile("defaultMods.json");
|
||||
VLC->settingsHandler->load(coreMod.config["settings"]);
|
||||
|
||||
for(const TModID & modName : activeMods)
|
||||
{
|
||||
const auto & mod = allMods[modName];
|
||||
if (!mod.config["settings"].isNull())
|
||||
VLC->settingsHandler->load(mod.config["settings"]);
|
||||
}
|
||||
}
|
||||
|
||||
bool CModHandler::validateTranslations(TModID modName) const
|
||||
|
@ -9,9 +9,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "filesystem/Filesystem.h"
|
||||
|
||||
#include "VCMI_Lib.h"
|
||||
#include "JsonNode.h"
|
||||
|
||||
#ifdef __UCLIBC__
|
||||
@ -267,8 +264,6 @@ class DLL_LINKAGE CModHandler
|
||||
std::vector <TModID> activeMods;//active mods, in order in which they were loaded
|
||||
CModInfo coreMod;
|
||||
|
||||
void loadConfigFromFile(const std::string & name);
|
||||
|
||||
bool hasCircularDependency(const TModID & mod, std::set<TModID> currentList = std::set<TModID>()) const;
|
||||
|
||||
/**
|
||||
@ -353,72 +348,6 @@ public:
|
||||
void load();
|
||||
void afterLoad(bool onlyEssential);
|
||||
|
||||
std::vector<std::shared_ptr<Bonus>> heroBaseBonuses; //these bonuses will be applied to every hero on map
|
||||
|
||||
struct DLL_LINKAGE hardcodedFeatures
|
||||
{
|
||||
JsonNode data;
|
||||
|
||||
int CREEP_SIZE; // neutral stacks won't grow beyond this number
|
||||
int WEEKLY_GROWTH; //percent
|
||||
int NEUTRAL_STACK_EXP;
|
||||
int MAX_BUILDING_PER_TURN;
|
||||
bool DWELLINGS_ACCUMULATE_CREATURES;
|
||||
bool ALL_CREATURES_GET_DOUBLE_MONTHS;
|
||||
int MAX_HEROES_AVAILABLE_PER_PLAYER;
|
||||
int MAX_HEROES_ON_MAP_PER_PLAYER;
|
||||
bool WINNING_HERO_WITH_NO_TROOPS_RETREATS;
|
||||
bool BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE;
|
||||
bool NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS;
|
||||
double ATTACK_POINT_DMG_MULTIPLIER;
|
||||
double ATTACK_POINTS_DMG_MULTIPLIER_CAP;
|
||||
double DEFENSE_POINT_DMG_MULTIPLIER;
|
||||
double DEFENSE_POINTS_DMG_MULTIPLIER_CAP;
|
||||
std::vector<int32_t> HERO_STARTING_ARMY_STACKS_COUNT_CHANCES;
|
||||
std::vector<int32_t> DEFAULT_BUILDING_SET_DWELLING_CHANCES;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & data;
|
||||
h & CREEP_SIZE;
|
||||
h & WEEKLY_GROWTH;
|
||||
h & NEUTRAL_STACK_EXP;
|
||||
h & MAX_BUILDING_PER_TURN;
|
||||
h & DWELLINGS_ACCUMULATE_CREATURES;
|
||||
h & ALL_CREATURES_GET_DOUBLE_MONTHS;
|
||||
h & MAX_HEROES_AVAILABLE_PER_PLAYER;
|
||||
h & MAX_HEROES_ON_MAP_PER_PLAYER;
|
||||
h & WINNING_HERO_WITH_NO_TROOPS_RETREATS;
|
||||
h & BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE;
|
||||
h & NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS;
|
||||
h & ATTACK_POINT_DMG_MULTIPLIER;
|
||||
h & ATTACK_POINTS_DMG_MULTIPLIER_CAP;
|
||||
h & DEFENSE_POINT_DMG_MULTIPLIER;
|
||||
h & DEFENSE_POINTS_DMG_MULTIPLIER_CAP;
|
||||
if(version >= 815)
|
||||
{
|
||||
h & HERO_STARTING_ARMY_STACKS_COUNT_CHANCES;
|
||||
h & DEFAULT_BUILDING_SET_DWELLING_CHANCES;
|
||||
}
|
||||
}
|
||||
} settings;
|
||||
|
||||
struct DLL_LINKAGE gameModules
|
||||
{
|
||||
bool STACK_EXP;
|
||||
bool STACK_ARTIFACT;
|
||||
bool COMMANDERS;
|
||||
bool MITHRIL;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & STACK_EXP;
|
||||
h & STACK_ARTIFACT;
|
||||
h & COMMANDERS;
|
||||
h & MITHRIL;
|
||||
}
|
||||
} modules;
|
||||
|
||||
CModHandler();
|
||||
virtual ~CModHandler() = default;
|
||||
|
||||
@ -460,9 +389,7 @@ public:
|
||||
|
||||
std::swap(activeMods, newActiveMods);
|
||||
}
|
||||
|
||||
h & settings;
|
||||
h & modules;
|
||||
|
||||
h & identifiers;
|
||||
}
|
||||
};
|
||||
|
@ -142,7 +142,7 @@ void CSkill::serializeJson(JsonSerializeFormat & handler)
|
||||
}
|
||||
|
||||
///CSkillHandler
|
||||
std::vector<JsonNode> CSkillHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CSkillHandler::loadLegacyData()
|
||||
{
|
||||
CLegacyConfigParser parser("DATA/SSTRAITS.TXT");
|
||||
|
||||
|
@ -102,7 +102,7 @@ class DLL_LINKAGE CSkillHandler: public CHandlerBase<SecondarySkill, Skill, CSki
|
||||
{
|
||||
public:
|
||||
///IHandler base
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
void afterLoadFinalization() override;
|
||||
void beforeValidate(JsonNode & object) override;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "CModHandler.h"
|
||||
#include "CHeroHandler.h"
|
||||
#include "CArtHandler.h"
|
||||
#include "GameSettings.h"
|
||||
#include "spells/CSpellHandler.h"
|
||||
#include "filesystem/Filesystem.h"
|
||||
#include "mapObjects/CObjectClassesHandler.h"
|
||||
@ -284,8 +285,10 @@ TPropagatorPtr & CTownHandler::emptyPropagator()
|
||||
return emptyProp;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> CTownHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CTownHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_FACTION);
|
||||
|
||||
std::vector<JsonNode> dest(dataSize);
|
||||
objects.resize(dataSize);
|
||||
|
||||
|
@ -411,7 +411,7 @@ public:
|
||||
CTownHandler();
|
||||
~CTownHandler();
|
||||
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||
|
112
lib/GameSettings.cpp
Normal file
112
lib/GameSettings.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* GameSettings.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "GameSettings.h"
|
||||
#include "JsonNode.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
bool IGameSettings::getBoolean(EGameSettings option) const
|
||||
{
|
||||
return getValue(option).Bool();
|
||||
}
|
||||
|
||||
int64_t IGameSettings::getInteger(EGameSettings option) const
|
||||
{
|
||||
return getValue(option).Integer();
|
||||
}
|
||||
|
||||
double IGameSettings::getDouble(EGameSettings option) const
|
||||
{
|
||||
return getValue(option).Float();
|
||||
}
|
||||
|
||||
std::vector<int> IGameSettings::getVector(EGameSettings option) const
|
||||
{
|
||||
return getValue(option).convertTo<std::vector<int>>();
|
||||
}
|
||||
|
||||
GameSettings::GameSettings()
|
||||
: gameSettings(static_cast<size_t>(EGameSettings::OPTIONS_COUNT))
|
||||
{
|
||||
}
|
||||
|
||||
void GameSettings::load(const JsonNode & input)
|
||||
{
|
||||
struct SettingOption
|
||||
{
|
||||
EGameSettings setting;
|
||||
std::string group;
|
||||
std::string key;
|
||||
};
|
||||
|
||||
static const std::vector<SettingOption> optionPath = {
|
||||
{EGameSettings::BONUSES_GLOBAL, "bonuses", "global" },
|
||||
{EGameSettings::BONUSES_PER_HERO, "bonuses", "perHero" },
|
||||
{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::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::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL, "dwellings", "accumulateWhenNeutral" },
|
||||
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED, "dwellings", "accumulateWhenOwned" },
|
||||
{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::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::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_MAP_VERSION, "textData", "mapVersion" },
|
||||
{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" },
|
||||
};
|
||||
|
||||
for(const auto & option : optionPath)
|
||||
{
|
||||
const JsonNode & optionValue = input[option.group][option.key];
|
||||
size_t index = static_cast<size_t>(option.setting);
|
||||
|
||||
if(optionValue.isNull())
|
||||
continue;
|
||||
|
||||
JsonUtils::mergeCopy(gameSettings[index], optionValue);
|
||||
}
|
||||
}
|
||||
|
||||
const JsonNode & GameSettings::getValue(EGameSettings option) const
|
||||
{
|
||||
assert(option < EGameSettings::OPTIONS_COUNT);
|
||||
auto index = static_cast<size_t>(option);
|
||||
|
||||
assert(!gameSettings[index].isNull());
|
||||
return gameSettings[index];
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
87
lib/GameSettings.h
Normal file
87
lib/GameSettings.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* GameSettings.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class JsonNode;
|
||||
|
||||
enum class EGameSettings
|
||||
{
|
||||
BONUSES_GLOBAL,
|
||||
BONUSES_PER_HERO,
|
||||
COMBAT_ATTACK_POINT_DAMAGE_FACTOR,
|
||||
COMBAT_ATTACK_POINT_DAMAGE_FACTOR_CAP,
|
||||
COMBAT_BAD_LUCK_DICE,
|
||||
COMBAT_BAD_MORALE_DICE,
|
||||
COMBAT_DEFENSE_POINT_DAMAGE_FACTOR,
|
||||
COMBAT_DEFENSE_POINT_DAMAGE_FACTOR_CAP,
|
||||
COMBAT_GOOD_LUCK_DICE,
|
||||
COMBAT_GOOD_MORALE_DICE,
|
||||
CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH,
|
||||
CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS,
|
||||
CREATURES_DAILY_STACK_EXPERIENCE,
|
||||
CREATURES_WEEKLY_GROWTH_CAP,
|
||||
CREATURES_WEEKLY_GROWTH_PERCENT,
|
||||
DWELLINGS_ACCUMULATE_WHEN_NEUTRAL,
|
||||
DWELLINGS_ACCUMULATE_WHEN_OWNED,
|
||||
HEROES_PER_PLAYER_ON_MAP_CAP,
|
||||
HEROES_PER_PLAYER_TOTAL_CAP,
|
||||
HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS,
|
||||
HEROES_STARTING_STACKS_CHANCES,
|
||||
MARKETS_BLACK_MARKET_RESTOCK_PERIOD,
|
||||
MODULE_COMMANDERS,
|
||||
MODULE_STACK_ARTIFACT,
|
||||
MODULE_STACK_EXPERIENCE,
|
||||
TEXTS_ARTIFACT,
|
||||
TEXTS_CREATURE,
|
||||
TEXTS_FACTION,
|
||||
TEXTS_HERO,
|
||||
TEXTS_HERO_CLASS,
|
||||
TEXTS_MAP_VERSION,
|
||||
TEXTS_OBJECT,
|
||||
TEXTS_RIVER,
|
||||
TEXTS_ROAD,
|
||||
TEXTS_SPELL,
|
||||
TEXTS_TERRAIN,
|
||||
TOWNS_BUILDINGS_PER_TURN_CAP,
|
||||
TOWNS_STARTING_DWELLING_CHANCES,
|
||||
|
||||
OPTIONS_COUNT
|
||||
};
|
||||
|
||||
class DLL_LINKAGE IGameSettings
|
||||
{
|
||||
public:
|
||||
virtual const JsonNode & getValue(EGameSettings option) const = 0;
|
||||
|
||||
bool getBoolean(EGameSettings option) const;
|
||||
int64_t getInteger(EGameSettings option) const;
|
||||
double getDouble(EGameSettings option) const;
|
||||
std::vector<int> getVector(EGameSettings option) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE GameSettings final : public IGameSettings
|
||||
{
|
||||
std::vector<JsonNode> gameSettings;
|
||||
|
||||
public:
|
||||
GameSettings();
|
||||
void load(const JsonNode & input);
|
||||
const JsonNode & getValue(EGameSettings option) const override;
|
||||
|
||||
template<typename Handler>
|
||||
void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & gameSettings;
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -30,6 +30,7 @@
|
||||
#include "CGameState.h"
|
||||
#include "mapping/CMap.h"
|
||||
#include "CPlayerState.h"
|
||||
#include "GameSettings.h"
|
||||
#include "ScriptHandler.h"
|
||||
#include "RoadHandler.h"
|
||||
#include "RiverHandler.h"
|
||||
|
@ -29,7 +29,7 @@ protected:
|
||||
public:
|
||||
/// loads all original game data in vector of json nodes
|
||||
/// dataSize - is number of items that must be loaded (normally - constant from GameConstants)
|
||||
virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) = 0;
|
||||
virtual std::vector<JsonNode> loadLegacyData() = 0;
|
||||
|
||||
/// loads single object into game. Scope is namespace of this object, same as name of source mod
|
||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data) = 0;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "CPlayerState.h"
|
||||
#include "TerrainHandler.h"
|
||||
#include "mapping/CCampaignHandler.h"
|
||||
#include "GameSettings.h"
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -1675,7 +1676,7 @@ void RebalanceStacks::applyGs(CGameState * gs)
|
||||
|
||||
const CCreature * srcType = src.army->getCreature(src.slot);
|
||||
TQuantity srcCount = src.army->getStackCount(src.slot);
|
||||
bool stackExp = VLC->modh->modules.STACK_EXP;
|
||||
bool stackExp = VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE);
|
||||
|
||||
if(srcCount == count) //moving whole stack
|
||||
{
|
||||
@ -2201,7 +2202,7 @@ void BattleResult::applyGs(CGameState *gs)
|
||||
}
|
||||
}
|
||||
|
||||
if(VLC->modh->modules.STACK_EXP)
|
||||
if(VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
if(exp[i])
|
||||
|
@ -109,7 +109,7 @@ ObstacleInfo * ObstacleHandler::loadFromJson(const std::string & scope, const Js
|
||||
return info;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> ObstacleHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> ObstacleHandler::loadLegacyData()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
size_t index) override;
|
||||
|
||||
const std::vector<std::string> & getTypeNames() const override;
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "RiverHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "GameSettings.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -50,8 +51,10 @@ const std::vector<std::string> & RiverTypeHandler::getTypeNames() const
|
||||
return typeNames;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> RiverTypeHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> RiverTypeHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_RIVER);
|
||||
|
||||
objects.resize(dataSize);
|
||||
return {};
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
RiverTypeHandler();
|
||||
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "RoadHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "GameSettings.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -50,8 +51,10 @@ const std::vector<std::string> & RoadTypeHandler::getTypeNames() const
|
||||
return typeNames;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> RoadTypeHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> RoadTypeHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_ROAD);
|
||||
|
||||
objects.resize(dataSize);
|
||||
return {};
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
RoadTypeHandler();
|
||||
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
|
@ -223,7 +223,7 @@ std::vector<bool> ScriptHandler::getDefaultAllowed() const
|
||||
return std::vector<bool>();
|
||||
}
|
||||
|
||||
std::vector<JsonNode> ScriptHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> ScriptHandler::loadLegacyData()
|
||||
{
|
||||
return std::vector<JsonNode>();
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
const Script * resolveScript(const std::string & name) const;
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
ScriptPtr loadFromJson(vstd::CLoggerBase * logger, const std::string & scope, const JsonNode & json, const std::string & identifier) const;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "TerrainHandler.h"
|
||||
#include "CModHandler.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "GameSettings.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -110,8 +111,10 @@ const std::vector<std::string> & TerrainTypeHandler::getTypeNames() const
|
||||
return typeNames;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> TerrainTypeHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> TerrainTypeHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_TERRAIN);
|
||||
|
||||
objects.resize(dataSize);
|
||||
|
||||
CLegacyConfigParser terrainParser("DATA/TERRNAME.TXT");
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
size_t index) override;
|
||||
|
||||
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||
virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
virtual std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "ScriptHandler.h"
|
||||
#include "BattleFieldHandler.h"
|
||||
#include "ObstacleHandler.h"
|
||||
#include "GameSettings.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -132,6 +133,11 @@ const ObstacleService * LibClasses::obstacles() const
|
||||
return obstacleHandler;
|
||||
}
|
||||
|
||||
const IGameSettings * LibClasses::settings() const
|
||||
{
|
||||
return settingsHandler;
|
||||
}
|
||||
|
||||
void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data)
|
||||
{
|
||||
switch(metatype)
|
||||
@ -201,6 +207,7 @@ void LibClasses::init(bool onlyEssential)
|
||||
CStopWatch pomtime;
|
||||
CStopWatch totalTime;
|
||||
|
||||
createHandler(settingsHandler, "Game Settings", pomtime);
|
||||
modh->initializeConfig();
|
||||
|
||||
createHandler(generaltexth, "General text", pomtime);
|
||||
|
@ -36,6 +36,8 @@ class ObstacleHandler;
|
||||
class CTerrainViewPatternConfig;
|
||||
class CRmgTemplateStorage;
|
||||
class IHandlerBase;
|
||||
class IGameSettings;
|
||||
class GameSettings;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
namespace scripting
|
||||
@ -70,6 +72,7 @@ public:
|
||||
const SkillService * skills() const override;
|
||||
const BattleFieldService * battlefields() const override;
|
||||
const ObstacleService * obstacles() const override;
|
||||
const IGameSettings * settings() const override;
|
||||
|
||||
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
||||
|
||||
@ -97,6 +100,7 @@ public:
|
||||
CRmgTemplateStorage * tplh;
|
||||
BattleFieldHandler * battlefieldsHandler;
|
||||
ObstacleHandler * obstacleHandler;
|
||||
GameSettings * settingsHandler;
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::ScriptHandler * scriptHandler;
|
||||
#endif
|
||||
@ -124,6 +128,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
h & settingsHandler;
|
||||
h & heroh;
|
||||
h & arth;
|
||||
h & creh;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "../HeroBonus.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
#include "../CModHandler.h"
|
||||
#include "../GameSettings.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -183,8 +183,8 @@ double DamageCalculator::getAttackSkillFactor() const
|
||||
|
||||
if(attackAdvantage > 0)
|
||||
{
|
||||
const double attackMultiplier = VLC->modh->settings.ATTACK_POINT_DMG_MULTIPLIER;
|
||||
const double attackMultiplierCap = VLC->modh->settings.ATTACK_POINTS_DMG_MULTIPLIER_CAP;
|
||||
const double attackMultiplier = VLC->settings()->getDouble(EGameSettings::COMBAT_ATTACK_POINT_DAMAGE_FACTOR);
|
||||
const double attackMultiplierCap = VLC->settings()->getDouble(EGameSettings::COMBAT_ATTACK_POINT_DAMAGE_FACTOR_CAP);
|
||||
const double attackFactor = std::min(attackMultiplier * attackAdvantage, attackMultiplierCap);
|
||||
|
||||
return attackFactor;
|
||||
@ -269,8 +269,8 @@ double DamageCalculator::getDefenseSkillFactor() const
|
||||
//bonus from attack/defense skills
|
||||
if(defenseAdvantage > 0) //decreasing dmg
|
||||
{
|
||||
const double defenseMultiplier = VLC->modh->settings.DEFENSE_POINT_DMG_MULTIPLIER;
|
||||
const double defenseMultiplierCap = VLC->modh->settings.DEFENSE_POINTS_DMG_MULTIPLIER_CAP;
|
||||
const double defenseMultiplier = VLC->settings()->getDouble(EGameSettings::COMBAT_DEFENSE_POINT_DAMAGE_FACTOR);
|
||||
const double defenseMultiplierCap = VLC->settings()->getDouble(EGameSettings::COMBAT_DEFENSE_POINT_DAMAGE_FACTOR_CAP);
|
||||
|
||||
const double dec = std::min(defenseMultiplier * defenseAdvantage, defenseMultiplierCap);
|
||||
return dec;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../RoadHandler.h"
|
||||
#include "../GameSettings.h"
|
||||
#include "../CModHandler.h"
|
||||
#include "../CSoundBase.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
@ -312,16 +313,17 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
|
||||
// are not attached to global bonus node but need access to some global bonuses
|
||||
// e.g. MANA_PER_KNOWLEDGE for correct preview and initial state after recruit for(const auto & ob : VLC->modh->heroBaseBonuses)
|
||||
// or MOVEMENT to compute initial movement before recruiting is finished
|
||||
for(const auto & ob : VLC->modh->heroBaseBonuses)
|
||||
const JsonNode & baseBonuses = VLC->settings()->getValue(EGameSettings::BONUSES_PER_HERO);
|
||||
for(const auto & b : baseBonuses.Struct())
|
||||
{
|
||||
auto bonus = ob;
|
||||
auto bonus = JsonUtils::parseBonus(b.second);
|
||||
bonus->source = Bonus::HERO_BASE_SKILL;
|
||||
bonus->sid = id.getNum();
|
||||
bonus->duration = Bonus::PERMANENT;
|
||||
addNewBonus(bonus);
|
||||
}
|
||||
|
||||
if (VLC->modh->modules.COMMANDERS && !commander)
|
||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS) && !commander)
|
||||
{
|
||||
commander = new CCommanderInstance(type->heroClass->commander->idNumber);
|
||||
commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders
|
||||
@ -339,27 +341,16 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst)
|
||||
|
||||
int warMachinesGiven = 0;
|
||||
|
||||
std::vector<int32_t> stacksCountChances = VLC->modh->settings.HERO_STARTING_ARMY_STACKS_COUNT_CHANCES;
|
||||
|
||||
const int zeroStacksAllowingValue = -1;
|
||||
bool allowZeroStacksArmy = !stacksCountChances.empty() && stacksCountChances.back() == zeroStacksAllowingValue;
|
||||
if(allowZeroStacksArmy)
|
||||
stacksCountChances.pop_back();
|
||||
|
||||
auto stacksCountChances = VLC->settings()->getVector(EGameSettings::HEROES_STARTING_STACKS_CHANCES);
|
||||
int stacksCountInitRandomNumber = rand.nextInt(1, 100);
|
||||
|
||||
auto stacksCountElementIndex = vstd::find_pos_if(stacksCountChances, [stacksCountInitRandomNumber](int element){ return stacksCountInitRandomNumber < element; });
|
||||
if(stacksCountElementIndex == -1)
|
||||
stacksCountElementIndex = stacksCountChances.size();
|
||||
size_t maxStacksCount = std::min(stacksCountChances.size(), type->initialArmy.size());
|
||||
|
||||
int howManyStacks = stacksCountElementIndex;
|
||||
if(!allowZeroStacksArmy)
|
||||
howManyStacks++;
|
||||
|
||||
vstd::amin(howManyStacks, type->initialArmy.size());
|
||||
|
||||
for(int stackNo=0; stackNo < howManyStacks; stackNo++)
|
||||
for(int stackNo=0; stackNo < maxStacksCount; stackNo++)
|
||||
{
|
||||
if (stacksCountInitRandomNumber > stacksCountChances[stackNo])
|
||||
continue;
|
||||
|
||||
auto & stack = type->initialArmy[stackNo];
|
||||
|
||||
int count = rand.nextInt(stack.minAmount, stack.maxAmount);
|
||||
@ -436,7 +427,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
{
|
||||
int txt_id;
|
||||
|
||||
if (cb->getHeroCount(h->tempOwner, false) < VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)//free hero slot
|
||||
if (cb->getHeroCount(h->tempOwner, false) < VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP))//free hero slot
|
||||
{
|
||||
//update hero parameters
|
||||
SetMovePoints smp;
|
||||
@ -1473,7 +1464,7 @@ void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler)
|
||||
handler.serializeBool<ui8>("female", sex, 1, 0, 0xFF);
|
||||
|
||||
{
|
||||
const int legacyHeroes = static_cast<int>(VLC->modh->settings.data["textData"]["hero"].Integer());
|
||||
const int legacyHeroes = VLC->settings()->getInteger(EGameSettings::TEXTS_HERO);
|
||||
const int moddedStart = legacyHeroes + GameConstants::HERO_PORTRAIT_SHIFT;
|
||||
|
||||
if(handler.saving)
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../CGameState.h"
|
||||
#include "CGTownInstance.h"
|
||||
#include "../CModHandler.h"
|
||||
#include "../GameSettings.h"
|
||||
#include "../CSkillHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -277,10 +277,12 @@ std::vector<int> CGBlackMarket::availableItemsIds(EMarketMode::EMarketMode mode)
|
||||
|
||||
void CGBlackMarket::newTurn(CRandomGenerator & rand) const
|
||||
{
|
||||
if(!VLC->modh->settings.BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE) //check if feature changing OH3 behavior is enabled
|
||||
int resetPeriod = VLC->settings()->getInteger(EGameSettings::MARKETS_BLACK_MARKET_RESTOCK_PERIOD);
|
||||
|
||||
if(resetPeriod == 0) //check if feature changing OH3 behavior is enabled
|
||||
return;
|
||||
|
||||
if(cb->getDate(Date::DAY_OF_MONTH) != 1) //new month
|
||||
if (((cb->getDate(Date::DAY)-1) % resetPeriod) != 0)
|
||||
return;
|
||||
|
||||
SetAvailableArtifacts saa;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../CConfigHandler.h"
|
||||
#include "../CGeneralTextHandler.h"
|
||||
#include "../CModHandler.h"
|
||||
#include "../GameSettings.h"
|
||||
#include "../IGameCallback.h"
|
||||
#include "../CGameState.h"
|
||||
#include "../mapping/CMap.h"
|
||||
@ -254,9 +255,16 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const
|
||||
{
|
||||
if(!creatures[i].second.empty())
|
||||
{
|
||||
bool creaturesAccumulate = false;
|
||||
|
||||
if (tempOwner.isValidPlayer())
|
||||
creaturesAccumulate = VLC->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED);
|
||||
else
|
||||
creaturesAccumulate = VLC->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL);
|
||||
|
||||
CCreature *cre = VLC->creh->objects[creatures[i].second[0]];
|
||||
TQuantity amount = cre->growth * (1 + cre->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100) + cre->valOfBonuses(Bonus::CREATURE_GROWTH);
|
||||
if (VLC->modh->settings.DWELLINGS_ACCUMULATE_CREATURES && ID != Obj::REFUGEE_CAMP) //camp should not try to accumulate different kinds of creatures
|
||||
if (creaturesAccumulate && ID != Obj::REFUGEE_CAMP) //camp should not try to accumulate different kinds of creatures
|
||||
sac.creatures[i].first += amount;
|
||||
else
|
||||
sac.creatures[i].first = amount;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../StringConstants.h"
|
||||
#include "../CGeneralTextHandler.h"
|
||||
#include "../CModHandler.h"
|
||||
#include "../GameSettings.h"
|
||||
#include "../JsonNode.h"
|
||||
#include "../CSoundBase.h"
|
||||
|
||||
@ -95,8 +96,10 @@ CObjectClassesHandler::~CObjectClassesHandler()
|
||||
delete p;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> CObjectClassesHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CObjectClassesHandler::loadLegacyData()
|
||||
{
|
||||
size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_OBJECT);
|
||||
|
||||
CLegacyConfigParser parser("Data/Objects.txt");
|
||||
auto totalNumber = static_cast<size_t>(parser.readNumber()); // first line contains number of objects to read and nothing else
|
||||
parser.endLine();
|
||||
|
@ -296,7 +296,7 @@ public:
|
||||
CObjectClassesHandler();
|
||||
~CObjectClassesHandler();
|
||||
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../CGameState.h"
|
||||
#include "../mapping/CMap.h"
|
||||
#include "../CPlayerState.h"
|
||||
#include "../GameSettings.h"
|
||||
#include "../serializer/JsonSerializeFormat.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -232,15 +233,15 @@ void CGCreature::newTurn(CRandomGenerator & rand) const
|
||||
{//Works only for stacks of single type of size up to 2 millions
|
||||
if (!notGrowingTeam)
|
||||
{
|
||||
if (stacks.begin()->second->count < VLC->modh->settings.CREEP_SIZE && cb->getDate(Date::DAY_OF_WEEK) == 1 && cb->getDate(Date::DAY) > 1)
|
||||
if (stacks.begin()->second->count < VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP) && cb->getDate(Date::DAY_OF_WEEK) == 1 && cb->getDate(Date::DAY) > 1)
|
||||
{
|
||||
ui32 power = static_cast<ui32>(temppower * (100 + VLC->modh->settings.WEEKLY_GROWTH) / 100);
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_COUNT, std::min(power / 1000, static_cast<ui32>(VLC->modh->settings.CREEP_SIZE))); //set new amount
|
||||
ui32 power = static_cast<ui32>(temppower * (100 + VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT)) / 100);
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_COUNT, std::min<uint32_t>(power / 1000, VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT))); //set new amount
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_POWER, power); //increase temppower
|
||||
}
|
||||
}
|
||||
if (VLC->modh->modules.STACK_EXP)
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_EXP, VLC->modh->settings.NEUTRAL_STACK_EXP); //for testing purpose
|
||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_EXP, VLC->settings()->getInteger(EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE)); //for testing purpose
|
||||
}
|
||||
void CGCreature::setPropertyDer(ui8 what, ui32 val)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ std::vector<bool> CRmgTemplateStorage::getDefaultAllowed() const
|
||||
return std::vector<bool>();
|
||||
}
|
||||
|
||||
std::vector<JsonNode> CRmgTemplateStorage::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CRmgTemplateStorage::loadLegacyData()
|
||||
{
|
||||
return std::vector<JsonNode>();
|
||||
//it would be cool to load old rmg.txt files
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
CRmgTemplateStorage() = default;
|
||||
|
||||
std::vector<bool> getDefaultAllowed() const override;
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
|
||||
/// loads single object into game. Scope is namespace of this object, same as name of source mod
|
||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
const ui32 SERIALIZATION_VERSION = 819;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 819;
|
||||
const ui32 SERIALIZATION_VERSION = 820;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 820;
|
||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||
|
||||
class CHero;
|
||||
|
@ -559,7 +559,7 @@ bool DLL_LINKAGE isInScreenRange(const int3 & center, const int3 & pos)
|
||||
}
|
||||
|
||||
///CSpellHandler
|
||||
std::vector<JsonNode> CSpellHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> CSpellHandler::loadLegacyData()
|
||||
{
|
||||
using namespace SpellConfig;
|
||||
std::vector<JsonNode> legacyData;
|
||||
|
@ -365,7 +365,7 @@ class DLL_LINKAGE CSpellHandler: public CHandlerBase<SpellID, spells::Spell, CSp
|
||||
{
|
||||
public:
|
||||
///IHandler base
|
||||
std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
void afterLoadFinalization() override;
|
||||
void beforeValidate(JsonNode & object) override;
|
||||
|
||||
|
@ -75,7 +75,9 @@ set(editor_TS
|
||||
translation/german.ts
|
||||
translation/polish.ts
|
||||
translation/russian.ts
|
||||
translation/ukrainian.ts)
|
||||
translation/spanish.ts
|
||||
translation/ukrainian.ts
|
||||
)
|
||||
|
||||
assign_source_group(${editor_SRCS} ${editor_HEADERS} mapeditor.rc)
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "../lib/CCreatureHandler.h"
|
||||
#include "../lib/CGameState.h"
|
||||
#include "../lib/CStack.h"
|
||||
#include "../lib/GameSettings.h"
|
||||
#include "../lib/battle/BattleInfo.h"
|
||||
#include "../lib/CondSh.h"
|
||||
#include "ServerNetPackVisitors.h"
|
||||
@ -987,7 +988,7 @@ void CGameHandler::battleAfterLevelUp(const BattleResult &result)
|
||||
RemoveObject ro(finishingBattle->winnerHero->id);
|
||||
sendAndApply(&ro);
|
||||
|
||||
if (VLC->modh->settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS)
|
||||
if (VLC->settings()->getBoolean(EGameSettings::HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS))
|
||||
{
|
||||
SetAvailableHeroes sah;
|
||||
sah.player = finishingBattle->victor;
|
||||
@ -1025,16 +1026,22 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender,
|
||||
|
||||
const int attackerLuck = attacker->LuckVal();
|
||||
|
||||
if (attackerLuck > 0 && getRandomGenerator().nextInt(23) < attackerLuck)
|
||||
if(attackerLuck > 0)
|
||||
{
|
||||
bat.flags |= BattleAttack::LUCKY;
|
||||
auto diceSize = VLC->settings()->getVector(EGameSettings::COMBAT_GOOD_LUCK_DICE);
|
||||
size_t diceIndex = std::min<size_t>(diceSize.size() - 1, attackerLuck);
|
||||
|
||||
if(diceSize.size() > 0 && getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
|
||||
bat.flags |= BattleAttack::LUCKY;
|
||||
}
|
||||
if (VLC->modh->settings.data["hardcodedFeatures"]["NEGATIVE_LUCK"].Bool()) // negative luck enabled
|
||||
|
||||
if(attackerLuck < 0)
|
||||
{
|
||||
if (attackerLuck < 0 && getRandomGenerator().nextInt(23) < abs(attackerLuck))
|
||||
{
|
||||
auto diceSize = VLC->settings()->getVector(EGameSettings::COMBAT_BAD_LUCK_DICE);
|
||||
size_t diceIndex = std::min<size_t>(diceSize.size() - 1, -attackerLuck);
|
||||
|
||||
if(diceSize.size() > 0 && getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
|
||||
bat.flags |= BattleAttack::UNLUCKY;
|
||||
}
|
||||
}
|
||||
|
||||
if (getRandomGenerator().nextInt(99) < attacker->valOfBonuses(Bonus::DOUBLE_DAMAGE_CHANCE))
|
||||
@ -1777,7 +1784,7 @@ void CGameHandler::newTurn()
|
||||
n.specialWeek = NewTurn::DEITYOFFIRE;
|
||||
n.creatureid = CreatureID::IMP;
|
||||
}
|
||||
else if(!VLC->modh->settings.NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS)
|
||||
else if(!VLC->settings()->getBoolean(EGameSettings::CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS))
|
||||
{
|
||||
int monthType = getRandomGenerator().nextInt(99);
|
||||
if (newMonth) //new month
|
||||
@ -1785,15 +1792,13 @@ void CGameHandler::newTurn()
|
||||
if (monthType < 40) //double growth
|
||||
{
|
||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||
if (VLC->modh->settings.ALL_CREATURES_GET_DOUBLE_MONTHS)
|
||||
if (VLC->settings()->getBoolean(EGameSettings::CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH))
|
||||
{
|
||||
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster(getRandomGenerator()));
|
||||
n.creatureid = newMonster.second;
|
||||
n.creatureid = VLC->creh->pickRandomMonster(getRandomGenerator());
|
||||
}
|
||||
else if (VLC->creh->doubledCreatures.size())
|
||||
{
|
||||
const std::vector<CreatureID> doubledCreatures (VLC->creh->doubledCreatures.begin(), VLC->creh->doubledCreatures.end());
|
||||
n.creatureid = *RandomGeneratorUtil::nextItem(doubledCreatures, getRandomGenerator());
|
||||
n.creatureid = *RandomGeneratorUtil::nextItem(VLC->creh->doubledCreatures, getRandomGenerator());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3960,7 +3965,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat
|
||||
if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dst.slot))
|
||||
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
|
||||
}
|
||||
catch (boost::bad_get const &)
|
||||
catch(const boost::bad_get &)
|
||||
{
|
||||
// object other than hero received an art - ignore
|
||||
}
|
||||
@ -4364,8 +4369,8 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl
|
||||
// if ((p->resources.at(Res::GOLD)<GOLD_NEEDED && complain("Not enough gold for buying hero!"))
|
||||
// || (getHeroCount(player, false) >= GameConstants::MAX_HEROES_PER_PLAYER && complain("Cannot hire hero, only 8 wandering heroes are allowed!")))
|
||||
if ((p->resources.at(Res::GOLD) < GameConstants::HERO_GOLD_COST && complain("Not enough gold for buying hero!"))
|
||||
|| ((getHeroCount(player, false) >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER && complain("Cannot hire hero, too many wandering heroes already!")))
|
||||
|| ((getHeroCount(player, true) >= VLC->modh->settings.MAX_HEROES_AVAILABLE_PER_PLAYER && complain("Cannot hire hero, too many heroes garrizoned and wandering already!"))))
|
||||
|| ((getHeroCount(player, false) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP) && complain("Cannot hire hero, too many wandering heroes already!")))
|
||||
|| ((getHeroCount(player, true) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP) && complain("Cannot hire hero, too many heroes garrizoned and wandering already!"))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -6568,7 +6573,10 @@ void CGameHandler::runBattle()
|
||||
int nextStackMorale = next->MoraleVal();
|
||||
if (nextStackMorale < 0)
|
||||
{
|
||||
if (getRandomGenerator().nextInt(23) < -2 * nextStackMorale)
|
||||
auto diceSize = VLC->settings()->getVector(EGameSettings::COMBAT_BAD_MORALE_DICE);
|
||||
size_t diceIndex = std::min<size_t>(diceSize.size()-1, -nextStackMorale);
|
||||
|
||||
if(diceSize.size() > 0 && getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
|
||||
{
|
||||
//unit loses its turn - empty freeze action
|
||||
BattleAction ba;
|
||||
@ -6756,7 +6764,10 @@ void CGameHandler::runBattle()
|
||||
&& next->alive()
|
||||
&& nextStackMorale > 0)
|
||||
{
|
||||
if(getRandomGenerator().nextInt(23) < nextStackMorale) //this stack hasn't got morale this turn
|
||||
auto diceSize = VLC->settings()->getVector(EGameSettings::COMBAT_GOOD_MORALE_DICE);
|
||||
size_t diceIndex = std::min<size_t>(diceSize.size()-1, nextStackMorale);
|
||||
|
||||
if(diceSize.size() > 0 && getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
|
||||
{
|
||||
BattleTriggerEffect bte;
|
||||
bte.stackID = next->ID;
|
||||
|
Loading…
Reference in New Issue
Block a user