From c6cc6e63014c5546acc15fe88a1dca3102b4d95f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 21 Apr 2013 12:49:26 +0000 Subject: [PATCH] Large changeset, first part of editing H3 objects via mods feature. Changes: - loading of all objects (including H3 objects) will be directed by mod handlers - common base for all handlers accessible from mod system (IHanderBase) - json format changes: use struct with string ID's instead of vector - fixed some gcc/clang errors and warnings - fixed several cases of memory leaks and invalid memory access (mostly related to usage of bonus system and/or identifiers resolution) Note that right now loading is much slower than before due to excessive json validation (or not fast enough validator) --- AI/VCAI/VCAI.cpp | 5 +- Global.h | 4 +- client/CCastleInterface.cpp | 4 +- client/CMT.cpp | 3 - client/CPreGame.cpp | 27 +- client/GUIClasses.cpp | 24 +- client/NetPacksClient.cpp | 2 +- client/battle/CBattleInterface.cpp | 2 +- config/artifacts.json | 5247 ++++++++++++++-------------- config/creatures/castle.json | 28 +- config/creatures/conflux.json | 28 +- config/creatures/dungeon.json | 28 +- config/creatures/fortress.json | 28 +- config/creatures/inferno.json | 28 +- config/creatures/necropolis.json | 28 +- config/creatures/neutral.json | 30 +- config/creatures/rampart.json | 28 +- config/creatures/special.json | 18 +- config/creatures/stronghold.json | 28 +- config/creatures/tower.json | 28 +- config/creatures/wog.json | 128 +- config/factions/castle.json | 167 +- config/factions/conflux.json | 177 +- config/factions/dungeon.json | 164 +- config/factions/fortress.json | 168 +- config/factions/inferno.json | 168 +- config/factions/necropolis.json | 178 +- config/factions/rampart.json | 179 +- config/factions/stronghold.json | 162 +- config/factions/tower.json | 164 +- config/gameConfig.json | 10 + config/heroClasses.json | 36 +- config/heroes/castle.json | 32 +- config/heroes/conflux.json | 32 +- config/heroes/dungeon.json | 32 +- config/heroes/fortress.json | 32 +- config/heroes/inferno.json | 32 +- config/heroes/necropolis.json | 32 +- config/heroes/rampart.json | 32 +- config/heroes/special.json | 24 +- config/heroes/stronghold.json | 32 +- config/heroes/tower.json | 32 +- config/schemas/artifact.json | 2 +- config/schemas/creature.json | 2 +- config/schemas/faction.json | 8 +- config/schemas/hero.json | 2 +- config/schemas/heroClass.json | 2 +- lib/BattleState.cpp | 2 +- lib/CArtHandler.cpp | 64 +- lib/CArtHandler.h | 24 +- lib/CBonusTypeHandler.cpp | 3 +- lib/CBonusTypeHandler.h | 1 + lib/CCreatureHandler.cpp | 83 +- lib/CCreatureHandler.h | 67 +- lib/CDefObjInfoHandler.cpp | 13 +- lib/CDefObjInfoHandler.h | 2 +- lib/CGameState.cpp | 34 +- lib/CGeneralTextHandler.cpp | 7 +- lib/CGeneralTextHandler.h | 1 - lib/CHeroHandler.cpp | 279 +- lib/CHeroHandler.h | 52 +- lib/CMakeLists.txt | 1 + lib/CModHandler.cpp | 253 +- lib/CModHandler.h | 53 +- lib/CObjectHandler.cpp | 53 +- lib/CObjectHandler.h | 5 +- lib/CSpellHandler.cpp | 16 +- lib/CSpellHandler.h | 6 +- lib/CTownHandler.cpp | 228 +- lib/CTownHandler.h | 116 +- lib/GameConstants.h | 6 +- lib/HeroBonus.cpp | 2 +- lib/IGameCallback.cpp | 5 +- lib/IHandlerBase.h | 40 + lib/JsonNode.cpp | 8 +- lib/ResourceSet.h | 4 +- lib/StringConstants.h | 16 + lib/VCMI_Lib.cpp | 16 +- lib/VCMI_Lib.h | 4 +- lib/mapping/CMap.cpp | 11 +- lib/mapping/CMapEditManager.h | 2 +- lib/rmg/CMapGenerator.cpp | 4 +- server/CGameHandler.cpp | 17 +- server/CQuery.cpp | 2 +- server/CQuery.h | 8 +- 85 files changed, 4714 insertions(+), 4441 deletions(-) create mode 100644 lib/IHandlerBase.h diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index b343204f3..f0b533ffe 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -1490,7 +1490,7 @@ void VCAI::wander(HeroPtr h) } } const ObjectIdRef&dest = dests.front(); - logAi->debugStream() << "Of all %d destinations, object oid=%d seems nice", dests.size() % dest.id.getNum(); + logAi->debugStream() << boost::format("Of all %d destinations, object oid=%d seems nice") % dests.size() % dest.id.getNum(); if(!goVisitObj(dest, h)) { if(!dest) @@ -1597,6 +1597,7 @@ void VCAI::validateVisitableObjs() logAi->errorStream() << helperObjInfo[obj].name << " at " << helperObjInfo[obj].pos << " shouldn't be on list!"; return true; } + return false; }); } @@ -2414,7 +2415,7 @@ TResources VCAI::estimateIncome() const //TODO duplikuje newturn if(t->hasBuilt(BuildingID::RESOURCE_SILO)) //there is resource silo { - if(t->town->primaryRes == 127) //we'll give wood and ore + if(t->town->primaryRes == Res::WOOD_AND_ORE) //we'll give wood and ore { ret[Res::WOOD] ++; ret[Res::ORE] ++; diff --git a/Global.h b/Global.h index 7c4f68afe..d43206d38 100644 --- a/Global.h +++ b/Global.h @@ -575,7 +575,7 @@ namespace vstd if(c.size()) return c.back(); else - return NULL; + return nullptr; } template @@ -584,7 +584,7 @@ namespace vstd if(c.size()) return c.front(); else - return NULL; + return nullptr; } } using vstd::operator-=; diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index f211d7aca..3fe772b15 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -110,7 +110,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState) if (bid < BuildingID::DWELL_FIRST) { CRClickPopup::createAndPush(CInfoWindow::genText(bld->Name(), bld->Description()), - new CComponent(CComponent::building, bld->tid, bld->bid)); + new CComponent(CComponent::building, bld->town->faction->index, bld->bid)); } else { @@ -1120,7 +1120,7 @@ void CTownInfo::clickRight(tribool down, bool previousState) { if(down && building) CRClickPopup::createAndPush(CInfoWindow::genText(building->Name(), building->Description()), - new CComponent(CComponent::building, building->tid, building->bid)); + new CComponent(CComponent::building, building->town->faction->index, building->bid)); } diff --git a/client/CMT.cpp b/client/CMT.cpp index 4469fb6f2..7afe847dc 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -797,9 +797,6 @@ static void listenForEvents() delete CGI->dobjinfo.get(); const_cast(CGI)->dobjinfo = new CDefObjInfoHandler; - VLC->dobjinfo = const_cast(CGI)->dobjinfo; // update dobjinfo pointer in VLC (used by modHandler::reload()) - - const_cast(CGI)->dobjinfo->load(); const_cast(CGI)->modh->reload(); //add info about new creatures to dobjinfo }; diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index ba9f49084..e647e92d8 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -1856,7 +1856,6 @@ void RandomMapTab::updateMapInfo() player.team = TeamID(i); player.hasMainTown = true; player.generateHeroAtMainTown = true; - player.isFactionRandom = true; mapInfo.mapHeader->players.push_back(player); } @@ -2644,7 +2643,7 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex() { case PlayerSettings::NONE: return TOWN_NONE; case PlayerSettings::RANDOM: return TOWN_RANDOM; - default: return CGI->townh->towns[settings.castle].clientInfo.icons[true][false] + 2; + default: return CGI->townh->factions[settings.castle]->town->clientInfo.icons[true][false] + 2; } case HERO: @@ -2669,9 +2668,9 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex() case PlayerSettings::GOLD: return GOLD; case PlayerSettings::RESOURCE: { - switch(CGI->townh->towns[settings.castle].primaryRes) + switch(CGI->townh->factions[settings.castle]->town->primaryRes) { - case 127 : return WOOD_ORE; + case Res::WOOD_AND_ORE : return WOOD_ORE; case Res::WOOD : return WOOD; case Res::MERCURY : return MERCURY; case Res::ORE : return ORE; @@ -2729,7 +2728,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName() { case PlayerSettings::NONE : return CGI->generaltexth->allTexts[523]; case PlayerSettings::RANDOM : return CGI->generaltexth->allTexts[522]; - default : return CGI->townh->factions[settings.castle].name; + default : return CGI->townh->factions[settings.castle]->name; } } case HERO: @@ -2777,13 +2776,13 @@ std::string OptionsTab::CPlayerSettingsHelper::getSubtitle() case PlayerSettings::GOLD: return CGI->generaltexth->allTexts[87]; //500-1000 case PlayerSettings::RESOURCE: { - switch(CGI->townh->towns[settings.castle].primaryRes) + switch(CGI->townh->factions[settings.castle]->town->primaryRes) { case Res::MERCURY: return CGI->generaltexth->allTexts[694]; case Res::SULFUR: return CGI->generaltexth->allTexts[695]; case Res::CRYSTAL: return CGI->generaltexth->allTexts[692]; case Res::GEMS: return CGI->generaltexth->allTexts[693]; - case 127: return CGI->generaltexth->allTexts[89]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool + case Res::WOOD_AND_ORE: return CGI->generaltexth->allTexts[89]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool } } } @@ -2807,13 +2806,13 @@ std::string OptionsTab::CPlayerSettingsHelper::getDescription() case PlayerSettings::GOLD: return CGI->generaltexth->allTexts[92]; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool case PlayerSettings::RESOURCE: { - switch(CGI->townh->towns[settings.castle].primaryRes) + switch(CGI->townh->factions[settings.castle]->town->primaryRes) { case Res::MERCURY: return CGI->generaltexth->allTexts[690]; case Res::SULFUR: return CGI->generaltexth->allTexts[691]; case Res::CRYSTAL: return CGI->generaltexth->allTexts[688]; case Res::GEMS: return CGI->generaltexth->allTexts[689]; - case 127: return CGI->generaltexth->allTexts[93]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool + case Res::WOOD_AND_ORE: return CGI->generaltexth->allTexts[93]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool } } } @@ -2872,10 +2871,10 @@ void OptionsTab::CPregameTooltipBox::genTownWindow() new CLabel(pos.w / 2 + 8, 122, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[79]); std::vector components; - const CTown & town = CGI->townh->towns[settings.castle]; + const CTown * town = CGI->townh->factions[settings.castle]->town; - for (size_t i=0; i< town.creatures.size(); i++) - components.push_back(new CComponent(CComponent::creature, town.creatures[i].front(), 0, CComponent::tiny)); + for (size_t i=0; i< town->creatures.size(); i++) + components.push_back(new CComponent(CComponent::creature, town->creatures[i].front(), 0, CComponent::tiny)); new CComponentBox(components, Rect(10, 140, pos.w - 20, 140)); } @@ -3450,8 +3449,8 @@ void CBonusSelection::updateBonusSelection() picName = graphics->ERMUtoPicture[faction][buildID]; picNumber = -1; - if (vstd::contains(CGI->townh->towns[faction].buildings, buildID)) - desc = CGI->townh->towns[faction].buildings.find(buildID)->second->Name(); + if (vstd::contains(CGI->townh->factions[faction]->town->buildings, buildID)) + desc = CGI->townh->factions[faction]->town->buildings.find(buildID)->second->Name(); } break; case CScenarioTravel::STravelBonus::ARTIFACT: diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 3837a9e11..9348edb0b 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -177,7 +177,7 @@ void CTownTooltip::init(const InfoAboutTown &town) if(town.details->customRes)//silo is built { - if (town.tType->primaryRes == 127 )// wood & ore + if (town.tType->primaryRes == Res::WOOD_AND_ORE )// wood & ore { new CAnimImage("SMALRES", Res::WOOD, 0, 7, 75); new CAnimImage("SMALRES", Res::ORE , 0, 7, 88); @@ -921,7 +921,7 @@ const std::vector CComponent::getFileName() case spell: return gen(spellsArr); case morale: return gen(moraleArr); case luck: return gen(luckArr); - case building: return std::vector(4, CGI->townh->towns[subtype].clientInfo.buildingsIcons); + case building: return std::vector(4, CGI->townh->factions[subtype]->town->clientInfo.buildingsIcons); case hero: return gen(heroArr); case flag: return gen(flagArr); } @@ -964,7 +964,7 @@ std::string CComponent::getDescription() case spell: return CGI->spellh->spells[subtype]->descriptions[val]; case morale: return CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)]; case luck: return CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)]; - case building: return CGI->townh->towns[subtype].buildings[BuildingID(val)]->Description(); + case building: return CGI->townh->factions[subtype]->town->buildings[BuildingID(val)]->Description(); case hero: return CGI->heroh->heroes[subtype]->name; case flag: return ""; } @@ -996,7 +996,7 @@ std::string CComponent::getSubtitleInternal() case spell: return CGI->spellh->spells[subtype]->name; case morale: return ""; case luck: return ""; - case building: return CGI->townh->towns[subtype].buildings[BuildingID(val)]->Name(); + case building: return CGI->townh->factions[subtype]->town->buildings[BuildingID(val)]->Name(); case hero: return CGI->heroh->heroes[subtype]->name; case flag: return CGI->generaltexth->capColors[subtype]; } @@ -1317,12 +1317,12 @@ CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool An TFaction faction = cre->faction; - assert(vstd::contains(CGI->townh->factions, cre->faction)); + assert(CGI->townh->factions.size() > faction); if(Big) - bg = new CPicture(CGI->townh->factions[faction].creatureBg130); + bg = new CPicture(CGI->townh->factions[faction]->creatureBg130); else - bg = new CPicture(CGI->townh->factions[faction].creatureBg120); + bg = new CPicture(CGI->townh->factions[faction]->creatureBg120); bg->needRefresh = true; anim = new CCreatureAnim(0, 0, cre->animDefName, Rect()); anim->clipRect(cre->isDoubleWide()?170:150, 155, bg->pos.w, bg->pos.h); @@ -2568,14 +2568,14 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan switch (mode) { break; case EMarketMode::CREATURE_RESOURCE: - title = CGI->townh->towns[ETownType::STRONGHOLD].buildings[BuildingID::FREELANCERS_GUILD]->Name(); + title = CGI->townh->factions[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->Name(); break; case EMarketMode::RESOURCE_ARTIFACT: - title = CGI->townh->towns[market->o->subID].buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); + title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); sliderNeeded = false; break; case EMarketMode::ARTIFACT_RESOURCE: - title = CGI->townh->towns[market->o->subID].buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); + title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); sliderNeeded = false; break; default: @@ -5239,7 +5239,7 @@ CPuzzleWindow::CPuzzleWindow(const int3 &GrailPos, double discoveredRatio): int faction = LOCPLINT->cb->getStartInfo()->playerInfos.find(LOCPLINT->playerID)->second.castle; - auto & puzzleMap = CGI->townh->factions[faction].puzzleMap; + auto & puzzleMap = CGI->townh->factions[faction]->puzzleMap; for(int g=0; go->ID == Obj::TOWN) - titlePic = new CAnimImage(CGI->townh->towns[ETownType::CONFLUX].clientInfo.buildingsIcons, BuildingID::MAGIC_UNIVERSITY); + titlePic = new CAnimImage(CGI->townh->factions[ETownType::CONFLUX]->town->clientInfo.buildingsIcons, BuildingID::MAGIC_UNIVERSITY); else titlePic = new CPicture("UNIVBLDG"); diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index ce6ff924d..0ba7df817 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -762,7 +762,7 @@ void SystemMessage::applyCl( CClient *cl ) std::ostringstream str; str << "System message: " << text; - logNetwork->debugStream() << str.str(); + logNetwork->errorStream() << str.str(); // usually used to receive error messages from server if(LOCPLINT) LOCPLINT->cingconsole->print(str.str()); } diff --git a/client/battle/CBattleInterface.cpp b/client/battle/CBattleInterface.cpp index a91284450..5a3fb0648 100644 --- a/client/battle/CBattleInterface.cpp +++ b/client/battle/CBattleInterface.cpp @@ -3570,7 +3570,7 @@ std::string CBattleInterface::SiegeHelper::getSiegeName(ui16 what, ui16 additInf return prefix + "BACK.BMP"; case 1: //background wall { - switch(town->town->typeID) + switch(town->town->faction->index) { case 5: case 4: case 1: case 6: return prefix + "TPW1.BMP"; diff --git a/config/artifacts.json b/config/artifacts.json index 3c93b3cea..e184386c9 100644 --- a/config/artifacts.json +++ b/config/artifacts.json @@ -1,2646 +1,2643 @@ { - "artifacts" : + "spellBook": { - "spellBook": - { - "id" : 0, - "type" : ["HERO"] - }, - "spellScroll": - { - "id" : 1, - "type" : ["HERO"] - }, - "grail": - { - "id" : 2, - "type" : ["HERO"] - }, - "catapult": - { - "id" : 3, - "type" : ["HERO"] - }, - "ballista": - { - "id" : 4, - "type" : ["HERO"] - }, - "ammoCart": - { - "id" : 5, - "type" : ["HERO"] - }, - "firstAidTent": - { - "id" : 6, - "type" : ["HERO"] - }, - "centaurAxe": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 7, - "type" : ["HERO"] - }, - "blackshardOfTheDeadKnight": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 8, - "type" : ["HERO"] - }, - "greaterGnollsFlail": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 9, - "type" : ["HERO"] - }, - "ogresClubOfHavoc": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 10, - "type" : ["HERO"] - }, - "swordOfHellfire": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 11, - "type" : ["HERO"] - }, - "titansGladius": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 12, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : -3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 12, - "type" : ["HERO"] - }, - "shieldOfTheDwarvenLords": - { - "bonuses" : [ - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 13, - "type" : ["HERO"] - }, - "shieldOfTheYawningDead": - { - "bonuses" : [ - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 14, - "type" : ["HERO"] - }, - "bucklerOfTheGnollKing": - { - "bonuses" : [ - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 15, - "type" : ["HERO"] - }, - "targOfTheRampagingOgre": - { - "bonuses" : [ - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 16, - "type" : ["HERO"] - }, - "shieldOfTheDamned": - { - "bonuses" : [ - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 17, - "type" : ["HERO"] - }, - "sentinelsShield": - { - "bonuses" : [ - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 12, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : 0, - "type" : "PRIMARY_SKILL", - "val" : -3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 18, - "type" : ["HERO"] - }, - "helmOfTheAlabasterUnicorn": - { - "bonuses" : [ - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 19, - "type" : ["HERO"] - }, - "skullHelmet": - { - "bonuses" : [ - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 20, - "type" : ["HERO"] - }, - "helmOfChaos": - { - "bonuses" : [ - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 21, - "type" : ["HERO"] - }, - "crownOfTheSupremeMagi": - { - "bonuses" : [ - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 22, - "type" : ["HERO"] - }, - "hellstormHelmet": - { - "bonuses" : [ - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 23, - "type" : ["HERO"] - }, - "thunderHelmet": - { - "bonuses" : [ - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 10, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : -2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 24, - "type" : ["HERO"] - }, - "breastplateOfPetrifiedWood": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 25, - "type" : ["HERO"] - }, - "ribCage": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 26, - "type" : ["HERO"] - }, - "scalesOfTheGreaterBasilisk": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 27, - "type" : ["HERO"] - }, - "tunicOfTheCyclopsKing": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 28, - "type" : ["HERO"] - }, - "breastplateOfBrimstone": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 29, - "type" : ["HERO"] - }, - "titansCuirass": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 10, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : -2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 30, - "type" : ["HERO"] - }, - "armorOfWonder": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 31, - "type" : ["HERO"] - }, - "sandalsOfTheSaint": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 32, - "type" : ["HERO"] - }, - "celestialNecklaceOfBliss": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 33, - "type" : ["HERO"] - }, - "lionsShieldOfCourage": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 34, - "type" : ["HERO"] - }, - "swordOfJudgement": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 35, - "type" : ["HERO"] - }, - "helmOfHeavenlyEnlightenment": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 36, - "type" : ["HERO"] - }, - "quietEyeOfTheDragon": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 37, - "type" : ["HERO"] - }, - "redDragonFlameTongue": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 38, - "type" : ["HERO"] - }, - "dragonScaleShield": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 39, - "type" : ["HERO"] - }, - "dragonScaleArmor": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 40, - "type" : ["HERO"] - }, - "dragonboneGreaves": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 41, - "type" : ["HERO"] - }, - "dragonWingTabard": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 42, - "type" : ["HERO"] - }, - "necklaceOfDragonteeth": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 43, - "type" : ["HERO"] - }, - "crownOfDragontooth": - { - "bonuses" : [ - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 44, - "type" : ["HERO"] - }, - "stillEyeOfTheDragon": - { - "bonuses" : [ - { - "type" : "MORALE", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "LUCK", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 45, - "type" : ["HERO"] - }, - "cloverOfFortune": - { - "bonuses" : [ - { - "type" : "LUCK", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 46, - "type" : ["HERO"] - }, - "cardsOfProphecy": - { - "bonuses" : [ - { - "type" : "LUCK", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 47, - "type" : ["HERO"] - }, - "ladybirdOfLuck": - { - "bonuses" : [ - { - "type" : "LUCK", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 48, - "type" : ["HERO"] - }, - "badgeOfCourage": - { - "bonuses" : [ - { - "type" : "MORALE", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "MIND_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 49, - "type" : ["HERO"] - }, - "crestOfValor": - { - "bonuses" : [ - { - "type" : "MORALE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 50, - "type" : ["HERO"] - }, - "glyphOfGallantry": - { - "bonuses" : [ - { - "type" : "MORALE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 51, - "type" : ["HERO"] - }, - "speculum": - { - "bonuses" : [ - { - "type" : "SIGHT_RADIOUS", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 52, - "type" : ["HERO"] - }, - "spyglass": - { - "bonuses" : [ - { - "type" : "SIGHT_RADIOUS", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 53, - "type" : ["HERO"] - }, - "amuletOfTheUndertaker": - { - "bonuses" : [ - { - "subtype" : 12, - "type" : "SECONDARY_SKILL_PREMY", - "val" : 5, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 54, - "type" : ["HERO"] - }, - "vampiresCowl": - { - "bonuses" : [ - { - "subtype" : 12, - "type" : "SECONDARY_SKILL_PREMY", - "val" : 10, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 55, - "type" : ["HERO"] - }, - "deadMansBoots": - { - "bonuses" : [ - { - "subtype" : 12, - "type" : "SECONDARY_SKILL_PREMY", - "val" : 15, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 56, - "type" : ["HERO"] - }, - "garnitureOfInterference": - { - "bonuses" : [ - { - "subtype" : 0, - "type" : "MAGIC_RESISTANCE", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 57, - "type" : ["HERO"] - }, - "surcoatOfCounterpoise": - { - "bonuses" : [ - { - "subtype" : 0, - "type" : "MAGIC_RESISTANCE", - "val" : 10, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 58, - "type" : ["HERO"] - }, - "bootsOfPolarity": - { - "bonuses" : [ - { - "subtype" : 0, - "type" : "MAGIC_RESISTANCE", - "val" : 15, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 59, - "type" : ["HERO"] - }, - "bowOfElvenCherrywood": - { - "bonuses" : [ - { - "subtype" : "skill.archery", - "type" : "SECONDARY_SKILL_PREMY", - "val" : 5, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 60, - "type" : ["HERO"] - }, - "bowstringOfTheUnicornsMane": - { - "bonuses" : [ - { - "subtype" : "skill.archery", - "type" : "SECONDARY_SKILL_PREMY", - "val" : 10, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 61, - "type" : ["HERO"] - }, - "angelFeatherArrows": - { - "bonuses" : [ - { - "subtype" : "skill.archery", - "type" : "SECONDARY_SKILL_PREMY", - "val" : 15, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 62, - "type" : ["HERO"] - }, - "birdOfPerception": - { - "bonuses" : [ - { - "subtype" : "skill.eagleEye", - "type" : "SECONDARY_SKILL_PREMY", - "val" : 5, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 63, - "type" : ["HERO"] - }, - "stoicWatchman": - { - "bonuses" : [ - { - "subtype" : "skill.eagleEye", - "type" : "SECONDARY_SKILL_PREMY", - "val" : 10, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 64, - "type" : ["HERO"] - }, - "emblemOfCognizance": - { - "bonuses" : [ - { - "subtype" : "skill.eagleEye", - "type" : "SECONDARY_SKILL_PREMY", - "val" : 15, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 65, - "type" : ["HERO"] - }, - "statesmansMedal": - { - "bonuses" : [ - { - "type" : "SURRENDER_DISCOUNT", - "val" : 10, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 66, - "type" : ["HERO"] - }, - "diplomatsRing": - { - "bonuses" : [ - { - "type" : "SURRENDER_DISCOUNT", - "val" : 10, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 67, - "type" : ["HERO"] - }, - "ambassadorsSash": - { - "bonuses" : [ - { - "type" : "SURRENDER_DISCOUNT", - "val" : 10, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 68, - "type" : ["HERO"] - }, - "ringOfTheWayfarer": - { - "bonuses" : [ - { - "type" : "STACKS_SPEED", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 69, - "type" : ["HERO"] - }, - "equestriansGloves": - { - "bonuses" : [ - { - "type" : "LAND_MOVEMENT", - "val" : 300, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 70, - "type" : ["HERO"] - }, - "necklaceOfOceanGuidance": - { - "bonuses" : [ - { - "type" : "SEA_MOVEMENT", - "val" : 1000, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 71, - "type" : ["HERO"] - }, - "angelWings": - { - "bonuses" : [ - { - "subtype" : 1, - "type" : "FLYING_MOVEMENT", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 72, - "type" : ["HERO"] - }, - "charmOfMana": - { - "bonuses" : [ - { - "type" : "MANA_REGENERATION", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 73, - "type" : ["HERO"] - }, - "talismanOfMana": - { - "bonuses" : [ - { - "type" : "MANA_REGENERATION", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 74, - "type" : ["HERO"] - }, - "mysticOrbOfMana": - { - "bonuses" : [ - { - "type" : "MANA_REGENERATION", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 75, - "type" : ["HERO"] - }, - "collarOfConjuring": - { - "bonuses" : [ - { - "type" : "SPELL_DURATION", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 76, - "type" : ["HERO"] - }, - "ringOfConjuring": - { - "bonuses" : [ - { - "type" : "SPELL_DURATION", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 77, - "type" : ["HERO"] - }, - "capeOfConjuring": - { - "bonuses" : [ - { - "type" : "SPELL_DURATION", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 78, - "type" : ["HERO"] - }, - "orbOfTheFirmament": - { - "bonuses" : [ - { - "type" : "AIR_SPELL_DMG_PREMY", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 79, - "type" : ["HERO"] - }, - "orbOfSilt": - { - "bonuses" : [ - { - "type" : "EARTH_SPELL_DMG_PREMY", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 80, - "type" : ["HERO"] - }, - "orbOfTempestuousFire": - { - "bonuses" : [ - { - "type" : "FIRE_SPELL_DMG_PREMY", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 81, - "type" : ["HERO"] - }, - "orbOfDrivingRain": - { - "bonuses" : [ - { - "type" : "WATER_SPELL_DMG_PREMY", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 82, - "type" : ["HERO"] - }, - "recantersCloak": - { - "id" : 83, - "type" : ["HERO"], - "bonuses": [ - { - "type" : "BLOCK_MAGIC_ABOVE", - "val" : 2, - "valueType" : "INDEPENDENT_MIN", - "propagator": "BATTLE_WIDE" - } - ] - }, - "spiritOfOppression": - { - "bonuses" : [ - { - "type" : "BLOCK_MORALE", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 84, - "type" : ["HERO"] - }, - "hourglassOfTheEvilHour": - { - "bonuses" : [ - { - "type" : "BLOCK_LUCK", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 85, - "type" : ["HERO"] - }, - "tomeOfFireMagic": - { - "bonuses" : [ - { - "type" : "FIRE_SPELLS", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 86, - "type" : ["HERO"] - }, - "tomeOfAirMagic": - { - "bonuses" : [ - { - "type" : "AIR_SPELLS", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 87, - "type" : ["HERO"] - }, - "tomeOfWaterMagic": - { - "bonuses" : [ - { - "type" : "WATER_SPELLS", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 88, - "type" : ["HERO"] - }, - "tomeOfEarthMagic": - { - "bonuses" : [ - { - "type" : "EARTH_SPELLS", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 89, - "type" : ["HERO"] - }, - "bootsOfLevitation": - { - "bonuses" : [ - { - "subtype" : 1, - "type" : "WATER_WALKING", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 90, - "type" : ["HERO"] - }, - "goldenBow": - { - "bonuses" : [ - { - "limiters" : ["SHOOTER_ONLY"], - "subtype" : 0, - "type" : "NO_DISTANCE_PENALTY", - "val" : 0, - "valueType" : "ADDITIVE_VALUE" - }, - { - "limiters" : ["SHOOTER_ONLY"], - "subtype" : 0, - "type" : "NO_WALL_PENALTY", - "val" : 0, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 91, - "type" : ["HERO"] - }, - "sphereOfPermanence": - { - "bonuses" : [ - { - "subtype" : 35, - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 92, - "type" : ["HERO"] - }, - "orbOfVulnerability": - { - "bonuses" : [ - { - "type" : "NEGATE_ALL_NATURAL_IMMUNITIES", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 93, - "type" : ["HERO"] - }, - "ringOfVitality": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 94, - "type" : ["HERO"] - }, - "ringOfLife": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 95, - "type" : ["HERO"] - }, - "vialOfLifeblood": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 96, - "type" : ["HERO"] - }, - "necklaceOfSwiftness": - { - "bonuses" : [ - { - "type" : "STACKS_SPEED", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 97, - "type" : ["HERO"] - }, - "bootsOfSpeed": - { - "bonuses" : [ - { - "type" : "LAND_MOVEMENT", - "val" : 600, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 98, - "type" : ["HERO"] - }, - "capeOfVelocity": - { - "bonuses" : [ - { - "type" : "STACKS_SPEED", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 99, - "type" : ["HERO"] - }, - "pendantOfDispassion": - { - "bonuses" : [ - { - "subtype" : "spell.berserk", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 100, - "type" : ["HERO"] - }, - "pendantOfSecondSight": - { - "bonuses" : [ - { - "subtype" : "spell.blind", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 101, - "type" : ["HERO"] - }, - "pendantOfHoliness": - { - "bonuses" : [ - { - "subtype" : "spell.curse", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 102, - "type" : ["HERO"] - }, - "pendantOfLife": - { - "bonuses" : [ - { - "subtype" : "spell.deathRipple", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 103, - "type" : ["HERO"] - }, - "pendantOfDeath": - { - "bonuses" : [ - { - "limiters" : ["IS_UNDEAD"], - "subtype" : "spell.destroyUndead", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 104, - "type" : ["HERO"] - }, - "pendantOfFreeWill": - { - "bonuses" : [ - { - "subtype" : "spell.hypnotize", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 105, - "type" : ["HERO"] - }, - "pendantOfNegativity": - { - "bonuses" : [ - { - "subtype" : "spell.lightningBolt", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.chainLightning", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 106, - "type" : ["HERO"] - }, - "pendantOfTotalRecall": - { - "bonuses" : [ - { - "subtype" : "spell.forgetfulness", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 107, - "type" : ["HERO"] - }, - "pendantOfCourage": - { - "bonuses" : [ - { - "type" : "MORALE", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "LUCK", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 108, - "type" : ["HERO"] - }, - "everflowingCrystalCloak": - { - "bonuses" : [ - { - "subtype" : "resource.crystal", - "type" : "GENERATE_RESOURCE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 109, - "type" : ["HERO"] - }, - "ringOfInfiniteGems": - { - "bonuses" : [ - { - "subtype" : "resource.gems", - "type" : "GENERATE_RESOURCE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 110, - "type" : ["HERO"] - }, - "everpouringVialOfMercury": - { - "bonuses" : [ - { - "subtype" : "resource.mercury", - "type" : "GENERATE_RESOURCE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 111, - "type" : ["HERO"] - }, - "inexhaustibleCartOfOre": - { - "bonuses" : [ - { - "subtype" : "resource.ore", - "type" : "GENERATE_RESOURCE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 112, - "type" : ["HERO"] - }, - "eversmokingRingOfSulfur": - { - "bonuses" : [ - { - "subtype" : "resource.sulfur", - "type" : "GENERATE_RESOURCE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 113, - "type" : ["HERO"] - }, - "inexhaustibleCartOfLumber": - { - "bonuses" : [ - { - "subtype" : "resource.wood", - "type" : "GENERATE_RESOURCE", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 114, - "type" : ["HERO"] - }, - "endlessSackOfGold": - { - "bonuses" : [ - { - "subtype" : "resource.gold", - "type" : "GENERATE_RESOURCE", - "val" : 1000, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 115, - "type" : ["HERO"] - }, - "endlessBagOfGold": - { - "bonuses" : [ - { - "subtype" : "resource.gold", - "type" : "GENERATE_RESOURCE", - "val" : 750, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 116, - "type" : ["HERO"] - }, - "endlessPurseOfGold": - { - "bonuses" : [ - { - "subtype" : "resource.gold", - "type" : "GENERATE_RESOURCE", - "val" : 500, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 117, - "type" : ["HERO"] - }, - "legsOfLegion": - { - "id" : 118, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "CREATURE_GROWTH", - "subtype" : 2, - "val" : 5, - "propagator": "VISITED_TOWN_AND_VISITOR" - } - ] - }, - "loinsOfLegion": - { - "id" : 119, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "CREATURE_GROWTH", - "subtype" : 3, - "val" : 4, - "propagator": "VISITED_TOWN_AND_VISITOR" - } - ] - }, - "torsoOfLegion": - { - "id" : 120, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "CREATURE_GROWTH", - "subtype" : 4, - "val" : 3, - "propagator": "VISITED_TOWN_AND_VISITOR" - } - ] - }, - "armsOfLegion": - { - "id" : 121, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "CREATURE_GROWTH", - "subtype" : 5, - "val" : 2, - "propagator": "VISITED_TOWN_AND_VISITOR" - } - ] - }, - "headOfLegion": - { - "id" : 122, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "CREATURE_GROWTH", - "subtype" : 6, - "val" : 1, - "propagator": "VISITED_TOWN_AND_VISITOR" - } - ] - }, - "seaCaptainsHat": - { - "bonuses" : [ - { - "type" : "WHIRLPOOL_PROTECTION", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "SEA_MOVEMENT", - "val" : 500, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.summonBoat", - "type" : "SPELL", - "val" : 3, - "valueType" : "INDEPENDENT_MAX" - }, - { - "subtype" : "spell.scuttleBoat", - "type" : "SPELL", - "val" : 3, - "valueType" : "INDEPENDENT_MAX" - } - ], - "id" : 123, - "type" : ["HERO"] - }, - "spellbindersHat": - { - "bonuses" : [ - { - "subtype" : 5, - "type" : "SPELLS_OF_LEVEL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 124, - "type" : ["HERO"] - }, - "shacklesOfWar": - { - "id" : 125, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "BATTLE_NO_FLEEING", - "propagator": "BATTLE_WIDE" - } - ] - }, - "orbOfInhibition": - { - "id" : 126, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "BLOCK_ALL_MAGIC", - "propagator": "BATTLE_WIDE" - } - ] - }, - "vialOfDragonBlood": - { - "bonuses" : [ - { - "limiters" : ["DRAGON_NATURE"], - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - }, - { - "limiters" : ["DRAGON_NATURE"], - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 5, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 127, - "type" : ["HERO"] - }, - "armageddonsBlade": - { - "bonuses" : [ - { - "subtype" : "spell.armageddon", - "type" : "SPELL", - "val" : 3, - "valueType" : "INDEPENDENT_MAX" - }, - { - "subtype" : "spell.armageddon", - "type" : "SPELL_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 3, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 128, - "type" : ["HERO"] - }, - "angelicAlliance": - { - "bonuses" : [ - { - "type" : "NONEVIL_ALIGNMENT_MIX", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.prayer", - "type" : "OPENING_BATTLE_SPELL", - "val" : 10, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 129, - "type" : ["HERO"], - "components": - [ - "armorOfWonder", - "sandalsOfTheSaint", - "celestialNecklaceOfBliss", - "lionsShieldOfCourage", - "swordOfJudgement", - "helmOfHeavenlyEnlightenment" - ] - }, - "cloakOfTheUndeadKing": - { - "bonuses" : [ - { - "type" : "IMPROVED_NECROMANCY", //TODO: more flexible? - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 130, - "type" : ["HERO"], - "components": - [ - "amuletOfTheUndertaker", - "vampiresCowl", - "deadMansBoots" - ] - }, - "elixirOfLife": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 25, - "valueType" : "PERCENT_TO_BASE" - }, - { - "type" : "HP_REGENERATION", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 131, - "type" : ["HERO"], - "components": - [ - "ringOfVitality", - "ringOfLife", - "vialOfLifeblood" - ] - }, - "armorOfTheDamned": - { - "bonuses" : [ - { - "subtype" : "spell.slow", - "type" : "OPENING_BATTLE_SPELL", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.curse", - "type" : "OPENING_BATTLE_SPELL", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.weakness", - "type" : "OPENING_BATTLE_SPELL", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.misfortune", - "type" : "OPENING_BATTLE_SPELL", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 132, - "type" : ["HERO"], - "components": - [ - "blackshardOfTheDeadKnight", - "shieldOfTheYawningDead", - "skullHelmet", - "ribCage" - ] - }, - "statueOfLegion": - { - "id" : 133, - "type" : ["HERO"], - "components": - [ - "legsOfLegion", - "loinsOfLegion", - "torsoOfLegion", - "armsOfLegion", - "headOfLegion" - ], - "bonuses" : [ - { - "type" : "CREATURE_GROWTH_PERCENT", - "val" : 50, - "propagator": "PLAYER_PROPAGATOR" - } - ] - }, - "powerOfTheDragonFather": - { - "id" : 134, - "type" : ["HERO"], - "bonuses" : [ - { - "type" : "LEVEL_SPELL_IMMUNITY", - "val" : 4, - "valueType" : "INDEPENDENT_MAX" - }, - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.defence", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.spellpower", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "primSkill.knowledge", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "components": - [ - "quietEyeOfTheDragon", - "redDragonFlameTongue", - "dragonScaleShield", - "dragonScaleArmor", - "dragonboneGreaves", - "dragonWingTabard", - "necklaceOfDragonteeth", - "crownOfDragontooth", - "stillEyeOfTheDragon" - ] - }, - "titansThunder": - { - "bonuses" : [ - { - "subtype" : "spell.titanBolt", - "type" : "SPELL", - "val" : 3, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 135, - "type" : ["HERO"], - "components": - [ - "titansGladius", - "sentinelsShield", - "thunderHelmet", - "titansCuirass" - ] - }, - "admiralsHat": - { - "bonuses" : [ - { - "type" : "FREE_SHIP_BOARDING", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 136, - "type" : ["HERO"], - "components": - [ - "necklaceOfOceanGuidance", - "seaCaptainsHat" - ] - }, - "bowOfTheSharpshooter": - { - "bonuses" : [ - { - "limiters" : ["SHOOTER_ONLY"], - "subtype" : 0, - "type" : "NO_DISTANCE_PENALTY", - "val" : 0, - "valueType" : "ADDITIVE_VALUE" - }, - { - "limiters" : ["SHOOTER_ONLY"], - "subtype" : 0, - "type" : "NO_WALL_PENALTY", - "val" : 0, - "valueType" : "ADDITIVE_VALUE" - }, - { - "limiters" : ["SHOOTER_ONLY"], - "subtype" : 0, - "type" : "FREE_SHOOTING", - "val" : 0, - "valueType" : "ADDITIVE_VALUE" - } - ], - "id" : 137, - "type" : ["HERO"], - "components": - [ - "bowOfElvenCherrywood", - "bowstringOfTheUnicornsMane", - "angelFeatherArrows" - ] - }, - "wizardsWell": - { - "bonuses" : [ - { - "type" : "FULL_MANA_REGENERATION", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 138, - "type" : ["HERO"], - "components": - [ - "charmOfMana", - "talismanOfMana", - "mysticOrbOfMana" - ] - }, - "ringOfTheMagi": - { - "bonuses" : [ - { - "type" : "SPELL_DURATION", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 139, - "type" : ["HERO"], - "components": - [ - "collarOfConjuring", - "ringOfConjuring", - "capeOfConjuring" - ] - }, - "cornucopia": - { - "bonuses" : [ - { - "subtype" : "resource.crystal", - "type" : "GENERATE_RESOURCE", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "resource.gems", - "type" : "GENERATE_RESOURCE", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "resource.mercury", - "type" : "GENERATE_RESOURCE", - "val" : 4, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "resource.sulfur", - "type" : "GENERATE_RESOURCE", - "val" : 4, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 140, - "type" : ["HERO"], - "components": - [ - "everflowingCrystalCloak", - "ringOfInfiniteGems", - "everpouringVialOfMercury", - "eversmokingRingOfSulfur" - ] - }, - "magicWand": - { - "bonuses" : [ - { - "type" : "CASTS", - "val" : 10, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.implosion", - "type" : "SPELLCASTER", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "spell.fireball", - "type" : "SPELLCASTER", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "RANDOM_SPELLCASTER", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : "creature.vampireLord", - "type" : "DAEMON_SUMMONING", - "val" : 10, - "valueType" : "BASE_NUMBER" - }, - { - "addInfo" : 2, - "subtype" : "spell.lightningBolt", - "type" : "ENCHANTER", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : 1, - "type" : "REBIRTH", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "MANA_DRAIN", - "val" : 10, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "HEALER", - "val" : 25, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 141, - "type" : ["CREATURE"] - }, - "goldTowerArrow": - { - "bonuses" : [ - { - "type" : "NO_DISTANCE_PENALTY", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "ADDITIONAL_ATTACK", - "val" : 2, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : 22, - "type" : "SPELL_LIKE_ATTACK", - "val" : 1, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "CATAPULT", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "ACID_BREATH", - "val" : 20, - "valueType" : "BASE_NUMBER" - }, - { - "subtype" : 0, - "type" : "SHOTS", - "val" : 200, - "valueType" : "PERCENT_TO_BASE" - }, - { - "addInfo" : 1, - "subtype" : "spell.age", - "type" : "SPELL_BEFORE_ATTACK", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "addInfo" : 1, - "subtype" : "spell.berserk", - "type" : "SPELL_AFTER_ATTACK", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "addInfo" : 1, - "subtype" : "spell.poison", - "type" : "SPELL_AFTER_ATTACK", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "addInfo" : 1, - "subtype" : "spell.disruptingRay", - "type" : "SPELL_AFTER_ATTACK", - "val" : 50, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 142, - "type" : ["CREATURE"] - }, - "monstersPower": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 100, - "valueType" : "PERCENT_TO_BASE" - }, - { - "subtype" : 2, - "type" : "CREATURE_DAMAGE", - "val" : 100, - "valueType" : "PERCENT_TO_ALL" - }, - { - "type" : "HP_REGENERATION", - "val" : 50, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "NO_RETALIATION", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "RETURN_AFTER_STRIKE", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "ATTACKS_ALL_ADJACENT", - "val" : 0, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "SPELL_RESISTANCE_AURA", - "val" : 100, - "valueType" : "BASE_NUMBER" - }, - { - "type" : "DIRECT_DAMAGE_IMMUNITY", - "val" : 0, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 143, - "type" : ["CREATURE"] - }, - "art144": - { - "id" : 144, - "type" : ["HERO"] - }, - "art145": - { - "id" : 145, - "type" : ["HERO"] - }, - "axeOfSmashing": //TODO: move growing bonuses to this config, someday - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 146, - "type" : ["COMMANDER"], - "growing": + "index" : 0, + "type" : ["HERO"] + }, + "spellScroll": + { + "index" : 1, + "type" : ["HERO"] + }, + "grail": + { + "index" : 2, + "type" : ["HERO"] + }, + "catapult": + { + "index" : 3, + "type" : ["HERO"] + }, + "ballista": + { + "index" : 4, + "type" : ["HERO"] + }, + "ammoCart": + { + "index" : 5, + "type" : ["HERO"] + }, + "firstAidTent": + { + "index" : 6, + "type" : ["HERO"] + }, + "centaurAxe": + { + "bonuses" : [ { - "bonusesPerLevel": - [ - { - "level": 6, - "bonus": - { - "type" : "PRIMARY_SKILL", - "subtype" : "primSkill.attack", - "val" : 1 - } - } - ] + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" } - }, - "mithrilMail": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 12, - "valueType" : "PERCENT_TO_ALL" - } - ], - "id" : 147, - "type" : ["COMMANDER"], - "growing": + ], + "index" : 7, + "type" : ["HERO"] + }, + "blackshardOfTheDeadKnight": + { + "bonuses" : [ { - "bonusesPerLevel": - [ - { - "level": 1, - "bonus": - { - "type" : "STACK_HEALTH", - "val" : 1 - } - } - ] + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" } - }, - "swordOfSharpness": - { - "bonuses" : [ - { - "subtype" : 0, - "type" : "CREATURE_DAMAGE", - "val" : 12, - "valueType" : "PERCENT_TO_ALL" - } - ], - "id" : 148, - "type" : ["COMMANDER"], - "growing": + ], + "index" : 8, + "type" : ["HERO"] + }, + "greaterGnollsFlail": + { + "bonuses" : [ { - "bonusesPerLevel": - [ - { - "level": 1, - "bonus": - { - "type" : "CREATURE_DAMAGE", - "val" : 1 - } - } - ] + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" } - }, - "helmOfImmortality": //TODO: implement - { - "id" : 149, - "type" : ["COMMANDER"] - }, - "pendantOfSorcery": - { - "bonuses" : [ - { - "type" : "CASTS", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 150, - "type" : ["COMMANDER"], - "growing": + ], + "index" : 9, + "type" : ["HERO"] + }, + "ogresClubOfHavoc": + { + "bonuses" : [ { - "bonusesPerLevel": - [ - { - "level": 10, - "bonus": - { - "type" : "CREATURE_ENCHANT_POWER", - "val" : 1 - } - } - ] + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" } - }, - "bootsOfHaste": - { - "bonuses" : [ - { - "type" : "STACKS_SPEED", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 151, - "type" : ["COMMANDER"], - "growing": + ], + "index" : 10, + "type" : ["HERO"] + }, + "swordOfHellfire": + { + "bonuses" : [ { - "bonusesPerLevel": - [ - { - "level": 10, - "bonus": - { - "type" : "STACKS_SPEED", - "val" : 1 - } - } - ] + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" } - }, - "bowOfSeeking": - { - "id" : 152, - "type" : ["COMMANDER"], - "growing": + ], + "index" : 11, + "type" : ["HERO"] + }, + "titansGladius": + { + "bonuses" : [ { - "thresholdBonuses": - [ - { - "level": 5, - "bonus": - { - "type" : "SHOOTER" - } - }, - { - "level": 25, - "bonus": - { - "type" : "NO_WALL_PENALTY" - } - }, - { - "level": 50, - "bonus": - { - "type" : "NO_DISTANCE_PENALTY" - } - } - ] - } - }, - "dragonEyeRing": //TODO: implement - { - "id" : 153, - "type" : ["COMMANDER"], - }, - "hardenedShield": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 154, - "type" : ["COMMANDER"], - "growing": + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 12, + "valueType" : "BASE_NUMBER" + }, { - "bonusesPerLevel": - [ - { - "level": 6, - "bonus": - { - "type" : "PRIMARY_SKILL", - "subtype" : "primSkill.defence", - "val" : 1 - } - } - ] + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : -3, + "valueType" : "BASE_NUMBER" } - }, - "slavasRingOfPower": //TODO: implement if possible + ], + "index" : 12, + "type" : ["HERO"] + }, + "shieldOfTheDwarvenLords": + { + "bonuses" : [ + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 13, + "type" : ["HERO"] + }, + "shieldOfTheYawningDead": + { + "bonuses" : [ + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 14, + "type" : ["HERO"] + }, + "bucklerOfTheGnollKing": + { + "bonuses" : [ + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 15, + "type" : ["HERO"] + }, + "targOfTheRampagingOgre": + { + "bonuses" : [ + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 16, + "type" : ["HERO"] + }, + "shieldOfTheDamned": + { + "bonuses" : [ + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 17, + "type" : ["HERO"] + }, + "sentinelsShield": + { + "bonuses" : [ + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 12, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : 0, + "type" : "PRIMARY_SKILL", + "val" : -3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 18, + "type" : ["HERO"] + }, + "helmOfTheAlabasterUnicorn": + { + "bonuses" : [ + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 19, + "type" : ["HERO"] + }, + "skullHelmet": + { + "bonuses" : [ + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 20, + "type" : ["HERO"] + }, + "helmOfChaos": + { + "bonuses" : [ + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 21, + "type" : ["HERO"] + }, + "crownOfTheSupremeMagi": + { + "bonuses" : [ + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 22, + "type" : ["HERO"] + }, + "hellstormHelmet": + { + "bonuses" : [ + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 23, + "type" : ["HERO"] + }, + "thunderHelmet": + { + "bonuses" : [ + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 10, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : -2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 24, + "type" : ["HERO"] + }, + "breastplateOfPetrifiedWood": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 25, + "type" : ["HERO"] + }, + "ribCage": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 26, + "type" : ["HERO"] + }, + "scalesOfTheGreaterBasilisk": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 27, + "type" : ["HERO"] + }, + "tunicOfTheCyclopsKing": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 28, + "type" : ["HERO"] + }, + "breastplateOfBrimstone": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 29, + "type" : ["HERO"] + }, + "titansCuirass": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 10, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : -2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 30, + "type" : ["HERO"] + }, + "armorOfWonder": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 31, + "type" : ["HERO"] + }, + "sandalsOfTheSaint": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 32, + "type" : ["HERO"] + }, + "celestialNecklaceOfBliss": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 33, + "type" : ["HERO"] + }, + "lionsShieldOfCourage": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 34, + "type" : ["HERO"] + }, + "swordOfJudgement": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 35, + "type" : ["HERO"] + }, + "helmOfHeavenlyEnlightenment": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 36, + "type" : ["HERO"] + }, + "quietEyeOfTheDragon": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 37, + "type" : ["HERO"] + }, + "redDragonFlameTongue": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 38, + "type" : ["HERO"] + }, + "dragonScaleShield": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 39, + "type" : ["HERO"] + }, + "dragonScaleArmor": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 40, + "type" : ["HERO"] + }, + "dragonboneGreaves": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 41, + "type" : ["HERO"] + }, + "dragonWingTabard": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 42, + "type" : ["HERO"] + }, + "necklaceOfDragonteeth": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 43, + "type" : ["HERO"] + }, + "crownOfDragontooth": + { + "bonuses" : [ + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 44, + "type" : ["HERO"] + }, + "stillEyeOfTheDragon": + { + "bonuses" : [ + { + "type" : "MORALE", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "LUCK", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 45, + "type" : ["HERO"] + }, + "cloverOfFortune": + { + "bonuses" : [ + { + "type" : "LUCK", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 46, + "type" : ["HERO"] + }, + "cardsOfProphecy": + { + "bonuses" : [ + { + "type" : "LUCK", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 47, + "type" : ["HERO"] + }, + "ladybirdOfLuck": + { + "bonuses" : [ + { + "type" : "LUCK", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 48, + "type" : ["HERO"] + }, + "badgeOfCourage": + { + "bonuses" : [ + { + "type" : "MORALE", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "MIND_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 49, + "type" : ["HERO"] + }, + "crestOfValor": + { + "bonuses" : [ + { + "type" : "MORALE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 50, + "type" : ["HERO"] + }, + "glyphOfGallantry": + { + "bonuses" : [ + { + "type" : "MORALE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 51, + "type" : ["HERO"] + }, + "speculum": + { + "bonuses" : [ + { + "type" : "SIGHT_RADIOUS", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 52, + "type" : ["HERO"] + }, + "spyglass": + { + "bonuses" : [ + { + "type" : "SIGHT_RADIOUS", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 53, + "type" : ["HERO"] + }, + "amuletOfTheUndertaker": + { + "bonuses" : [ + { + "subtype" : 12, + "type" : "SECONDARY_SKILL_PREMY", + "val" : 5, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 54, + "type" : ["HERO"] + }, + "vampiresCowl": + { + "bonuses" : [ + { + "subtype" : 12, + "type" : "SECONDARY_SKILL_PREMY", + "val" : 10, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 55, + "type" : ["HERO"] + }, + "deadMansBoots": + { + "bonuses" : [ + { + "subtype" : 12, + "type" : "SECONDARY_SKILL_PREMY", + "val" : 15, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 56, + "type" : ["HERO"] + }, + "garnitureOfInterference": + { + "bonuses" : [ + { + "subtype" : 0, + "type" : "MAGIC_RESISTANCE", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 57, + "type" : ["HERO"] + }, + "surcoatOfCounterpoise": + { + "bonuses" : [ + { + "subtype" : 0, + "type" : "MAGIC_RESISTANCE", + "val" : 10, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 58, + "type" : ["HERO"] + }, + "bootsOfPolarity": + { + "bonuses" : [ + { + "subtype" : 0, + "type" : "MAGIC_RESISTANCE", + "val" : 15, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 59, + "type" : ["HERO"] + }, + "bowOfElvenCherrywood": + { + "bonuses" : [ + { + "subtype" : "skill.archery", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 5, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 60, + "type" : ["HERO"] + }, + "bowstringOfTheUnicornsMane": + { + "bonuses" : [ + { + "subtype" : "skill.archery", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 10, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 61, + "type" : ["HERO"] + }, + "angelFeatherArrows": + { + "bonuses" : [ + { + "subtype" : "skill.archery", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 15, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 62, + "type" : ["HERO"] + }, + "birdOfPerception": + { + "bonuses" : [ + { + "subtype" : "skill.eagleEye", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 5, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 63, + "type" : ["HERO"] + }, + "stoicWatchman": + { + "bonuses" : [ + { + "subtype" : "skill.eagleEye", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 10, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 64, + "type" : ["HERO"] + }, + "emblemOfCognizance": + { + "bonuses" : [ + { + "subtype" : "skill.eagleEye", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 15, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 65, + "type" : ["HERO"] + }, + "statesmansMedal": + { + "bonuses" : [ + { + "type" : "SURRENDER_DISCOUNT", + "val" : 10, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 66, + "type" : ["HERO"] + }, + "diplomatsRing": + { + "bonuses" : [ + { + "type" : "SURRENDER_DISCOUNT", + "val" : 10, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 67, + "type" : ["HERO"] + }, + "ambassadorsSash": + { + "bonuses" : [ + { + "type" : "SURRENDER_DISCOUNT", + "val" : 10, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 68, + "type" : ["HERO"] + }, + "ringOfTheWayfarer": + { + "bonuses" : [ + { + "type" : "STACKS_SPEED", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 69, + "type" : ["HERO"] + }, + "equestriansGloves": + { + "bonuses" : [ + { + "type" : "LAND_MOVEMENT", + "val" : 300, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 70, + "type" : ["HERO"] + }, + "necklaceOfOceanGuidance": + { + "bonuses" : [ + { + "type" : "SEA_MOVEMENT", + "val" : 1000, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 71, + "type" : ["HERO"] + }, + "angelWings": + { + "bonuses" : [ + { + "subtype" : 1, + "type" : "FLYING_MOVEMENT", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 72, + "type" : ["HERO"] + }, + "charmOfMana": + { + "bonuses" : [ + { + "type" : "MANA_REGENERATION", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 73, + "type" : ["HERO"] + }, + "talismanOfMana": + { + "bonuses" : [ + { + "type" : "MANA_REGENERATION", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 74, + "type" : ["HERO"] + }, + "mysticOrbOfMana": + { + "bonuses" : [ + { + "type" : "MANA_REGENERATION", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 75, + "type" : ["HERO"] + }, + "collarOfConjuring": + { + "bonuses" : [ + { + "type" : "SPELL_DURATION", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 76, + "type" : ["HERO"] + }, + "ringOfConjuring": + { + "bonuses" : [ + { + "type" : "SPELL_DURATION", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 77, + "type" : ["HERO"] + }, + "capeOfConjuring": + { + "bonuses" : [ + { + "type" : "SPELL_DURATION", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 78, + "type" : ["HERO"] + }, + "orbOfTheFirmament": + { + "bonuses" : [ + { + "type" : "AIR_SPELL_DMG_PREMY", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 79, + "type" : ["HERO"] + }, + "orbOfSilt": + { + "bonuses" : [ + { + "type" : "EARTH_SPELL_DMG_PREMY", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 80, + "type" : ["HERO"] + }, + "orbOfTempestuousFire": + { + "bonuses" : [ + { + "type" : "FIRE_SPELL_DMG_PREMY", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 81, + "type" : ["HERO"] + }, + "orbOfDrivingRain": + { + "bonuses" : [ + { + "type" : "WATER_SPELL_DMG_PREMY", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 82, + "type" : ["HERO"] + }, + "recantersCloak": + { + "index" : 83, + "type" : ["HERO"], + "bonuses": [ + { + "type" : "BLOCK_MAGIC_ABOVE", + "val" : 2, + "valueType" : "INDEPENDENT_MIN", + "propagator": "BATTLE_WIDE" + } + ] + }, + "spiritOfOppression": + { + "bonuses" : [ + { + "type" : "BLOCK_MORALE", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 84, + "type" : ["HERO"] + }, + "hourglassOfTheEvilHour": + { + "bonuses" : [ + { + "type" : "BLOCK_LUCK", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 85, + "type" : ["HERO"] + }, + "tomeOfFireMagic": + { + "bonuses" : [ + { + "type" : "FIRE_SPELLS", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 86, + "type" : ["HERO"] + }, + "tomeOfAirMagic": + { + "bonuses" : [ + { + "type" : "AIR_SPELLS", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 87, + "type" : ["HERO"] + }, + "tomeOfWaterMagic": + { + "bonuses" : [ + { + "type" : "WATER_SPELLS", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 88, + "type" : ["HERO"] + }, + "tomeOfEarthMagic": + { + "bonuses" : [ + { + "type" : "EARTH_SPELLS", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 89, + "type" : ["HERO"] + }, + "bootsOfLevitation": + { + "bonuses" : [ + { + "subtype" : 1, + "type" : "WATER_WALKING", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 90, + "type" : ["HERO"] + }, + "goldenBow": + { + "bonuses" : [ + { + "limiters" : ["SHOOTER_ONLY"], + "subtype" : 0, + "type" : "NO_DISTANCE_PENALTY", + "val" : 0, + "valueType" : "ADDITIVE_VALUE" + }, + { + "limiters" : ["SHOOTER_ONLY"], + "subtype" : 0, + "type" : "NO_WALL_PENALTY", + "val" : 0, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 91, + "type" : ["HERO"] + }, + "sphereOfPermanence": + { + "bonuses" : [ + { + "subtype" : 35, + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 92, + "type" : ["HERO"] + }, + "orbOfVulnerability": + { + "bonuses" : [ + { + "type" : "NEGATE_ALL_NATURAL_IMMUNITIES", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 93, + "type" : ["HERO"] + }, + "ringOfVitality": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 94, + "type" : ["HERO"] + }, + "ringOfLife": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 95, + "type" : ["HERO"] + }, + "vialOfLifeblood": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 96, + "type" : ["HERO"] + }, + "necklaceOfSwiftness": + { + "bonuses" : [ + { + "type" : "STACKS_SPEED", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 97, + "type" : ["HERO"] + }, + "bootsOfSpeed": + { + "bonuses" : [ + { + "type" : "LAND_MOVEMENT", + "val" : 600, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 98, + "type" : ["HERO"] + }, + "capeOfVelocity": + { + "bonuses" : [ + { + "type" : "STACKS_SPEED", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 99, + "type" : ["HERO"] + }, + "pendantOfDispassion": + { + "bonuses" : [ + { + "subtype" : "spell.berserk", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 100, + "type" : ["HERO"] + }, + "pendantOfSecondSight": + { + "bonuses" : [ + { + "subtype" : "spell.blind", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 101, + "type" : ["HERO"] + }, + "pendantOfHoliness": + { + "bonuses" : [ + { + "subtype" : "spell.curse", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 102, + "type" : ["HERO"] + }, + "pendantOfLife": + { + "bonuses" : [ + { + "subtype" : "spell.deathRipple", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 103, + "type" : ["HERO"] + }, + "pendantOfDeath": + { + "bonuses" : [ + { + "limiters" : ["IS_UNDEAD"], + "subtype" : "spell.destroyUndead", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 104, + "type" : ["HERO"] + }, + "pendantOfFreeWill": + { + "bonuses" : [ + { + "subtype" : "spell.hypnotize", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 105, + "type" : ["HERO"] + }, + "pendantOfNegativity": + { + "bonuses" : [ + { + "subtype" : "spell.lightningBolt", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.chainLightning", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 106, + "type" : ["HERO"] + }, + "pendantOfTotalRecall": + { + "bonuses" : [ + { + "subtype" : "spell.forgetfulness", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 107, + "type" : ["HERO"] + }, + "pendantOfCourage": + { + "bonuses" : [ + { + "type" : "MORALE", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "LUCK", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 108, + "type" : ["HERO"] + }, + "everflowingCrystalCloak": + { + "bonuses" : [ + { + "subtype" : "resource.crystal", + "type" : "GENERATE_RESOURCE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 109, + "type" : ["HERO"] + }, + "ringOfInfiniteGems": + { + "bonuses" : [ + { + "subtype" : "resource.gems", + "type" : "GENERATE_RESOURCE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 110, + "type" : ["HERO"] + }, + "everpouringVialOfMercury": + { + "bonuses" : [ + { + "subtype" : "resource.mercury", + "type" : "GENERATE_RESOURCE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 111, + "type" : ["HERO"] + }, + "inexhaustibleCartOfOre": + { + "bonuses" : [ + { + "subtype" : "resource.ore", + "type" : "GENERATE_RESOURCE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 112, + "type" : ["HERO"] + }, + "eversmokingRingOfSulfur": + { + "bonuses" : [ + { + "subtype" : "resource.sulfur", + "type" : "GENERATE_RESOURCE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 113, + "type" : ["HERO"] + }, + "inexhaustibleCartOfLumber": + { + "bonuses" : [ + { + "subtype" : "resource.wood", + "type" : "GENERATE_RESOURCE", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 114, + "type" : ["HERO"] + }, + "endlessSackOfGold": + { + "bonuses" : [ + { + "subtype" : "resource.gold", + "type" : "GENERATE_RESOURCE", + "val" : 1000, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 115, + "type" : ["HERO"] + }, + "endlessBagOfGold": + { + "bonuses" : [ + { + "subtype" : "resource.gold", + "type" : "GENERATE_RESOURCE", + "val" : 750, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 116, + "type" : ["HERO"] + }, + "endlessPurseOfGold": + { + "bonuses" : [ + { + "subtype" : "resource.gold", + "type" : "GENERATE_RESOURCE", + "val" : 500, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 117, + "type" : ["HERO"] + }, + "legsOfLegion": + { + "index" : 118, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "CREATURE_GROWTH", + "subtype" : 2, + "val" : 5, + "propagator": "VISITED_TOWN_AND_VISITOR" + } + ] + }, + "loinsOfLegion": + { + "index" : 119, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "CREATURE_GROWTH", + "subtype" : 3, + "val" : 4, + "propagator": "VISITED_TOWN_AND_VISITOR" + } + ] + }, + "torsoOfLegion": + { + "index" : 120, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "CREATURE_GROWTH", + "subtype" : 4, + "val" : 3, + "propagator": "VISITED_TOWN_AND_VISITOR" + } + ] + }, + "armsOfLegion": + { + "index" : 121, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "CREATURE_GROWTH", + "subtype" : 5, + "val" : 2, + "propagator": "VISITED_TOWN_AND_VISITOR" + } + ] + }, + "headOfLegion": + { + "index" : 122, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "CREATURE_GROWTH", + "subtype" : 6, + "val" : 1, + "propagator": "VISITED_TOWN_AND_VISITOR" + } + ] + }, + "seaCaptainsHat": + { + "bonuses" : [ + { + "type" : "WHIRLPOOL_PROTECTION", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "SEA_MOVEMENT", + "val" : 500, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.summonBoat", + "type" : "SPELL", + "val" : 3, + "valueType" : "INDEPENDENT_MAX" + }, + { + "subtype" : "spell.scuttleBoat", + "type" : "SPELL", + "val" : 3, + "valueType" : "INDEPENDENT_MAX" + } + ], + "index" : 123, + "type" : ["HERO"] + }, + "spellbindersHat": + { + "bonuses" : [ + { + "subtype" : 5, + "type" : "SPELLS_OF_LEVEL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 124, + "type" : ["HERO"] + }, + "shacklesOfWar": + { + "index" : 125, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "BATTLE_NO_FLEEING", + "propagator": "BATTLE_WIDE" + } + ] + }, + "orbOfInhibition": + { + "index" : 126, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "BLOCK_ALL_MAGIC", + "propagator": "BATTLE_WIDE" + } + ] + }, + "vialOfDragonBlood": + { + "bonuses" : [ + { + "limiters" : ["DRAGON_NATURE"], + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + }, + { + "limiters" : ["DRAGON_NATURE"], + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 127, + "type" : ["HERO"] + }, + "armageddonsBlade": + { + "bonuses" : [ + { + "subtype" : "spell.armageddon", + "type" : "SPELL", + "val" : 3, + "valueType" : "INDEPENDENT_MAX" + }, + { + "subtype" : "spell.armageddon", + "type" : "SPELL_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 3, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 128, + "type" : ["HERO"] + }, + "angelicAlliance": + { + "bonuses" : [ + { + "type" : "NONEVIL_ALIGNMENT_MIX", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.prayer", + "type" : "OPENING_BATTLE_SPELL", + "val" : 10, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 129, + "type" : ["HERO"], + "components": + [ + "armorOfWonder", + "sandalsOfTheSaint", + "celestialNecklaceOfBliss", + "lionsShieldOfCourage", + "swordOfJudgement", + "helmOfHeavenlyEnlightenment" + ] + }, + "cloakOfTheUndeadKing": + { + "bonuses" : [ + { + "type" : "IMPROVED_NECROMANCY", //TODO: more flexible? + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 130, + "type" : ["HERO"], + "components": + [ + "amuletOfTheUndertaker", + "vampiresCowl", + "deadMansBoots" + ] + }, + "elixirOfLife": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 25, + "valueType" : "PERCENT_TO_BASE" + }, + { + "type" : "HP_REGENERATION", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 131, + "type" : ["HERO"], + "components": + [ + "ringOfVitality", + "ringOfLife", + "vialOfLifeblood" + ] + }, + "armorOfTheDamned": + { + "bonuses" : [ + { + "subtype" : "spell.slow", + "type" : "OPENING_BATTLE_SPELL", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.curse", + "type" : "OPENING_BATTLE_SPELL", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.weakness", + "type" : "OPENING_BATTLE_SPELL", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.misfortune", + "type" : "OPENING_BATTLE_SPELL", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 132, + "type" : ["HERO"], + "components": + [ + "blackshardOfTheDeadKnight", + "shieldOfTheYawningDead", + "skullHelmet", + "ribCage" + ] + }, + "statueOfLegion": + { + "index" : 133, + "type" : ["HERO"], + "components": + [ + "legsOfLegion", + "loinsOfLegion", + "torsoOfLegion", + "armsOfLegion", + "headOfLegion" + ], + "bonuses" : [ + { + "type" : "CREATURE_GROWTH_PERCENT", + "val" : 50, + "propagator": "PLAYER_PROPAGATOR" + } + ] + }, + "powerOfTheDragonFather": + { + "index" : 134, + "type" : ["HERO"], + "bonuses" : [ + { + "type" : "LEVEL_SPELL_IMMUNITY", + "val" : 4, + "valueType" : "INDEPENDENT_MAX" + }, + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.defence", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.spellpower", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "primSkill.knowledge", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "components": + [ + "quietEyeOfTheDragon", + "redDragonFlameTongue", + "dragonScaleShield", + "dragonScaleArmor", + "dragonboneGreaves", + "dragonWingTabard", + "necklaceOfDragonteeth", + "crownOfDragontooth", + "stillEyeOfTheDragon" + ] + }, + "titansThunder": + { + "bonuses" : [ + { + "subtype" : "spell.titanBolt", + "type" : "SPELL", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 135, + "type" : ["HERO"], + "components": + [ + "titansGladius", + "sentinelsShield", + "thunderHelmet", + "titansCuirass" + ] + }, + "admiralsHat": + { + "bonuses" : [ + { + "type" : "FREE_SHIP_BOARDING", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 136, + "type" : ["HERO"], + "components": + [ + "necklaceOfOceanGuidance", + "seaCaptainsHat" + ] + }, + "bowOfTheSharpshooter": + { + "bonuses" : [ + { + "limiters" : ["SHOOTER_ONLY"], + "subtype" : 0, + "type" : "NO_DISTANCE_PENALTY", + "val" : 0, + "valueType" : "ADDITIVE_VALUE" + }, + { + "limiters" : ["SHOOTER_ONLY"], + "subtype" : 0, + "type" : "NO_WALL_PENALTY", + "val" : 0, + "valueType" : "ADDITIVE_VALUE" + }, + { + "limiters" : ["SHOOTER_ONLY"], + "subtype" : 0, + "type" : "FREE_SHOOTING", + "val" : 0, + "valueType" : "ADDITIVE_VALUE" + } + ], + "index" : 137, + "type" : ["HERO"], + "components": + [ + "bowOfElvenCherrywood", + "bowstringOfTheUnicornsMane", + "angelFeatherArrows" + ] + }, + "wizardsWell": + { + "bonuses" : [ + { + "type" : "FULL_MANA_REGENERATION", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 138, + "type" : ["HERO"], + "components": + [ + "charmOfMana", + "talismanOfMana", + "mysticOrbOfMana" + ] + }, + "ringOfTheMagi": + { + "bonuses" : [ + { + "type" : "SPELL_DURATION", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 139, + "type" : ["HERO"], + "components": + [ + "collarOfConjuring", + "ringOfConjuring", + "capeOfConjuring" + ] + }, + "cornucopia": + { + "bonuses" : [ + { + "subtype" : "resource.crystal", + "type" : "GENERATE_RESOURCE", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "resource.gems", + "type" : "GENERATE_RESOURCE", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "resource.mercury", + "type" : "GENERATE_RESOURCE", + "val" : 4, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "resource.sulfur", + "type" : "GENERATE_RESOURCE", + "val" : 4, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 140, + "type" : ["HERO"], + "components": + [ + "everflowingCrystalCloak", + "ringOfInfiniteGems", + "everpouringVialOfMercury", + "eversmokingRingOfSulfur" + ] + }, + "magicWand": + { + "bonuses" : [ + { + "type" : "CASTS", + "val" : 10, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.implosion", + "type" : "SPELLCASTER", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "spell.fireball", + "type" : "SPELLCASTER", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "RANDOM_SPELLCASTER", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "creature.vampireLord", + "type" : "DAEMON_SUMMONING", + "val" : 10, + "valueType" : "BASE_NUMBER" + }, + { + "addInfo" : 2, + "subtype" : "spell.lightningBolt", + "type" : "ENCHANTER", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : 1, + "type" : "REBIRTH", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "MANA_DRAIN", + "val" : 10, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "HEALER", + "val" : 25, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 141, + "type" : ["CREATURE"] + }, + "goldTowerArrow": + { + "bonuses" : [ + { + "type" : "NO_DISTANCE_PENALTY", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "ADDITIONAL_ATTACK", + "val" : 2, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : 22, + "type" : "SPELL_LIKE_ATTACK", + "val" : 1, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "CATAPULT", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "ACID_BREATH", + "val" : 20, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : 0, + "type" : "SHOTS", + "val" : 200, + "valueType" : "PERCENT_TO_BASE" + }, + { + "addInfo" : 1, + "subtype" : "spell.age", + "type" : "SPELL_BEFORE_ATTACK", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "addInfo" : 1, + "subtype" : "spell.berserk", + "type" : "SPELL_AFTER_ATTACK", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "addInfo" : 1, + "subtype" : "spell.poison", + "type" : "SPELL_AFTER_ATTACK", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "addInfo" : 1, + "subtype" : "spell.disruptingRay", + "type" : "SPELL_AFTER_ATTACK", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 142, + "type" : ["CREATURE"] + }, + "monstersPower": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 100, + "valueType" : "PERCENT_TO_BASE" + }, + { + "subtype" : 2, + "type" : "CREATURE_DAMAGE", + "val" : 100, + "valueType" : "PERCENT_TO_ALL" + }, + { + "type" : "HP_REGENERATION", + "val" : 50, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "NO_RETALIATION", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "RETURN_AFTER_STRIKE", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "ATTACKS_ALL_ADJACENT", + "val" : 0, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "SPELL_RESISTANCE_AURA", + "val" : 100, + "valueType" : "BASE_NUMBER" + }, + { + "type" : "DIRECT_DAMAGE_IMMUNITY", + "val" : 0, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 143, + "type" : ["CREATURE"] + }, + "art144": + { + "index" : 144, + "type" : ["HERO"] + }, + "art145": + { + "index" : 145, + "type" : ["HERO"] + }, + "axeOfSmashing": //TODO: move growing bonuses to this config, someday + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 146, + "type" : ["COMMANDER"], + "growing": { - "id" : 155, - "type" : ["COMMANDER"] - }, - "warlordsBanner": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "id" : 156, - "type" : ["CREATURE"] - }, - "crimsonShieldOfRetribution": //TODO: implement - { - "id" : 157, - "type" : ["HERO"] - }, - "barbarianLordsAxeOfFerocity": //TODO: implement - { - "id" : 158, - "type" : ["HERO"], - "components": + "bonusesPerLevel": [ - "ogresClubOfHavoc", - "targOfTheRampagingOgre", - "crownOfTheSupremeMagi", - "tunicOfTheCyclopsKing" + { + "level": 6, + "bonus": + { + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.attack", + "val" : 1 + } + } ] - }, - "dragonheart": - { - "id" : 159, - "type" : ["HERO"] - }, - "gateKey": - { - "id" : 160, - "type" : ["HERO"] - }, - "art161": - { - "id" : 161, - "type" : ["HERO"] - }, - "art162": - { - "id" : 162, - "type" : ["HERO"] - }, - "art163": - { - "id" : 163, - "type" : ["HERO"] - }, - "art164": - { - "id" : 164, - "type" : ["HERO"] - }, - "art165": - { - "id" : 165, - "type" : ["HERO"] - }, - "art166": - { - "id" : 166, - "type" : ["HERO"] - }, - "art167": - { - "id" : 167, - "type" : ["HERO"] - }, - "art168": - { - "id" : 168, - "type" : ["HERO"] - }, - "art169": - { - "id" : 169, - "type" : ["HERO"] - }, - "art170": - { - "id" : 170, - "type" : ["HERO"] } + }, + "mithrilMail": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 12, + "valueType" : "PERCENT_TO_ALL" + } + ], + "index" : 147, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 1, + "bonus": + { + "type" : "STACK_HEALTH", + "val" : 1 + } + } + ] + } + }, + "swordOfSharpness": + { + "bonuses" : [ + { + "subtype" : 0, + "type" : "CREATURE_DAMAGE", + "val" : 12, + "valueType" : "PERCENT_TO_ALL" + } + ], + "index" : 148, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 1, + "bonus": + { + "type" : "CREATURE_DAMAGE", + "val" : 1 + } + } + ] + } + }, + "helmOfImmortality": //TODO: implement + { + "index" : 149, + "type" : ["COMMANDER"] + }, + "pendantOfSorcery": + { + "bonuses" : [ + { + "type" : "CASTS", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 150, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 10, + "bonus": + { + "type" : "CREATURE_ENCHANT_POWER", + "val" : 1 + } + } + ] + } + }, + "bootsOfHaste": + { + "bonuses" : [ + { + "type" : "STACKS_SPEED", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 151, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 10, + "bonus": + { + "type" : "STACKS_SPEED", + "val" : 1 + } + } + ] + } + }, + "bowOfSeeking": + { + "index" : 152, + "type" : ["COMMANDER"], + "growing": + { + "thresholdBonuses": + [ + { + "level": 5, + "bonus": + { + "type" : "SHOOTER" + } + }, + { + "level": 25, + "bonus": + { + "type" : "NO_WALL_PENALTY" + } + }, + { + "level": 50, + "bonus": + { + "type" : "NO_DISTANCE_PENALTY" + } + } + ] + } + }, + "dragonEyeRing": //TODO: implement + { + "index" : 153, + "type" : ["COMMANDER"], + }, + "hardenedShield": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 154, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 6, + "bonus": + { + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "val" : 1 + } + } + ] + } + }, + "slavasRingOfPower": //TODO: implement if possible + { + "index" : 155, + "type" : ["COMMANDER"] + }, + "warlordsBanner": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 156, + "type" : ["CREATURE"] + }, + "crimsonShieldOfRetribution": //TODO: implement + { + "index" : 157, + "type" : ["HERO"] + }, + "barbarianLordsAxeOfFerocity": //TODO: implement + { + "index" : 158, + "type" : ["HERO"], + "components": + [ + "ogresClubOfHavoc", + "targOfTheRampagingOgre", + "crownOfTheSupremeMagi", + "tunicOfTheCyclopsKing" + ] + }, + "dragonheart": + { + "index" : 159, + "type" : ["HERO"] + }, + "gateKey": + { + "index" : 160, + "type" : ["HERO"] + }, + "art161": + { + "index" : 161, + "type" : ["HERO"] + }, + "art162": + { + "index" : 162, + "type" : ["HERO"] + }, + "art163": + { + "index" : 163, + "type" : ["HERO"] + }, + "art164": + { + "index" : 164, + "type" : ["HERO"] + }, + "art165": + { + "index" : 165, + "type" : ["HERO"] + }, + "art166": + { + "index" : 166, + "type" : ["HERO"] + }, + "art167": + { + "index" : 167, + "type" : ["HERO"] + }, + "art168": + { + "index" : 168, + "type" : ["HERO"] + }, + "art169": + { + "index" : 169, + "type" : ["HERO"] + }, + "art170": + { + "index" : 170, + "type" : ["HERO"] } } diff --git a/config/creatures/castle.json b/config/creatures/castle.json index bf7625982..595084073 100644 --- a/config/creatures/castle.json +++ b/config/creatures/castle.json @@ -1,7 +1,7 @@ { "pikeman" : { - "id": 0, + "index": 0, "level": 1, "faction": "castle", "upgrades": ["halberdier"], @@ -27,7 +27,7 @@ }, "halberdier" : { - "id": 1, + "index": 1, "level": 1, "faction": "castle", "abilities": @@ -52,7 +52,7 @@ }, "archer" : { - "id": 2, + "index": 2, "level": 2, "extraNames": [ "lightCrossbowman" ], "faction": "castle", @@ -77,7 +77,7 @@ }, "marksman" : { - "id": 3, + "index": 3, "level": 2, "faction": "castle", "abilities": { @@ -108,7 +108,7 @@ }, "griffin" : { - "id": 4, + "index": 4, "level": 3, "faction": "castle", "abilities": @@ -136,7 +136,7 @@ }, "royalGriffin" : { - "id": 5, + "index": 5, "level": 3, "faction": "castle", "abilities": @@ -161,7 +161,7 @@ }, "swordsman" : { - "id": 6, + "index": 6, "level": 4, "faction": "castle", "upgrades": ["crusader"], @@ -180,7 +180,7 @@ }, "crusader" : { - "id": 7, + "index": 7, "level": 4, "faction": "castle", "abilities": @@ -206,7 +206,7 @@ }, "monk" : { - "id": 8, + "index": 8, "level": 5, "faction": "castle", "upgrades": ["zealot"], @@ -230,7 +230,7 @@ }, "zealot" : { - "id": 9, + "index": 9, "level": 5, "faction": "castle", "graphics" : @@ -253,7 +253,7 @@ }, "cavalier" : { - "id": 10, + "index": 10, "level": 6, "faction": "castle", "upgrades": ["champion"], @@ -272,7 +272,7 @@ }, "champion" : { - "id": 11, + "index": 11, "level": 6, "faction": "castle", "graphics" : @@ -290,7 +290,7 @@ }, "angel" : { - "id": 12, + "index": 12, "level": 7, "faction": "castle", "abilities": @@ -324,7 +324,7 @@ }, "archangel" : { - "id": 13, + "index": 13, "level": 7, "faction": "castle", "abilities": diff --git a/config/creatures/conflux.json b/config/creatures/conflux.json index b88ebd118..500a8c653 100644 --- a/config/creatures/conflux.json +++ b/config/creatures/conflux.json @@ -1,7 +1,7 @@ { "airElemental" : { - "id": 112, + "index": 112, "level": 2, "extraNames": [ "airElementals" ], "faction": "conflux", @@ -49,7 +49,7 @@ }, "earthElemental" : { - "id": 113, + "index": 113, "level": 5, "faction": "conflux", "abilities": @@ -95,7 +95,7 @@ }, "fireElemental" : { - "id": 114, + "index": 114, "level": 4, "faction": "conflux", "abilities": @@ -141,7 +141,7 @@ }, "waterElemental" : { - "id": 115, + "index": 115, "level": 3, "extraNames": [ "waterElementals" ], "faction": "conflux", @@ -207,7 +207,7 @@ }, "pixie" : { - "id": 118, + "index": 118, "level": 1, "extraNames": [ "pixies" ], "faction": "conflux", @@ -227,7 +227,7 @@ }, "sprite" : { - "id": 119, + "index": 119, "level": 1, "faction": "conflux", "graphics" : @@ -245,7 +245,7 @@ }, "psychicElemental" : { - "id": 120, + "index": 120, "level": 6, "faction": "conflux", "abilities": @@ -272,7 +272,7 @@ }, "magicElemental" : { - "id": 121, + "index": 121, "level": 6, "faction": "conflux", "abilities": @@ -303,7 +303,7 @@ }, "iceElemental" : { - "id": 123, + "index": 123, "level": 3, "faction": "conflux", "abilities": @@ -350,7 +350,7 @@ }, "magmaElemental" : { - "id": 125, + "index": 125, "level": 5, "faction": "conflux", "abilities": @@ -391,7 +391,7 @@ }, "stormElemental" : { - "id": 127, + "index": 127, "level": 2, "faction": "conflux", "abilities": @@ -437,7 +437,7 @@ }, "energyElemental" : { - "id": 129, + "index": 129, "level": 4, "faction": "conflux", "abilities": @@ -478,7 +478,7 @@ }, "firebird" : { - "id": 130, + "index": 130, "level": 7, "faction": "conflux", "upgrades": ["phoenix"], @@ -504,7 +504,7 @@ }, "phoenix" : { - "id": 131, + "index": 131, "level": 7, "faction": "conflux", "abilities": diff --git a/config/creatures/dungeon.json b/config/creatures/dungeon.json index c88a4de13..34e23f545 100644 --- a/config/creatures/dungeon.json +++ b/config/creatures/dungeon.json @@ -1,7 +1,7 @@ { "troglodyte" : { - "id": 70, + "index": 70, "level": 1, "faction": "dungeon", "abilities": @@ -29,7 +29,7 @@ }, "infernalTroglodyte" : { - "id": 71, + "index": 71, "level": 1, "faction": "dungeon", "abilities": @@ -55,7 +55,7 @@ }, "harpy" : { - "id": 72, + "index": 72, "level": 2, "faction": "dungeon", "abilities": @@ -83,7 +83,7 @@ }, "harpyHag" : { - "id": 73, + "index": 73, "level": 2, "faction": "dungeon", "abilities": @@ -113,7 +113,7 @@ }, "beholder" : { - "id": 74, + "index": 74, "level": 3, "faction": "dungeon", "upgrades": ["evilEye"], @@ -137,7 +137,7 @@ }, "evilEye" : { - "id": 75, + "index": 75, "level": 3, "faction": "dungeon", "graphics" : @@ -160,7 +160,7 @@ }, "medusa" : { - "id": 76, + "index": 76, "level": 4, "faction": "dungeon", "abilities": @@ -194,7 +194,7 @@ }, "medusaQueen" : { - "id": 77, + "index": 77, "level": 4, "faction": "dungeon", "abilities": @@ -227,7 +227,7 @@ }, "minotaur" : { - "id": 78, + "index": 78, "level": 5, "faction": "dungeon", "abilities": @@ -253,7 +253,7 @@ }, "minotaurKing" : { - "id": 79, + "index": 79, "level": 5, "faction": "dungeon", "abilities": @@ -279,7 +279,7 @@ }, "manticore" : { - "id": 80, + "index": 80, "level": 6, "faction": "dungeon", "upgrades": ["scorpicore"], @@ -299,7 +299,7 @@ }, "scorpicore" : { - "id": 81, + "index": 81, "level": 6, "faction": "dungeon", "abilities": @@ -327,7 +327,7 @@ }, "redDragon" : { - "id": 82, + "index": 82, "level": 7, "faction": "dungeon", "abilities": @@ -362,7 +362,7 @@ }, "blackDragon" : { - "id": 83, + "index": 83, "level": 7, "faction": "dungeon", "abilities": diff --git a/config/creatures/fortress.json b/config/creatures/fortress.json index 1db38fcbb..cae1fe703 100644 --- a/config/creatures/fortress.json +++ b/config/creatures/fortress.json @@ -1,7 +1,7 @@ { "gnoll" : { - "id": 98, + "index": 98, "level": 1, "faction": "fortress", "upgrades": ["gnollMarauder"], @@ -20,7 +20,7 @@ }, "gnollMarauder" : { - "id": 99, + "index": 99, "level": 1, "faction": "fortress", "graphics" : @@ -38,7 +38,7 @@ }, "lizardman" : { - "id": 100, + "index": 100, "level": 2, "extraNames": [ "primitiveLizardman", ], "faction": "fortress", @@ -64,7 +64,7 @@ }, "lizardWarrior" : { - "id": 101, + "index": 101, "level": 2, "faction": "fortress", "graphics" : @@ -87,7 +87,7 @@ }, "gorgon" : { - "id": 102, + "index": 102, "level": 5, "faction": "fortress", "upgrades": ["mightyGorgon"], @@ -106,7 +106,7 @@ }, "mightyGorgon" : { - "id": 103, + "index": 103, "level": 5, "faction": "fortress", "abilities": @@ -132,7 +132,7 @@ }, "serpentFly" : { - "id": 104, + "index": 104, "level": 3, "extraNames": [ "dragonFly" ], "faction": "fortress", @@ -162,7 +162,7 @@ }, "fireDragonFly" : // dragonFly is correct in-game, incorrect in HOTRAITS { - "id": 105, + "index": 105, "level": 3, "faction": "fortress", "abilities": @@ -196,7 +196,7 @@ }, "basilisk" : { - "id": 106, + "index": 106, "level": 4, "faction": "fortress", "abilities": @@ -224,7 +224,7 @@ }, "greaterBasilisk" : { - "id": 107, + "index": 107, "level": 4, "faction": "fortress", "abilities": @@ -251,7 +251,7 @@ }, "wyvern" : { - "id": 108, + "index": 108, "level": 6, "faction": "fortress", "upgrades": ["wyvernMonarch"], @@ -270,7 +270,7 @@ }, "wyvernMonarch" : { - "id": 109, + "index": 109, "level": 6, "faction": "fortress", "abilities": @@ -297,7 +297,7 @@ }, "hydra" : { - "id": 110, + "index": 110, "level": 7, "faction": "fortress", "abilities": @@ -327,7 +327,7 @@ }, "chaosHydra" : { - "id": 111, + "index": 111, "level": 7, "faction": "fortress", "abilities": diff --git a/config/creatures/inferno.json b/config/creatures/inferno.json index 3b4ff031a..a53c7dfcc 100644 --- a/config/creatures/inferno.json +++ b/config/creatures/inferno.json @@ -1,7 +1,7 @@ { "imp" : { - "id": 42, + "index": 42, "level": 1, "faction": "inferno", "upgrades": ["familiar"], @@ -20,7 +20,7 @@ }, "familiar" : { - "id": 43, + "index": 43, "level": 1, "faction": "inferno", "abilities": @@ -46,7 +46,7 @@ }, "gog" : { - "id": 44, + "index": 44, "level": 2, "faction": "inferno", "upgrades": ["magog"], @@ -71,7 +71,7 @@ }, "magog" : { - "id": 45, + "index": 45, "level": 2, "faction": "inferno", "abilities": @@ -102,7 +102,7 @@ }, "hellHound" : { - "id": 46, + "index": 46, "level": 3, "faction": "inferno", "upgrades": ["cerberus"], @@ -125,7 +125,7 @@ }, "cerberus" : { - "id": 47, + "index": 47, "level": 3, "faction": "inferno", "abilities": @@ -155,7 +155,7 @@ }, "demon" : { - "id": 48, + "index": 48, "level": 4, "faction": "inferno", "upgrades": ["hornedDemon"], @@ -174,7 +174,7 @@ }, "hornedDemon" : { - "id": 49, + "index": 49, "level": 4, "faction": "inferno", "graphics" : @@ -192,7 +192,7 @@ }, "pitFiend" : { - "id": 50, + "index": 50, "level": 5, "faction": "inferno", "upgrades": ["pitLord"], @@ -211,7 +211,7 @@ }, "pitLord" : { - "id": 51, + "index": 51, "level": 5, "faction": "inferno", "abilities": @@ -243,7 +243,7 @@ }, "efreet" : { - "id": 52, + "index": 52, "level": 6, "faction": "inferno", "abilities": @@ -285,7 +285,7 @@ }, "efreetSultan" : { - "id": 53, + "index": 53, "level": 6, "faction": "inferno", "abilities": @@ -332,7 +332,7 @@ }, "devil" : { - "id": 54, + "index": 54, "level": 7, "faction": "inferno", "abilities": @@ -383,7 +383,7 @@ }, "archDevil" : { - "id": 55, + "index": 55, "level": 7, "faction": "inferno", "abilities" : diff --git a/config/creatures/necropolis.json b/config/creatures/necropolis.json index ca0875e95..f73084803 100644 --- a/config/creatures/necropolis.json +++ b/config/creatures/necropolis.json @@ -1,7 +1,7 @@ { "skeleton" : { - "id": 56, + "index": 56, "level": 1, "faction": "necropolis", "upgrades": ["skeletonWarrior"], @@ -20,7 +20,7 @@ }, "skeletonWarrior" : { - "id": 57, + "index": 57, "level": 1, "faction": "necropolis", "graphics" : @@ -38,7 +38,7 @@ }, "walkingDead" : { - "id": 58, + "index": 58, "level": 2, "extraNames": [ "zombie" ], //FIXME: zombie is a name of upgrade but not in HOTRAITS "faction" : "necropolis", @@ -58,7 +58,7 @@ }, "zombieLord" : //FIXME: zombie is a correct in-name but not in HOTRAITS.TXT { - "id": 59, + "index": 59, "level": 2, "faction": "necropolis", "graphics" : @@ -76,7 +76,7 @@ }, "wight" : { - "id": 60, + "index": 60, "level": 3, "faction": "necropolis", "abilities": @@ -104,7 +104,7 @@ }, "wraith" : { - "id": 61, + "index": 61, "level": 3, "faction": "necropolis", "abilities": @@ -135,7 +135,7 @@ }, "vampire" : { - "id": 62, + "index": 62, "level": 4, "faction": "necropolis", "abilities": @@ -164,7 +164,7 @@ }, "vampireLord" : { - "id": 63, + "index": 63, "level": 4, "faction": "necropolis", "abilities": @@ -198,7 +198,7 @@ }, "lich" : { - "id": 64, + "index": 64, "level": 5, "faction": "necropolis", "abilities": @@ -230,7 +230,7 @@ }, "powerLich" : { - "id": 65, + "index": 65, "level": 5, "faction": "necropolis", "abilities": @@ -261,7 +261,7 @@ }, "blackKnight" : { - "id": 66, + "index": 66, "level": 6, "faction": "necropolis", "abilities": @@ -289,7 +289,7 @@ }, "dreadKnight" : { - "id": 67, + "index": 67, "level": 6, "faction": "necropolis", "abilities": @@ -321,7 +321,7 @@ }, "boneDragon" : { - "id": 68, + "index": 68, "level": 7, "faction": "necropolis", "abilities" : @@ -347,7 +347,7 @@ }, "ghostDragon" : { - "id": 69, + "index": 69, "level": 7, "faction": "necropolis", "abilities": diff --git a/config/creatures/neutral.json b/config/creatures/neutral.json index 48e6f82f1..ee30fcb06 100644 --- a/config/creatures/neutral.json +++ b/config/creatures/neutral.json @@ -2,7 +2,7 @@ { "goldGolem" : { - "id": 116, + "index": 116, "level": 4, "faction": "neutral", "abilities": @@ -33,7 +33,7 @@ }, "diamondGolem" : { - "id": 117, + "index": 117, "level": 5, "faction": "neutral", "abilities": @@ -65,7 +65,7 @@ "azureDragon" : { "special" : true, - "id": 132, + "index": 132, "level": 10, "faction": "neutral", "abilities": @@ -108,7 +108,7 @@ "crystalDragon" : { "special" : true, - "id": 133, + "index": 133, "level": 10, "faction": "neutral", "abilities": @@ -135,7 +135,7 @@ "fairieDragon" : { "special" : true, - "id": 134, + "index": 134, "level": 8, "faction": "neutral", "abilities": @@ -233,7 +233,7 @@ "rustDragon" : { "special" : true, - "id": 135, + "index": 135, "level": 10, "faction": "neutral", "abilities": @@ -271,7 +271,7 @@ "enchanter" : { "special" : true, - "id": 136, + "index": 136, "level": 6, "extraNames": [ "enchanters" ], "faction": "neutral", @@ -351,7 +351,7 @@ "sharpshooter" : { "special" : true, - "id": 137, + "index": 137, "level": 4, "extraNames": [ "sharpshooters" ], "faction": "neutral", @@ -386,7 +386,7 @@ }, "halfling" : { - "id": 138, + "index": 138, "level": 1, "faction": "neutral", "graphics" : @@ -409,7 +409,7 @@ }, "peasant" : { - "id": 139, + "index": 139, "level": 1, "faction": "neutral", "graphics" : @@ -427,7 +427,7 @@ }, "boar" : { - "id": 140, + "index": 140, "level": 2, "faction": "neutral", "doubleWide" : true, @@ -446,7 +446,7 @@ }, "mummy" : { - "id": 141, + "index": 141, "level": 3, "faction": "neutral", "abilities": @@ -471,7 +471,7 @@ }, "nomad" : { - "id": 142, + "index": 142, "level": 3, "faction": "neutral", "doubleWide" : true, @@ -490,7 +490,7 @@ }, "rogue" : { - "id": 143, + "index": 143, "level": 2, "faction": "neutral", "graphics" : @@ -508,7 +508,7 @@ }, "troll" : { - "id": 144, + "index": 144, "level": 5, "faction": "neutral", "abilities": diff --git a/config/creatures/rampart.json b/config/creatures/rampart.json index 6563ac6a2..ea105a901 100644 --- a/config/creatures/rampart.json +++ b/config/creatures/rampart.json @@ -1,7 +1,7 @@ { "centaur" : { - "id": 14, + "index": 14, "level": 1, "faction": "rampart", "upgrades": ["centaurCaptain"], @@ -23,7 +23,7 @@ }, "centaurCaptain" : { - "id": 15, + "index": 15, "level": 1, "faction": "rampart", "graphics" : @@ -42,7 +42,7 @@ }, "dwarf" : { - "id": 16, + "index": 16, "level": 2, "faction": "rampart", "abilities": @@ -69,7 +69,7 @@ }, "battleDwarf" : { - "id": 17, + "index": 17, "level": 2, "faction": "rampart", "abilities": @@ -95,7 +95,7 @@ }, "woodElf" : { - "id": 18, + "index": 18, "level": 3, "faction": "rampart", "upgrades": ["grandElf"], @@ -119,7 +119,7 @@ }, "grandElf" : { - "id": 19, + "index": 19, "level": 3, "faction": "rampart", "abilities": @@ -151,7 +151,7 @@ }, "pegasus" : { - "id": 20, + "index": 20, "level": 4, "faction": "rampart", "abilities": @@ -179,7 +179,7 @@ }, "silverPegasus" : { - "id": 21, + "index": 21, "level": 4, "faction": "rampart", "abilities": @@ -205,7 +205,7 @@ }, "dendroidGuard" : { - "id": 22, + "index": 22, "level": 5, "faction": "rampart", "abilities": @@ -233,7 +233,7 @@ }, "dendroidSoldier" : { - "id": 23, + "index": 23, "level": 5, "faction": "rampart", "abilities": @@ -260,7 +260,7 @@ }, "unicorn" : { - "id": 24, + "index": 24, "level": 6, "faction": "rampart", "abilities": @@ -293,7 +293,7 @@ }, "warUnicorn" : { - "id": 25, + "index": 25, "level": 6, "faction": "rampart", "abilities": @@ -326,7 +326,7 @@ }, "greenDragon" : { - "id": 26, + "index": 26, "level": 7, "faction": "rampart", "abilities": @@ -361,7 +361,7 @@ }, "goldDragon" : { - "id": 27, + "index": 27, "level": 7, "faction": "rampart", "abilities": diff --git a/config/creatures/special.json b/config/creatures/special.json index 9c6b3ae7f..452aa9bff 100644 --- a/config/creatures/special.json +++ b/config/creatures/special.json @@ -6,34 +6,34 @@ "faction": "neutral", "disabled" : true, "graphics" : null, - "id" : 122 + "index" : 122 }, "unused124" : { "faction": "neutral", "disabled" : true, "graphics" : null, - "id" : 124 + "index" : 124 }, "unused126" : { "faction": "neutral", "disabled" : true, "graphics" : null, - "id" : 126 + "index" : 126 }, "unused128" : { "faction": "neutral", "disabled" : true, "graphics" : null, - "id" : 128 + "index" : 128 }, "catapult" : { "special" : true, - "id": 145, + "index": 145, "level": 0, "faction": "neutral", "graphics" : @@ -54,7 +54,7 @@ "ballista" : { "special" : true, - "id": 146, + "index": 146, "level": 0, "faction": "neutral", "graphics" : @@ -75,7 +75,7 @@ "firstAidTent" : { "special" : true, - "id": 147, + "index": 147, "level": 0, "faction": "neutral", "abilities": { "heals" : { "type" : "HEALER" } }, @@ -92,7 +92,7 @@ "ammoCart" : { "special" : true, - "id": 148, + "index": 148, "level": 0, "faction": "neutral", "abilities": { "inactive" : { "type" : "NOT_ACTIVE" } }, @@ -109,7 +109,7 @@ "arrowTower" : { "special" : true, - "id": 149, + "index": 149, "level": 0, "faction": "neutral", "abilities": { "shooter" : { "type" : "SHOOTER" } }, diff --git a/config/creatures/stronghold.json b/config/creatures/stronghold.json index 736c7509c..95ab5a7a3 100644 --- a/config/creatures/stronghold.json +++ b/config/creatures/stronghold.json @@ -1,7 +1,7 @@ { "goblin" : { - "id": 84, + "index": 84, "level": 1, "extraNames": [ "goblins" ], "faction": "stronghold", @@ -21,7 +21,7 @@ }, "hobgoblin" : { - "id": 85, + "index": 85, "level": 1, "faction": "stronghold", "hasDoubleWeek": true, @@ -40,7 +40,7 @@ }, "goblinWolfRider" : { - "id": 86, + "index": 86, "level": 2, "faction": "stronghold", "upgrades": ["hobgoblinWolfRider"], @@ -60,7 +60,7 @@ }, "hobgoblinWolfRider" : { - "id": 87, + "index": 87, "level": 2, "faction": "stronghold", "abilities": @@ -86,7 +86,7 @@ }, "orc" : { - "id": 88, + "index": 88, "level": 3, "faction": "stronghold", "upgrades": ["orcChieftain"], @@ -110,7 +110,7 @@ }, "orcChieftain" : { - "id": 89, + "index": 89, "level": 3, "faction": "stronghold", "graphics" : @@ -133,7 +133,7 @@ }, "ogre" : { - "id": 90, + "index": 90, "level": 4, "faction": "stronghold", "upgrades": ["ogreMage"], @@ -152,7 +152,7 @@ }, "ogreMage" : { - "id": 91, + "index": 91, "level": 4, "faction": "stronghold", "abilities": @@ -190,7 +190,7 @@ }, "roc" : { - "id": 92, + "index": 92, "level": 5, "faction": "stronghold", "upgrades": ["thunderbird"], @@ -209,7 +209,7 @@ }, "thunderbird" : { - "id": 93, + "index": 93, "level": 5, "faction": "stronghold", "abilities": @@ -242,7 +242,7 @@ }, "cyclop" : { - "id": 94, + "index": 94, "level": 6, "faction": "stronghold", "upgrades": ["cyclopKing"], @@ -266,7 +266,7 @@ }, "cyclopKing" : { - "id": 95, + "index": 95, "level": 6, "faction": "stronghold", "graphics" : @@ -289,7 +289,7 @@ }, "behemoth" : { - "id": 96, + "index": 96, "level": 7, "faction": "stronghold", "abilities": @@ -316,7 +316,7 @@ }, "ancientBehemoth" : { - "id": 97, + "index": 97, "level": 7, "faction": "stronghold", "abilities": diff --git a/config/creatures/tower.json b/config/creatures/tower.json index 69d241669..009b63998 100644 --- a/config/creatures/tower.json +++ b/config/creatures/tower.json @@ -1,7 +1,7 @@ { "gremlin" : { - "id": 28, + "index": 28, "level": 1, "extraNames": [ "apprenticeGremlin" ], "faction": "tower", @@ -23,7 +23,7 @@ }, "masterGremlin" : { - "id": 29, + "index": 29, "level": 1, "faction": "tower", "graphics" : @@ -46,7 +46,7 @@ }, "stoneGargoyle" : { - "id": 30, + "index": 30, "level": 2, "faction": "tower", "abilities": @@ -72,7 +72,7 @@ }, "obsidianGargoyle" : { - "id": 31, + "index": 31, "level": 2, "faction": "tower", "abilities": @@ -97,7 +97,7 @@ }, "ironGolem" : //FIXME correct ID is stoneGolem, unchangeable due to HOTRAITS.TXT { - "id": 32, + "index": 32, "level": 3, "faction": "tower", "abilities": @@ -129,7 +129,7 @@ }, "stoneGolem" : //FIXME correct ID is ironGolem, unchangeable due to HOTRAITS.TXT { - "id": 33, + "index": 33, "level": 3, "faction": "tower", "abilities" : @@ -160,7 +160,7 @@ }, "mage" : { - "id": 34, + "index": 34, "level": 4, "faction": "tower", "abilities": @@ -192,7 +192,7 @@ }, "archMage" : { - "id": 35, + "index": 35, "level": 4, "faction": "tower", "abilities": @@ -223,7 +223,7 @@ }, "genie" : { - "id": 36, + "index": 36, "level": 5, "faction": "tower", "abilities": @@ -257,7 +257,7 @@ }, "masterGenie" : { - "id": 37, + "index": 37, "level": 5, "faction": "tower", "abilities": @@ -306,7 +306,7 @@ }, "naga" : { - "id": 38, + "index": 38, "level": 6, "faction": "tower", "abilities" : @@ -332,7 +332,7 @@ }, "nagaQueen" : { - "id": 39, + "index": 39, "level": 6, "faction": "tower", "abilities" : @@ -357,7 +357,7 @@ }, "giant" : { - "id": 40, + "index": 40, "level": 7, "faction": "tower", "abilities" : @@ -383,7 +383,7 @@ }, "titan" : { - "id": 41, + "index": 41, "level": 7, "faction": "tower", "abilities" : diff --git a/config/creatures/wog.json b/config/creatures/wog.json index a65ba9fcc..59fd1b131 100644 --- a/config/creatures/wog.json +++ b/config/creatures/wog.json @@ -1,7 +1,7 @@ { "supremeArchangel" : { - "id": 150, + "index": 150, "level": 8, "faction": "castle", "graphics" : @@ -19,7 +19,7 @@ }, "diamondDragon" : { - "id": 151, + "index": 151, "level": 8, "faction": "rampart", "abilities": @@ -44,7 +44,7 @@ }, "lordofThunder" : { - "id": 152, + "index": 152, "level": 8, "faction": "tower", "graphics" : @@ -67,7 +67,7 @@ }, "hellBaron" : { - "id": 153, + "index": 153, "level": 8, "faction": "inferno", "abilities": @@ -96,7 +96,7 @@ }, "bloodDragon" : { - "id": 154, + "index": 154, "level": 8, "faction": "necropolis", "abilities": @@ -126,7 +126,7 @@ }, "darknessDragon" : { - "id": 155, + "index": 155, "level": 8, "faction": "dungeon", "abilities": @@ -151,7 +151,7 @@ }, "ghostBehemoth" : { - "id": 156, + "index": 156, "level": 8, "faction": "stronghold", "graphics" : @@ -169,7 +169,7 @@ }, "hellHydra" : { - "id": 157, + "index": 157, "level": 8, "faction": "fortress", "abilities" : @@ -191,7 +191,7 @@ }, "sacredPhoenix" : { - "id": 158, + "index": 158, "level": 8, "faction": "conflux", "graphics" : @@ -209,7 +209,7 @@ }, "ghost" : { - "id": 159, + "index": 159, "level": 0, "faction": "neutral", "graphics" : @@ -228,7 +228,7 @@ "godWar" : { "disabled" : true, - "id": 160, + "index": 160, "level": 0, "faction": "neutral", "graphics" : @@ -239,7 +239,7 @@ "godPeace" : { "disabled" : true, - "id": 161, + "index": 161, "level": 0, "faction": "neutral", "graphics" : @@ -250,7 +250,7 @@ "godMana" : { "disabled" : true, - "id": 162, + "index": 162, "level": 0, "faction": "neutral", "graphics" : @@ -261,7 +261,7 @@ "godLore" : { "disabled" : true, - "id": 163, + "index": 163, "level": 0, "faction": "neutral", "graphics" : @@ -271,7 +271,7 @@ }, "minotaurKing2" :// WTF is this? Same ID as Minotaur King from Dungeon { - "id": 164, + "index": 164, "level": 0, "faction": "neutral", "graphics" : @@ -289,7 +289,7 @@ }, "mineralElemental" : { - "id": 165, + "index": 165, "level": 0, "faction": "neutral", "graphics" : @@ -307,7 +307,7 @@ }, "electricityElemental" : { - "id": 166, + "index": 166, "level": 0, "faction": "neutral", "graphics" : @@ -325,7 +325,7 @@ }, "ancientBasilisk" : { - "id": 167, + "index": 167, "level": 0, "faction": "neutral", "graphics" : @@ -343,7 +343,7 @@ }, "gorynych" : { - "id": 168, + "index": 168, "level": 0, "faction": "neutral", "abilities": @@ -368,7 +368,7 @@ }, "warZealot" : { - "id": 169, + "index": 169, "level": 0, "faction": "neutral", "graphics" : @@ -391,7 +391,7 @@ }, "myriad" : { - "id": 170, + "index": 170, "level": 0, "faction": "neutral", "graphics" : @@ -414,7 +414,7 @@ }, "medusaMatriarch" : { - "id": 171, + "index": 171, "level": 0, "faction": "neutral", "graphics" : @@ -437,7 +437,7 @@ }, "nightmare" : { - "id": 172, + "index": 172, "level": 0, "faction": "neutral", "graphics" : @@ -455,7 +455,7 @@ }, "santaGremlin" : { - "id": 173, + "index": 173, "level": 0, "faction": "neutral", "graphics" : @@ -478,14 +478,38 @@ "paladin1" : { "special" : true, - "id": 174, + "index": 174, "level": 0, "faction": "neutral", - "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], - [ "CASTS", 1, 0, 0 ] , - [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , - [ "CREATURE_SPELL_POWER", 100, 0, 0 ] , - [ "SPELLCASTER", 3, "spell.cure", 0 ] ], //expert cure + "abilities": + { + "magicResistance" : + { + "type" : "MAGIC_RESISTANCE", + "val" : 5 + }, + "castsAmount" : + { + "type" : "CASTS", + "val" : 1 + }, + "enchant" : + { + "type" : "CREATURE_ENCHANT_POWER", + "val" : 1 + }, + "spellpower" : + { + "type" : "CREATURE_SPELL_POWER", + "val" : 100 + }, + "canCast" : + { + "type" : "SPELLCASTER", + "subtype" : "spell.cure", + "val" : 3 + } + }, "graphics" : { "animation": "ZM174NPC.DEF", @@ -506,7 +530,7 @@ "hierophant1" : { "special" : true, - "id": 175, + "index": 175, "level": 0, "faction": "neutral", "abilities": @@ -559,7 +583,7 @@ "templeGuardian1" : { "special" : true, - "id": 176, + "index": 176, "level": 0, "faction": "neutral", "abilities": @@ -612,7 +636,7 @@ "succubus1" : { "special" : true, - "id": 177, + "index": 177, "level": 0, "faction": "neutral", "abilities": @@ -664,7 +688,7 @@ "soulEater1" : { "special" : true, - "id": 178, + "index": 178, "level": 0, "faction": "neutral", "abilities": @@ -716,7 +740,7 @@ "brute1" : { "special" : true, - "id": 179, + "index": 179, "level": 0, "faction": "neutral", "abilities": @@ -768,7 +792,7 @@ "ogreLeader1" : { "special" : true, - "id": 180, + "index": 180, "level": 0, "faction": "neutral", "abilities": @@ -820,7 +844,7 @@ "shaman1" : { "special" : true, - "id": 181, + "index": 181, "level": 0, "faction": "neutral", "abilities": @@ -873,7 +897,7 @@ "astralSpirit1" : { "special" : true, - "id": 182, + "index": 182, "level": 0, "faction": "neutral", "abilities": @@ -925,7 +949,7 @@ "paladin2" : { "special" : true, - "id": 183, + "index": 183, "level": 0, "faction": "neutral", "graphics" : @@ -941,7 +965,7 @@ { "special" : true, "disabled" : true, - "id": 184, + "index": 184, "level": 0, "faction": "neutral", "graphics" : @@ -957,7 +981,7 @@ { "special" : true, "disabled" : true, - "id": 185, + "index": 185, "level": 0, "faction": "neutral", "graphics" : @@ -973,7 +997,7 @@ { "special" : true, "disabled" : true, - "id": 186, + "index": 186, "level": 0, "faction": "neutral", "graphics" : @@ -989,7 +1013,7 @@ { "special" : true, "disabled" : true, - "id": 187, + "index": 187, "level": 0, "faction": "neutral", "graphics" : @@ -1005,7 +1029,7 @@ { "special" : true, "disabled" : true, - "id": 188, + "index": 188, "level": 0, "faction": "neutral", "graphics" : @@ -1021,7 +1045,7 @@ { "special" : true, "disabled" : true, - "id": 189, + "index": 189, "level": 0, "faction": "neutral", "graphics" : @@ -1037,7 +1061,7 @@ { "special" : true, "disabled" : true, - "id": 190, + "index": 190, "level": 0, "faction": "neutral", "graphics" : @@ -1053,7 +1077,7 @@ { "special" : true, "disabled" : true, - "id": 191, + "index": 191, "level": 0, "faction": "neutral", "graphics" : @@ -1067,7 +1091,7 @@ }, "sylvanCentaur" : { - "id": 192, + "index": 192, "level": 0, "faction": "neutral", "graphics" : @@ -1090,7 +1114,7 @@ }, "sorceresses" : { - "id": 193, + "index": 193, "level": 0, "faction": "neutral", "graphics" : @@ -1113,7 +1137,7 @@ }, "werewolf" : { - "id": 194, + "index": 194, "level": 0, "faction": "neutral", "graphics" : @@ -1123,7 +1147,7 @@ }, "hellSteed" : { - "id": 195, + "index": 195, "level": 0, "faction": "neutral", "graphics" : @@ -1142,7 +1166,7 @@ }, "dracolich" : { - "id": 196, + "index": 196, "level": 10, "faction": "neutral", "abilities": diff --git a/config/factions/castle.json b/config/factions/castle.json index 2df9ee187..8803bf338 100644 --- a/config/factions/castle.json +++ b/config/factions/castle.json @@ -74,46 +74,46 @@ "capitol" : "AVCCASZ0.DEF" }, "structures" : - [ - { "animation" : "TBCSEXT2.def", "x" : 46, "y" : 119 }, - { "id" : 0, "animation" : "TBCSMAGE.def", "x" : 707, "y" : 166, "z" : 1, "border" : "TOCSMAG1.bmp", "area" : "TZCSMAG1.bmp" }, - { "id" : 1, "animation" : "TBCSMAG2.def", "x" : 706, "y" : 135, "z" : 1, "border" : "TOCSMAG2.bmp", "area" : "TZCSMAG2.bmp" }, - { "id" : 2, "animation" : "TBCSMAG3.def", "x" : 704, "y" : 107, "z" : 1, "border" : "TOCSM301.bmp", "area" : "TZCSM301.bmp" }, - { "id" : 3, "animation" : "TBCSMAG4.def", "x" : 704, "y" : 76, "z" : 1, "border" : "TOCSM401.bmp", "area" : "TZCSM401.bmp" }, - { "id" : 5, "animation" : "TBCSTVRN.def", "x" : 0, "y" : 230, "z" : 1, "border" : "TOCSTAV1.bmp", "area" : "TZCSTAV1.bmp" }, - { "id" : 6, "animation" : "TBCSDOCK.def", "x" : 478, "y" : 134, "border" : "TOCSDKMS.bmp", "area" : "TZCSDKMS.bmp" }, - { "id" : 7, "animation" : "TBCSCSTL.def", "x" : 595, "y" : 66, "border" : "TOCSCAS1.bmp", "area" : "TZCSCAS1.bmp" }, - { "id" : 8, "animation" : "TBCSCAS2.def", "x" : 478, "y" : 66, "border" : "TOCSCAS2.bmp", "area" : "TZCSCAS2.bmp" }, - { "id" : 9, "animation" : "TBCSCAS3.def", "x" : 478, "y" : 37, "border" : "TOCSCAS3.bmp", "area" : "TZCSCAS3.bmp" }, - { "id" : 10, "animation" : "TBCSHALL.def", "x" : 0, "y" : 209, "border" : "TOCSH101.bmp", "area" : "TZCSH101.bmp" }, - { "id" : 11, "animation" : "TBCSHAL2.def", "x" : 0, "y" : 176, "border" : "TOCSH201.bmp", "area" : "TZCSH201.bmp" }, - { "id" : 12, "animation" : "TBCSHAL3.def", "x" : 0, "y" : 164, "border" : "TOCSH301.bmp", "area" : "TZCSH301.bmp" }, - { "id" : 13, "animation" : "TBCSHAL4.def", "x" : 0, "y" : 154, "border" : "TOCSH401.bmp", "area" : "TZCSH401.bmp" }, - { "id" : 14, "animation" : "TBCSMARK.def", "x" : 413, "y" : 264, "border" : "TOCSMRK1.bmp", "area" : "TZCSMRK1.bmp" }, - { "id" : 15, "animation" : "TBCSSILO.def", "x" : 488, "y" : 228, "border" : "TOCSMRK2.bmp", "area" : "TZCSMRK2.bmp" }, - { "id" : 16, "animation" : "TBCSBLAK.def", "x" : 213, "y" : 251, "border" : "TOCSBLAK.bmp", "area" : "TZCSBLAK.bmp" }, - { "id" : 17, "animation" : "TBCSSPEC.def", "x" : 533, "y" : 71, "border" : "TOCSLT01.bmp", "area" : "TZCSLT01.bmp" }, - { "id" : 18, "animation" : "TBCSHRD1.def", "x" : 76, "y" : 53, "border" : "TOCSGR1H.bmp", "area" : "TZCSGR1H.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBCSHRD2.def", "x" : 76, "y" : 35, "border" : "TOCSGR2H.bmp", "area" : "TZCSGR2H.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 20, "animation" : "TBCSBOAT.def", "x" : 478, "y" : 134, "border" : "TOCSDKMN.bmp", "area" : "TZCSDKMN.bmp", "hidden" : true }, - { "id" : 21, "animation" : "TBCSEXT0.def", "x" : 384, "y" : 193, "z" : -2, "border" : "TOCSCAVM.bmp", "area" : "TZCSCAVM.bmp" }, - { "id" : 22, "animation" : "TBCSEXT1.def", "x" : 0, "y" : 198, "z" : 1, "border" : "TOCSTAV2.bmp", "area" : "TZCSTAV2.bmp" }, - { "id" : 26, "animation" : "TBCSHOLY.def", "x" : 456, "y" : 109, "z" : -1, "border" : "TOCSHOLY.bmp", "area" : "TZCSHOLY.bmp" }, - { "id" : 30, "animation" : "TBCSDW_0.def", "x" : 304, "y" : 92, "border" : "TOCSPIK1.bmp", "area" : "TZCSPIK1.bmp" }, - { "id" : 31, "animation" : "TBCSDW_1.def", "x" : 360, "y" : 130, "border" : "TOCSCRS1.bmp", "area" : "TZCSCRS1.bmp" }, - { "id" : 32, "animation" : "TBCSDW_2.def", "x" : 76, "y" : 57, "border" : "TOCSGR1N.bmp", "area" : "TZCSGR1N.bmp" }, - { "id" : 33, "animation" : "TBCSDW_3.def", "x" : 176, "y" : 101, "border" : "TOCSSWD1.bmp", "area" : "TZCSSWD1.bmp" }, - { "id" : 34, "animation" : "TBCSDW_4.def", "x" : 563, "y" : 211, "z" : 1, "border" : "TOCSMON1.bmp", "area" : "TZCSMON1.bmp" }, - { "id" : 35, "animation" : "TBCSDW_5.def", "x" : 174, "y" : 190, "z" : -1, "border" : "TOCSC101.bmp", "area" : "TZCSCAV1.bmp" }, - { "id" : 36, "animation" : "TBCSDW_6.def", "x" : 303, "y" : 0, "z" : -1, "border" : "TOCSANG1.bmp", "area" : "TZCSANG1.bmp" }, - { "id" : 37, "animation" : "TBCSUP_0.def", "x" : 304, "y" : 65, "border" : "TOCSPIK2.bmp", "area" : "TZCSPIK2.bmp" }, - { "id" : 38, "animation" : "TBCSUP_1.def", "x" : 360, "y" : 115, "border" : "TOCSCRS2.bmp", "area" : "TZCSCRS2.bmp" }, - { "id" : 39, "animation" : "TBCSUP_2.def", "x" : 76, "y" : 35, "border" : "TOCSGR2N.bmp", "area" : "TZCSGR2N.bmp" }, - { "id" : 40, "animation" : "TBCSUP_3.def", "x" : 176, "y" : 85, "border" : "TOCSSWD2.bmp", "area" : "TZCSSWD2.bmp" }, - { "id" : 41, "animation" : "TBCSUP_4.def", "x" : 563, "y" : 173, "z" : 1, "border" : "TOCSMON2.bmp", "area" : "TZCSMON2.bmp" }, - { "id" : 42, "animation" : "TBCSUP_5.def", "x" : 160, "y" : 190, "z" : -1, "border" : "TOCSCAV2.bmp", "area" : "TZCSCAV2.bmp" }, - { "id" : 43, "animation" : "TBCSUP_6.def", "x" : 303, "y" : 0, "z" : -1, "border" : "TOCSANG2.bmp", "area" : "TZCSANG2.bmp" } - ], + { + "extraAnimation": { "animation" : "TBCSEXT2.def", "x" : 46, "y" : 119 }, + "mageGuild1": { "id" : 0, "animation" : "TBCSMAGE.def", "x" : 707, "y" : 166, "z" : 1, "border" : "TOCSMAG1.bmp", "area" : "TZCSMAG1.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBCSMAG2.def", "x" : 706, "y" : 135, "z" : 1, "border" : "TOCSMAG2.bmp", "area" : "TZCSMAG2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBCSMAG3.def", "x" : 704, "y" : 107, "z" : 1, "border" : "TOCSM301.bmp", "area" : "TZCSM301.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBCSMAG4.def", "x" : 704, "y" : 76, "z" : 1, "border" : "TOCSM401.bmp", "area" : "TZCSM401.bmp" }, + "tavern": { "id" : 5, "animation" : "TBCSTVRN.def", "x" : 0, "y" : 230, "z" : 1, "border" : "TOCSTAV1.bmp", "area" : "TZCSTAV1.bmp" }, + "shipyard": { "id" : 6, "animation" : "TBCSDOCK.def", "x" : 478, "y" : 134, "border" : "TOCSDKMS.bmp", "area" : "TZCSDKMS.bmp" }, + "fort": { "id" : 7, "animation" : "TBCSCSTL.def", "x" : 595, "y" : 66, "border" : "TOCSCAS1.bmp", "area" : "TZCSCAS1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBCSCAS2.def", "x" : 478, "y" : 66, "border" : "TOCSCAS2.bmp", "area" : "TZCSCAS2.bmp" }, + "castle": { "id" : 9, "animation" : "TBCSCAS3.def", "x" : 478, "y" : 37, "border" : "TOCSCAS3.bmp", "area" : "TZCSCAS3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBCSHALL.def", "x" : 0, "y" : 209, "border" : "TOCSH101.bmp", "area" : "TZCSH101.bmp" }, + "townHall": { "id" : 11, "animation" : "TBCSHAL2.def", "x" : 0, "y" : 176, "border" : "TOCSH201.bmp", "area" : "TZCSH201.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBCSHAL3.def", "x" : 0, "y" : 164, "border" : "TOCSH301.bmp", "area" : "TZCSH301.bmp" }, + "capitol": { "id" : 13, "animation" : "TBCSHAL4.def", "x" : 0, "y" : 154, "border" : "TOCSH401.bmp", "area" : "TZCSH401.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBCSMARK.def", "x" : 413, "y" : 264, "border" : "TOCSMRK1.bmp", "area" : "TZCSMRK1.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBCSSILO.def", "x" : 488, "y" : 228, "border" : "TOCSMRK2.bmp", "area" : "TZCSMRK2.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBCSBLAK.def", "x" : 213, "y" : 251, "border" : "TOCSBLAK.bmp", "area" : "TZCSBLAK.bmp" }, + "special1": { "id" : 17, "animation" : "TBCSSPEC.def", "x" : 533, "y" : 71, "border" : "TOCSLT01.bmp", "area" : "TZCSLT01.bmp" }, + "horde1": { "id" : 18, "animation" : "TBCSHRD1.def", "x" : 76, "y" : 53, "border" : "TOCSGR1H.bmp", "area" : "TZCSGR1H.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBCSHRD2.def", "x" : 76, "y" : 35, "border" : "TOCSGR2H.bmp", "area" : "TZCSGR2H.bmp", "hidden" : true, "builds" : 18 }, + "ship": { "id" : 20, "animation" : "TBCSBOAT.def", "x" : 478, "y" : 134, "border" : "TOCSDKMN.bmp", "area" : "TZCSDKMN.bmp", "hidden" : true }, + "special2": { "id" : 21, "animation" : "TBCSEXT0.def", "x" : 384, "y" : 193, "z" : -2, "border" : "TOCSCAVM.bmp", "area" : "TZCSCAVM.bmp" }, + "special3": { "id" : 22, "animation" : "TBCSEXT1.def", "x" : 0, "y" : 198, "z" : 1, "border" : "TOCSTAV2.bmp", "area" : "TZCSTAV2.bmp" }, + "grail": { "id" : 26, "animation" : "TBCSHOLY.def", "x" : 456, "y" : 109, "z" : -1, "border" : "TOCSHOLY.bmp", "area" : "TZCSHOLY.bmp" }, + "dwellingLvl1": { "id" : 30, "animation" : "TBCSDW_0.def", "x" : 304, "y" : 92, "border" : "TOCSPIK1.bmp", "area" : "TZCSPIK1.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBCSDW_1.def", "x" : 360, "y" : 130, "border" : "TOCSCRS1.bmp", "area" : "TZCSCRS1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBCSDW_2.def", "x" : 76, "y" : 57, "border" : "TOCSGR1N.bmp", "area" : "TZCSGR1N.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBCSDW_3.def", "x" : 176, "y" : 101, "border" : "TOCSSWD1.bmp", "area" : "TZCSSWD1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBCSDW_4.def", "x" : 563, "y" : 211, "z" : 1, "border" : "TOCSMON1.bmp", "area" : "TZCSMON1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBCSDW_5.def", "x" : 174, "y" : 190, "z" : -1, "border" : "TOCSC101.bmp", "area" : "TZCSCAV1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBCSDW_6.def", "x" : 303, "y" : 0, "z" : -1, "border" : "TOCSANG1.bmp", "area" : "TZCSANG1.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBCSUP_0.def", "x" : 304, "y" : 65, "border" : "TOCSPIK2.bmp", "area" : "TZCSPIK2.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBCSUP_1.def", "x" : 360, "y" : 115, "border" : "TOCSCRS2.bmp", "area" : "TZCSCRS2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBCSUP_2.def", "x" : 76, "y" : 35, "border" : "TOCSGR2N.bmp", "area" : "TZCSGR2N.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBCSUP_3.def", "x" : 176, "y" : 85, "border" : "TOCSSWD2.bmp", "area" : "TZCSSWD2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBCSUP_4.def", "x" : 563, "y" : 173, "z" : 1, "border" : "TOCSMON2.bmp", "area" : "TZCSMON2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBCSUP_5.def", "x" : 160, "y" : 190, "z" : -1, "border" : "TOCSCAV2.bmp", "area" : "TZCSCAV2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBCSUP_6.def", "x" : 303, "y" : 0, "z" : -1, "border" : "TOCSANG2.bmp", "area" : "TZCSANG2.bmp" } + }, "icons" : { "village" : {"normal" : 18, "built" : 19 }, @@ -150,49 +150,50 @@ "moatDamage" : 70, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 6 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 6 ] }, - { "id" : 18, "upgrades" : 32 }, - { "id" : 19, "upgrades" : 39, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 20, "upgrades" : 6 }, - { "id" : 21, "requires" : [ 33 ] }, - { "id" : 22, "upgrades" : 5 }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 33 ] }, - { "id" : 33, "requires" : [ 16, 30 ] }, - { "id" : 34, "requires" : [ 0, 33 ] }, - { "id" : 35, "requires" : [ 21 ] }, - { "id" : 36, "requires" : [ 34 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33 }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "tavern": { "id" : 5 }, + "shipyard": { "id" : 6 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 6 ] }, + "horde1": { "id" : 18, "upgrades" : 32 }, + "horde1Upgr": { "id" : 19, "upgrades" : 39, "requires" : [ 18 ], "mode" : "auto" }, + "ship": { "id" : 20, "upgrades" : 6 }, + "special2": { "id" : 21, "requires" : [ 33 ] }, + "special3": { "id" : 22, "upgrades" : 5 }, + "grail": { "id" : 26, "mode" : "grail"}, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 33 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 16, 30 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 0, 33 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 21 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 34 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33 }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "horde2" : null, + "horde2Upgr" : null, + "mageGuild5" : null, + "special4" : null + }, "siege" : { diff --git a/config/factions/conflux.json b/config/factions/conflux.json index a2ec80e37..41d673029 100644 --- a/config/factions/conflux.json +++ b/config/factions/conflux.json @@ -74,50 +74,50 @@ "capitol" : "AVCHFORZ.DEF" }, "structures" : - [ - { "animation" : "TBELEXT5.def", "x" : 682, "y" : 183, "z" : -1, }, - { "animation" : "TBELEXT1.def", "x" : 23, "y" : 218 }, - { "id" : 0, "animation" : "TBELMAGE.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAGE.bmp", "area" : "TZELMAGE.bmp" }, - { "id" : 1, "animation" : "TBELMAG2.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG2.bmp", "area" : "TZELMAG2.bmp" }, - { "id" : 2, "animation" : "TBELMAG3.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG3.bmp", "area" : "TZELMAG3.bmp" }, - { "id" : 3, "animation" : "TBELMAG4.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG4.bmp", "area" : "TZELMAG4.bmp" }, - { "id" : 4, "animation" : "TBELMAG5.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG5.bmp", "area" : "TZELMAG5.bmp" }, - { "id" : 5, "animation" : "TBELTVRN.def", "x" : 553, "y" : 203, "z" : 1, "border" : "TOELTVRN.bmp", "area" : "TZELTVRN.bmp" }, - { "id" : 6, "animation" : "TBELDOCK.def", "x" : 239, "y" : 215, "z" : 2, "border" : "TOELDOCK.bmp", "area" : "TZELDOCK.bmp" }, - { "id" : 7, "animation" : "TBELCSTL.def", "x" : 349, "y" : 101, "z" : -1, "border" : "TOELCSTL.bmp", "area" : "TZELCSTL.bmp" }, - { "id" : 8, "animation" : "TBELCAS2.def", "x" : 349, "y" : 101, "z" : -1, "border" : "TOELCAS2.bmp", "area" : "TZELCAS2.bmp" }, - { "id" : 9, "animation" : "TBELCAS3.def", "x" : 349, "y" : 101, "z" : -1, "border" : "TOELCAS3.bmp", "area" : "TZELCAS3.bmp" }, - { "id" : 10, "animation" : "TBELHALL.def", "x" : -1, "y" : 164, "z" : 5, "border" : "TOELHALL.bmp", "area" : "TZELHALL.bmp" }, - { "id" : 11, "animation" : "TBELHAL2.def", "x" : 0, "y" : 165, "z" : 5, "border" : "TOELHAL2.bmp", "area" : "TZELHAL2.bmp" }, - { "id" : 12, "animation" : "TBELHAL3.def", "x" : 0, "y" : 165, "z" : 5, "border" : "TOELHAL3.bmp", "area" : "TZELHAL3.bmp" }, - { "id" : 13, "animation" : "TBELHAL4.def", "x" : 0, "y" : 164, "z" : 5, "border" : "TOELHAL4.bmp", "area" : "TZELHAL4.bmp" }, - { "id" : 14, "animation" : "TBELMARK.def", "x" : 347, "y" : 216, "z" : 4, "border" : "TOELMARK.bmp", "area" : "TZELMARK.bmp" }, - { "id" : 15, "animation" : "TBELSILO.def", "x" : 372, "y" : 171, "z" : 2, "border" : "TOELSILO.bmp", "area" : "TZELSILO.bmp" }, - { "id" : 16, "animation" : "TBELBLAK.def", "x" : 449, "y" : 151, "z" : 1, "border" : "TOELBLAK.bmp", "area" : "TZELBLAK.bmp" }, - { "id" : 17, "animation" : "TBELSPEC.def", "x" : 284, "y" : 246, "z" : 4, "border" : "TOELSPEC.bmp", "area" : "TZELSPEC.bmp" }, - { "id" : 18, "animation" : "TBELHRD1.def", "x" : 689, "y" : 250, "border" : "TOELHRD1.bmp", "area" : "TZELHRD1.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBELHRD2.def", "x" : 689, "y" : 250, "border" : "TOELHRD2.bmp", "area" : "TZELHRD2.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 20, "animation" : "TBELBOAT.def", "x" : 239, "y" : 215, "z" : 2, "border" : "TOELBOAT.bmp", "area" : "TZELBOAT.bmp", "hidden" : true }, - { "id" : 21, "animation" : "TBELEXT6.def", "x" : 104, "y" : 170, "z" : 3, "border" : "TOELEXT6.bmp", "area" : "TZELEXT6.bmp" }, - { "id" : 26, "animation" : "TBELHOLY.def", "x" : 307, "y" : 2, "border" : "TOELHOLY.bmp", "area" : "TZELHOLY.bmp" }, - { "id" : 27, "animation" : "TBELEXT2.def", "x" : 232, "y" : 205 }, - { "id" : 28, "animation" : "TBELEXT3.def", "x" : 516, "y" : 223, "z" : 1 }, - { "id" : 29, "animation" : "TBELEXT4.def", "x" : 0, "y" : 252, "z" : 6 }, - { "id" : 30, "animation" : "TBELDW_0.def", "x" : 689, "y" : 250, "border" : "TOELDW_0.bmp", "area" : "TZELDW_0.bmp" }, - { "id" : 31, "animation" : "TBELDW_1.def", "x" : 630, "y" : 50, "border" : "TOELDW_1.bmp", "area" : "TZELDW_1.bmp" }, - { "id" : 32, "animation" : "TBELDW_2.def", "x" : 709, "y" : 210, "z" : -1, "border" : "TOELDW_2.bmp", "area" : "TZELDW_2.bmp" }, - { "id" : 33, "animation" : "TBELDW_3.def", "x" : 108, "y" : 131, "z" : -1, "border" : "TOELDW_3.bmp", "area" : "TZELDW_3.bmp" }, - { "id" : 34, "animation" : "TBELDW_4.def", "x" : 264, "y" : 168, "z" : -1, "border" : "TOELDW_4.bmp", "area" : "TZELDW_4.bmp" }, - { "id" : 35, "animation" : "TBELDW_5.def", "x" : 394, "y" : 283, "z" : 2, "border" : "TOELDW_5.bmp", "area" : "TZELDW_5.bmp" }, - { "id" : 36, "animation" : "TBELDW_6.def", "x" : 43, "y" : 16, "z" : -2, "border" : "TOELDW_6.bmp", "area" : "TZELDW_6.bmp" }, - { "id" : 37, "animation" : "TBELUP_0.def", "x" : 689, "y" : 250, "border" : "TOELUP_0.bmp", "area" : "TZELUP_0.bmp" }, - { "id" : 38, "animation" : "TBELUP_1.def", "x" : 630, "y" : 50, "border" : "TOELUP_1.bmp", "area" : "TZELUP_1.bmp" }, - { "id" : 39, "animation" : "TBELUP_2.def", "x" : 709, "y" : 210, "z" : -1, "border" : "TOELUP_2.bmp", "area" : "TZELUP_2.bmp" }, - { "id" : 40, "animation" : "TBELUP_3.def", "x" : 108, "y" : 131, "z" : -1, "border" : "TOELUP_3.bmp", "area" : "TZELUP_3.bmp" }, - { "id" : 41, "animation" : "TBELUP_4.def", "x" : 264, "y" : 168, "z" : -1, "border" : "TOELUP_4.bmp", "area" : "TZELUP_4.bmp" }, - { "id" : 42, "animation" : "TBELUP_5.def", "x" : 394, "y" : 283, "z" : 2, "border" : "TOELUP_5.bmp", "area" : "TZELUP_5.bmp" }, - { "id" : 43, "animation" : "TBELUP_6.def", "x" : 43, "y" : 0, "z" : -2, "border" : "TOELUP_6.bmp", "area" : "TZELUP_6.bmp" }, - ], + { + "extraAnimation2":{ "animation" : "TBELEXT5.def", "x" : 682, "y" : 183, "z" : -1, }, + "extraAnimation": { "animation" : "TBELEXT1.def", "x" : 23, "y" : 218 }, + "mageGuild1": { "id" : 0, "animation" : "TBELMAGE.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAGE.bmp", "area" : "TZELMAGE.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBELMAG2.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG2.bmp", "area" : "TZELMAG2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBELMAG3.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG3.bmp", "area" : "TZELMAG3.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBELMAG4.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG4.bmp", "area" : "TZELMAG4.bmp" }, + "mageGuild5": { "id" : 4, "animation" : "TBELMAG5.def", "x" : 206, "y" : 58, "z" : 4, "border" : "TOELMAG5.bmp", "area" : "TZELMAG5.bmp" }, + "tavern": { "id" : 5, "animation" : "TBELTVRN.def", "x" : 553, "y" : 203, "z" : 1, "border" : "TOELTVRN.bmp", "area" : "TZELTVRN.bmp" }, + "shipyard": { "id" : 6, "animation" : "TBELDOCK.def", "x" : 239, "y" : 215, "z" : 2, "border" : "TOELDOCK.bmp", "area" : "TZELDOCK.bmp" }, + "fort": { "id" : 7, "animation" : "TBELCSTL.def", "x" : 349, "y" : 101, "z" : -1, "border" : "TOELCSTL.bmp", "area" : "TZELCSTL.bmp" }, + "citadel": { "id" : 8, "animation" : "TBELCAS2.def", "x" : 349, "y" : 101, "z" : -1, "border" : "TOELCAS2.bmp", "area" : "TZELCAS2.bmp" }, + "castle": { "id" : 9, "animation" : "TBELCAS3.def", "x" : 349, "y" : 101, "z" : -1, "border" : "TOELCAS3.bmp", "area" : "TZELCAS3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBELHALL.def", "x" : -1, "y" : 164, "z" : 5, "border" : "TOELHALL.bmp", "area" : "TZELHALL.bmp" }, + "townHall": { "id" : 11, "animation" : "TBELHAL2.def", "x" : 0, "y" : 165, "z" : 5, "border" : "TOELHAL2.bmp", "area" : "TZELHAL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBELHAL3.def", "x" : 0, "y" : 165, "z" : 5, "border" : "TOELHAL3.bmp", "area" : "TZELHAL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBELHAL4.def", "x" : 0, "y" : 164, "z" : 5, "border" : "TOELHAL4.bmp", "area" : "TZELHAL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBELMARK.def", "x" : 347, "y" : 216, "z" : 4, "border" : "TOELMARK.bmp", "area" : "TZELMARK.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBELSILO.def", "x" : 372, "y" : 171, "z" : 2, "border" : "TOELSILO.bmp", "area" : "TZELSILO.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBELBLAK.def", "x" : 449, "y" : 151, "z" : 1, "border" : "TOELBLAK.bmp", "area" : "TZELBLAK.bmp" }, + "special1": { "id" : 17, "animation" : "TBELSPEC.def", "x" : 284, "y" : 246, "z" : 4, "border" : "TOELSPEC.bmp", "area" : "TZELSPEC.bmp" }, + "horde1": { "id" : 18, "animation" : "TBELHRD1.def", "x" : 689, "y" : 250, "border" : "TOELHRD1.bmp", "area" : "TZELHRD1.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBELHRD2.def", "x" : 689, "y" : 250, "border" : "TOELHRD2.bmp", "area" : "TZELHRD2.bmp", "hidden" : true, "builds" : 18 }, + "ship": { "id" : 20, "animation" : "TBELBOAT.def", "x" : 239, "y" : 215, "z" : 2, "border" : "TOELBOAT.bmp", "area" : "TZELBOAT.bmp", "hidden" : true }, + "special2": { "id" : 21, "animation" : "TBELEXT6.def", "x" : 104, "y" : 170, "z" : 3, "border" : "TOELEXT6.bmp", "area" : "TZELEXT6.bmp" }, + "grail": { "id" : 26, "animation" : "TBELHOLY.def", "x" : 307, "y" : 2, "border" : "TOELHOLY.bmp", "area" : "TZELHOLY.bmp" }, + "extraTownHall": { "id" : 27, "animation" : "TBELEXT2.def", "x" : 232, "y" : 205 }, + "extraCityHall": { "id" : 28, "animation" : "TBELEXT3.def", "x" : 516, "y" : 223, "z" : 1 }, + "extraCapitol": { "id" : 29, "animation" : "TBELEXT4.def", "x" : 0, "y" : 252, "z" : 6 }, + "dwellingLvl1": { "id" : 30, "animation" : "TBELDW_0.def", "x" : 689, "y" : 250, "border" : "TOELDW_0.bmp", "area" : "TZELDW_0.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBELDW_1.def", "x" : 630, "y" : 50, "border" : "TOELDW_1.bmp", "area" : "TZELDW_1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBELDW_2.def", "x" : 709, "y" : 210, "z" : -1, "border" : "TOELDW_2.bmp", "area" : "TZELDW_2.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBELDW_3.def", "x" : 108, "y" : 131, "z" : -1, "border" : "TOELDW_3.bmp", "area" : "TZELDW_3.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBELDW_4.def", "x" : 264, "y" : 168, "z" : -1, "border" : "TOELDW_4.bmp", "area" : "TZELDW_4.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBELDW_5.def", "x" : 394, "y" : 283, "z" : 2, "border" : "TOELDW_5.bmp", "area" : "TZELDW_5.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBELDW_6.def", "x" : 43, "y" : 16, "z" : -2, "border" : "TOELDW_6.bmp", "area" : "TZELDW_6.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBELUP_0.def", "x" : 689, "y" : 250, "border" : "TOELUP_0.bmp", "area" : "TZELUP_0.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBELUP_1.def", "x" : 630, "y" : 50, "border" : "TOELUP_1.bmp", "area" : "TZELUP_1.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBELUP_2.def", "x" : 709, "y" : 210, "z" : -1, "border" : "TOELUP_2.bmp", "area" : "TZELUP_2.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBELUP_3.def", "x" : 108, "y" : 131, "z" : -1, "border" : "TOELUP_3.bmp", "area" : "TZELUP_3.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBELUP_4.def", "x" : 264, "y" : 168, "z" : -1, "border" : "TOELUP_4.bmp", "area" : "TZELUP_4.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBELUP_5.def", "x" : 394, "y" : 283, "z" : 2, "border" : "TOELUP_5.bmp", "area" : "TZELUP_5.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBELUP_6.def", "x" : 43, "y" : 0, "z" : -2, "border" : "TOELUP_6.bmp", "area" : "TZELUP_6.bmp" } + }, "icons" : { "village" : {"normal" : 34, "built" : 35 }, @@ -154,48 +154,53 @@ "moatDamage" : 70, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 6 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 14 ] }, - { "id" : 18, "upgrades" : 30 }, - { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 20, "upgrades" : 6 }, - { "id" : 21, "requires" : [ 0 ] }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30, 0 ] }, - { "id" : 32, "requires" : [ 30, 0 ] }, - { "id" : 33, "requires" : [ 31 ] }, - { "id" : 34, "requires" : [ 32 ] }, - { "id" : 35, "requires" : [ 33, 34 ] }, - { "id" : 36, "requires" : [ 35 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33, "requires" : [ 31 ] }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35, "requires" : [ 1 ] }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "mageGuild5": { "id" : 4, "upgrades" : 3 }, + "tavern": { "id" : 5 }, + "shipyard": { "id" : 6 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 14 ] }, + "horde1": { "id" : 18, "upgrades" : 30 }, + "horde1Upgr": { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, + "ship": { "id" : 20, "upgrades" : 6 }, + "special2": { "id" : 21, "requires" : [ 0 ] }, + "grail": { "id" : 26, "mode" : "grail"}, + "extraTownHall": { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, + "extraCityHall": { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, + "extraCapitol": { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30, 0 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30, 0 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 31 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 32 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 33, 34 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 35 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33, "requires" : [ 31 ] }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35, "requires" : [ 1 ] }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "horde2" : null, + "horde2Upgr" : null, + "special3" : null, + "special4" : null + }, "siege" : { diff --git a/config/factions/dungeon.json b/config/factions/dungeon.json index 6a6d29964..ce62f8d5d 100644 --- a/config/factions/dungeon.json +++ b/config/factions/dungeon.json @@ -74,45 +74,45 @@ "capitol" : "AVCDUNZ0.DEF" }, "structures" : - [ - { "id" : 0, "animation" : "TBDNMAGE.def", "x" : 164, "y" : 119, "z" : -1, "border" : "TODMAG1.bmp", "area" : "TZDMAG1.bmp" }, - { "id" : 1, "animation" : "TBDNMAG2.def", "x" : 164, "y" : 97, "z" : -1, "border" : "TODMAG2.bmp", "area" : "TZDMAG2.bmp" }, - { "id" : 2, "animation" : "TBDNMAG3.def", "x" : 164, "y" : 77, "z" : -1, "border" : "TODMAG3.bmp", "area" : "TZDMAG3.bmp" }, - { "id" : 3, "animation" : "TBDNMAG4.def", "x" : 164, "y" : 61, "z" : -1, "border" : "TODMAG4.bmp", "area" : "TZDMAG4.bmp" }, - { "id" : 4, "animation" : "TBDNMAG5.def", "x" : 164, "y" : 15, "z" : -1, "border" : "TODMAG5.bmp", "area" : "TZDMAG5.bmp" }, - { "id" : 5, "animation" : "TBDNTVRN.def", "x" : 211, "y" : 297, "border" : "TODTAV.bmp", "area" : "TZDTAV.bmp" }, - { "id" : 7, "animation" : "TBDNCSTL.def", "x" : 363, "y" : 87, "z" : 2, "border" : "TODCAS1.bmp", "area" : "TZDCAS1.bmp" }, - { "id" : 8, "animation" : "TBDNCAS2.def", "x" : 363, "y" : 87, "z" : 2, "border" : "TODCAS2.bmp", "area" : "TZDCAS2.bmp" }, - { "id" : 9, "animation" : "TBDNCAS3.def", "x" : 363, "y" : 87, "z" : 2, "border" : "TODCAS3.bmp", "area" : "TZDCAS3.bmp" }, - { "id" : 10, "animation" : "TBDNHALL.def", "x" : 0, "y" : 234, "border" : "TODHALL1.bmp", "area" : "TZDHALL1.bmp" }, - { "id" : 11, "animation" : "TBDNHAL2.def", "x" : 0, "y" : 223, "border" : "TODHALL2.bmp", "area" : "TZDHALL2.bmp" }, - { "id" : 12, "animation" : "TBDNHAL3.def", "x" : 0, "y" : 223, "border" : "TODHALL3.bmp", "area" : "TZDHALL3.bmp" }, - { "id" : 13, "animation" : "TBDNHAL4.def", "x" : 0, "y" : 203, "z" : -1, "border" : "TODHALL4.bmp", "area" : "TZDHALL4.bmp" }, - { "id" : 14, "animation" : "TBDNMARK.def", "x" : 590, "y" : 318, "z" : -2, "border" : "TODMARK.bmp", "area" : "TZDMARK.bmp" }, - { "id" : 15, "animation" : "TBDNSILO.def", "x" : 624, "y" : 335, "z" : 1, "border" : "TODSILO.bmp", "area" : "TZDSILO.bmp" }, - { "id" : 16, "animation" : "TBDNBLAK.def", "x" : 544, "y" : 248, "z" : -3, "border" : "TODSMITH.bmp", "area" : "TZDSMITH.bmp" }, - { "id" : 17, "animation" : "TBDNSPEC.def", "x" : 746, "y" : 294, "z" : 1, "border" : "TODART.bmp", "area" : "TZDART.bmp" }, - { "id" : 18, "animation" : "TBDNHRD1.def", "x" : 0, "y" : 326, "z" : 2, "border" : "TODTR1HA.bmp", "area" : "TZDTR1HA.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBDNHRD2.def", "x" : 0, "y" : 300, "z" : 2, "border" : "TODTR2HA.bmp", "area" : "TZDTR2HA.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 21, "animation" : "TBDNEXT0.def", "x" : 131, "y" : 26 , "border" : "TODVOR1A.bmp", "area" : "TZDVOR1A.bmp" }, - { "id" : 22, "animation" : "TBDNEXT1.def", "x" : 687, "y" : 177, "border" : "TODPORTA.bmp", "area" : "TZDPORTA.bmp" }, - { "id" : 23, "animation" : "TBDNEXT2.def", "x" : 313, "y" : 298, "border" : "TODACAD.bmp", "area" : "TZDACAD.bmp" }, - { "id" : 26, "animation" : "TBDNHOLY.def", "x" : 562, "y" : 24, "z" : 1, "border" : "TODHOLY.bmp", "area" : "TZDHOLY.bmp" }, - { "id" : 30, "animation" : "TBDNDW_0.def", "x" : 0, "y" : 326, "z" : 2, "border" : "TODTRG1A.bmp", "area" : "TZDTRG1A.bmp" }, - { "id" : 31, "animation" : "TBDNDW_1.def", "x" : 0, "y" : 26, "border" : "TODHAR1.bmp", "area" : "TZDHAR1.bmp" }, - { "id" : 32, "animation" : "TBDNDW_2.def", "x" : 118, "y" : 308, "z" : 1, "border" : "TODBEH1A.bmp", "area" : "TZDBEH1A.bmp" }, - { "id" : 33, "animation" : "TBDNDW_3.def", "x" : 300, "y" : 29, "z" : -1, "border" : "TODMED1.bmp", "area" : "TZDMED1.bmp" }, - { "id" : 34, "animation" : "TBDNDW_4.def", "x" : 551, "y" : 186, "z" : 1, "border" : "TODMIN1.bmp", "area" : "TZDMIN1.bmp" }, - { "id" : 35, "animation" : "TBDNDW_5.def", "x" : 270, "y" : 253, "z" : -1, "border" : "TODMAN1.bmp", "area" : "TZDMAN1.bmp" }, - { "id" : 36, "animation" : "TBDNDW_6.def", "x" : 550, "y" : 0, "z" : -1, "border" : "TODDRA1A.bmp", "area" : "TZDDRA1A.bmp" }, - { "id" : 37, "animation" : "TBDNUP_0.def", "x" : 0, "y" : 300, "z" : 2, "border" : "TODTRG2A.bmp", "area" : "TZDTRG2A.bmp" }, - { "id" : 38, "animation" : "TBDNUP_1.def", "x" : 0, "y" : 26, "border" : "TODHAR2.bmp", "area" : "TZDHAR2.bmp" }, - { "id" : 39, "animation" : "TBDNUP_2.def", "x" : 118, "y" : 256, "z" : 1, "border" : "TODBEH2A.bmp", "area" : "TZDBEH2A.bmp" }, - { "id" : 40, "animation" : "TBDNUP_3.def", "x" : 300, "y" : 29, "z" : -1, "border" : "TODMED2.bmp", "area" : "TZDMED2.bmp" }, - { "id" : 41, "animation" : "TBDNUP_4.def", "x" : 519, "y" : 172, "z" : 1, "border" : "TODMIN2.bmp", "area" : "TZDMIN2.bmp" }, - { "id" : 42, "animation" : "TBDNUP_5.def", "x" : 270, "y" : 253, "z" : -1, "border" : "TODMAN2.bmp", "area" : "TZDMAN2.bmp" }, - { "id" : 43, "animation" : "TBDNUP_6.def", "x" : 550, "y" : 0, "z" : -1, "border" : "TODDRA2A.bmp", "area" : "TZDDRA2A.bmp" }, - ], + { + "mageGuild1": { "id" : 0, "animation" : "TBDNMAGE.def", "x" : 164, "y" : 119, "z" : -1, "border" : "TODMAG1.bmp", "area" : "TZDMAG1.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBDNMAG2.def", "x" : 164, "y" : 97, "z" : -1, "border" : "TODMAG2.bmp", "area" : "TZDMAG2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBDNMAG3.def", "x" : 164, "y" : 77, "z" : -1, "border" : "TODMAG3.bmp", "area" : "TZDMAG3.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBDNMAG4.def", "x" : 164, "y" : 61, "z" : -1, "border" : "TODMAG4.bmp", "area" : "TZDMAG4.bmp" }, + "mageGuild5": { "id" : 4, "animation" : "TBDNMAG5.def", "x" : 164, "y" : 15, "z" : -1, "border" : "TODMAG5.bmp", "area" : "TZDMAG5.bmp" }, + "tavern": { "id" : 5, "animation" : "TBDNTVRN.def", "x" : 211, "y" : 297, "border" : "TODTAV.bmp", "area" : "TZDTAV.bmp" }, + "fort": { "id" : 7, "animation" : "TBDNCSTL.def", "x" : 363, "y" : 87, "z" : 2, "border" : "TODCAS1.bmp", "area" : "TZDCAS1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBDNCAS2.def", "x" : 363, "y" : 87, "z" : 2, "border" : "TODCAS2.bmp", "area" : "TZDCAS2.bmp" }, + "castle": { "id" : 9, "animation" : "TBDNCAS3.def", "x" : 363, "y" : 87, "z" : 2, "border" : "TODCAS3.bmp", "area" : "TZDCAS3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBDNHALL.def", "x" : 0, "y" : 234, "border" : "TODHALL1.bmp", "area" : "TZDHALL1.bmp" }, + "townHall": { "id" : 11, "animation" : "TBDNHAL2.def", "x" : 0, "y" : 223, "border" : "TODHALL2.bmp", "area" : "TZDHALL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBDNHAL3.def", "x" : 0, "y" : 223, "border" : "TODHALL3.bmp", "area" : "TZDHALL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBDNHAL4.def", "x" : 0, "y" : 203, "z" : -1, "border" : "TODHALL4.bmp", "area" : "TZDHALL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBDNMARK.def", "x" : 590, "y" : 318, "z" : -2, "border" : "TODMARK.bmp", "area" : "TZDMARK.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBDNSILO.def", "x" : 624, "y" : 335, "z" : 1, "border" : "TODSILO.bmp", "area" : "TZDSILO.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBDNBLAK.def", "x" : 544, "y" : 248, "z" : -3, "border" : "TODSMITH.bmp", "area" : "TZDSMITH.bmp" }, + "special1": { "id" : 17, "animation" : "TBDNSPEC.def", "x" : 746, "y" : 294, "z" : 1, "border" : "TODART.bmp", "area" : "TZDART.bmp" }, + "horde1": { "id" : 18, "animation" : "TBDNHRD1.def", "x" : 0, "y" : 326, "z" : 2, "border" : "TODTR1HA.bmp", "area" : "TZDTR1HA.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBDNHRD2.def", "x" : 0, "y" : 300, "z" : 2, "border" : "TODTR2HA.bmp", "area" : "TZDTR2HA.bmp", "hidden" : true, "builds" : 18 }, + "special2": { "id" : 21, "animation" : "TBDNEXT0.def", "x" : 131, "y" : 26 , "border" : "TODVOR1A.bmp", "area" : "TZDVOR1A.bmp" }, + "special3": { "id" : 22, "animation" : "TBDNEXT1.def", "x" : 687, "y" : 177, "border" : "TODPORTA.bmp", "area" : "TZDPORTA.bmp" }, + "special4": { "id" : 23, "animation" : "TBDNEXT2.def", "x" : 313, "y" : 298, "border" : "TODACAD.bmp", "area" : "TZDACAD.bmp" }, + "grail": { "id" : 26, "animation" : "TBDNHOLY.def", "x" : 562, "y" : 24, "z" : 1, "border" : "TODHOLY.bmp", "area" : "TZDHOLY.bmp" }, + "dwellingLvl1": { "id" : 30, "animation" : "TBDNDW_0.def", "x" : 0, "y" : 326, "z" : 2, "border" : "TODTRG1A.bmp", "area" : "TZDTRG1A.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBDNDW_1.def", "x" : 0, "y" : 26, "border" : "TODHAR1.bmp", "area" : "TZDHAR1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBDNDW_2.def", "x" : 118, "y" : 308, "z" : 1, "border" : "TODBEH1A.bmp", "area" : "TZDBEH1A.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBDNDW_3.def", "x" : 300, "y" : 29, "z" : -1, "border" : "TODMED1.bmp", "area" : "TZDMED1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBDNDW_4.def", "x" : 551, "y" : 186, "z" : 1, "border" : "TODMIN1.bmp", "area" : "TZDMIN1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBDNDW_5.def", "x" : 270, "y" : 253, "z" : -1, "border" : "TODMAN1.bmp", "area" : "TZDMAN1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBDNDW_6.def", "x" : 550, "y" : 0, "z" : -1, "border" : "TODDRA1A.bmp", "area" : "TZDDRA1A.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBDNUP_0.def", "x" : 0, "y" : 300, "z" : 2, "border" : "TODTRG2A.bmp", "area" : "TZDTRG2A.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBDNUP_1.def", "x" : 0, "y" : 26, "border" : "TODHAR2.bmp", "area" : "TZDHAR2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBDNUP_2.def", "x" : 118, "y" : 256, "z" : 1, "border" : "TODBEH2A.bmp", "area" : "TZDBEH2A.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBDNUP_3.def", "x" : 300, "y" : 29, "z" : -1, "border" : "TODMED2.bmp", "area" : "TZDMED2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBDNUP_4.def", "x" : 519, "y" : 172, "z" : 1, "border" : "TODMIN2.bmp", "area" : "TZDMIN2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBDNUP_5.def", "x" : 270, "y" : 253, "z" : -1, "border" : "TODMAN2.bmp", "area" : "TZDMAN2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBDNUP_6.def", "x" : 550, "y" : 0, "z" : -1, "border" : "TODDRA2A.bmp", "area" : "TZDDRA2A.bmp" } + }, "icons" : { "village" : {"normal" : 28, "built" : 29 }, @@ -149,48 +149,50 @@ "moatDamage" : 90, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 14 ] }, - { "id" : 18, "upgrades" : 30 }, - { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 21, "requires" : [ 0 ] }, - { "id" : 22 }, - { "id" : 23 }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 31, 32 ] }, - { "id" : 34, "requires" : [ 33 ] }, - { "id" : 35, "requires" : [ 33 ] }, - { "id" : 36, "requires" : [ 1, 34, 35 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33 }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36, "requires" : [ 2 ] } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "mageGuild5": { "id" : 4, "upgrades" : 3 }, + "tavern": { "id" : 5 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 14 ] }, + "horde1": { "id" : 18, "upgrades" : 30 }, + "horde1Upgr": { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, + "special2": { "id" : 21, "requires" : [ 0 ] }, + "special3": { "id" : 22 }, + "special4": { "id" : 23 }, + "grail": { "id" : 26, "mode" : "grail"}, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 31, 32 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 33 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 33 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 1, 34, 35 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33 }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36, "requires" : [ 2 ] }, + + "horde2" : null, + "horde2Upgr" : null, + "ship" : null, + "shipyard" : null + }, "siege" : { diff --git a/config/factions/fortress.json b/config/factions/fortress.json index 6bf9832c2..1797ce927 100644 --- a/config/factions/fortress.json +++ b/config/factions/fortress.json @@ -74,46 +74,46 @@ "capitol" : "AVCFORZ0.DEF" }, "structures" : - [ - { "animation" : "TBFREXT2.def", "x" : 372, "y" : 227 }, - { "id" : 0, "animation" : "TBFRMAGE.def", "x" : 0, "y" : 200, "z" : -1, "border" : "TOFMAG1A.bmp", "area" : "TZFMAG1A.bmp" }, - { "id" : 1, "animation" : "TBFRMAG2.def", "x" : 0, "y" : 177, "z" : -1, "border" : "TOFMAG2A.bmp", "area" : "TZFMAG2A.bmp" }, - { "id" : 2, "animation" : "TBFRMAG3.def", "x" : 0, "y" : 135, "z" : -1, "border" : "TOFMAG3A.bmp", "area" : "TZFMAG3A.bmp" }, - { "id" : 5, "animation" : "TBFRTVRN.def", "x" : 634, "y" : 219, "z" : 3, "border" : "TOFTAVA.bmp", "area" : "TZFTAVA.bmp" }, - { "id" : 6, "animation" : "TBFRDOCK.def", "x" : 197, "y" : 294, "border" : "TOFDCK2.bmp", "area" : "TZFDCK2.bmp" }, - { "id" : 7, "animation" : "TBFRCSTL.def", "x" : 368, "y" : 118, "z" : -1, "border" : "TOFCAS1.bmp", "area" : "TZFCAS1.bmp" }, - { "id" : 8, "animation" : "TBFRCAS2.def", "x" : 368, "y" : 98, "z" : -1, "border" : "TOFCAS2.bmp", "area" : "TZFCAS2.bmp" }, - { "id" : 9, "animation" : "TBFRCAS3.def", "x" : 368, "y" : 55, "z" : -1, "border" : "TOFCAS3.bmp", "area" : "TZFCAS3.bmp" }, - { "id" : 10, "animation" : "TBFRHALL.def", "x" : 166, "y" : 128, "z" : 1, "border" : "TOFHAL1.bmp", "area" : "TZFHAL1.bmp" }, - { "id" : 11, "animation" : "TBFRHAL2.def", "x" : 166, "y" : 97, "z" : 1, "border" : "TOFHAL2.bmp", "area" : "TZFHAL2.bmp" }, - { "id" : 12, "animation" : "TBFRHAL3.def", "x" : 166, "y" : 51, "z" : 1, "border" : "TOFHAL3.bmp", "area" : "TZFHAL3.bmp" }, - { "id" : 13, "animation" : "TBFRHAL4.def", "x" : 166, "y" : 2, "z" : 1, "border" : "TOFHAL4.bmp", "area" : "TZFHAL4.bmp" }, - { "id" : 14, "animation" : "TBFRMARK.def", "x" : 382, "y" : 219, "z" : 4, "border" : "TOFMRKAA.bmp", "area" : "TZFMRKAA.bmp" }, - { "id" : 15, "animation" : "TBFRSILO.def", "x" : 448, "y" : 210, "z" : 2, "border" : "TOFMRK2A.bmp", "area" : "TZFMRK2A.bmp" }, - { "id" : 16, "animation" : "TBFRBLAK.def", "x" : 360, "y" : 160, "border" : "TOFAIDA.bmp", "area" : "TZFAIDA.bmp" }, - { "id" : 17, "animation" : "TBFRSPEC.def", "x" : 703, "y" : 36, "border" : "TOFCAGE.bmp", "area" : "TZFCAGE.bmp" }, - { "id" : 18, "animation" : "TBFRHRD1.def", "x" : 641, "y" : 121, "z" : 1, "border" : "TOFGNL1H.bmp", "area" : "TZFGNL1H.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBFRHRD2.def", "x" : 641, "y" : 68, "z" : 1, "border" : "TOFGNL2H.bmp", "area" : "TZFGNL2H.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 20, "animation" : "TBFRBOAT.def", "x" : 197, "y" : 294, "z" : 1, "border" : "TOFDCK1.bmp", "area" : "TZFDCK1.bmp", "hidden" : true }, - { "id" : 21, "animation" : "TBFREXT0.def", "x" : 341, "y" : 174, "border" : "TOFCASD.bmp", "area" : "TZFCASD.bmp" }, - { "id" : 22, "animation" : "TBFREXT1.def", "x" : 349, "y" : 79, "z" : -2, "border" : "TOFCASA.bmp", "area" : "TZFCASA.bmp" }, - { "id" : 26, "animation" : "TBFRHOLY.def", "x" : 468, "y" : 260, "z" : 5, "border" : "TOFHLYAA.bmp", "area" : "TZFHLYAA.bmp" }, - { "id" : 29, "animation" : "TBFRWTRW.def", "x" : 320, "y" : 141 }, - { "id" : 30, "animation" : "TBFRDW_0.def", "x" : 641, "y" : 168, "z" : 1, "border" : "TOFGNL1.bmp", "area" : "TZFGNL1.bmp" }, - { "id" : 31, "animation" : "TBFRDW_1.def", "x" : 141, "y" : 178, "border" : "TOFLIZ1.bmp", "area" : "TZFLIZ1.bmp" }, - { "id" : 32, "animation" : "TBFRDW_3.def", "x" : 192, "y" : 85, "border" : "TOFFLY1A.bmp", "area" : "TZFFLY1A.bmp" }, - { "id" : 33, "animation" : "TBFRDW_4.def", "x" : 0, "y" : 292, "border" : "TOFBAS1.bmp", "area" : "TZFBAS1.bmp" }, - { "id" : 34, "animation" : "TBFRDW_2.def", "x" : 15, "y" : 127, "z" : -2, "border" : "TOFGOR1.bmp", "area" : "TZFGOR1.bmp" }, - { "id" : 35, "animation" : "TBFRDW_5.def", "x" : 0, "y" : 4, "border" : "TOFWYV1.bmp", "area" : "TZFWYV1.bmp" }, - { "id" : 36, "animation" : "TBFRDW_6.def", "x" : 612, "y" : 291, "z" : 5, "border" : "TOFHYD1A.bmp", "area" : "TZFHYD1A.bmp" }, - { "id" : 37, "animation" : "TBFRUP_0.def", "x" : 641, "y" : 107, "z" : 1, "border" : "TOFGNL2.bmp", "area" : "TZFGNL2.bmp" }, - { "id" : 38, "animation" : "TBFRUP_1.def", "x" : 125, "y" : 163, "border" : "TOFLIZ2.bmp", "area" : "TZFLIZ2.bmp" }, - { "id" : 39, "animation" : "TBFRUP_3.def", "x" : 159, "y" : 19, "border" : "TOFFLY2A.bmp", "area" : "TZFFLY2A.bmp" }, - { "id" : 40, "animation" : "TBFRUP_4.def", "x" : 0, "y" : 257, "border" : "TOFBAS2.bmp", "area" : "TZFBAS2.bmp" }, - { "id" : 41, "animation" : "TBFRUP_2.def", "x" : 15, "y" : 69, "z" : -2, "border" : "TOFGOR2.bmp", "area" : "TZFGOR2.bmp" }, - { "id" : 42, "animation" : "TBFRUP_5.def", "x" : 0, "y" : 4, "border" : "TOFWYV2.bmp", "area" : "TZFWYV2.bmp" }, - { "id" : 43, "animation" : "TBFRUP_6.def", "x" : 587, "y" : 263, "z" : 5, "border" : "TOFHYD2A.bmp", "area" : "TZFHYD2A.bmp" } - ], + { + "extraAnimation": { "animation" : "TBFREXT2.def", "x" : 372, "y" : 227 }, + "mageGuild1": { "id" : 0, "animation" : "TBFRMAGE.def", "x" : 0, "y" : 200, "z" : -1, "border" : "TOFMAG1A.bmp", "area" : "TZFMAG1A.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBFRMAG2.def", "x" : 0, "y" : 177, "z" : -1, "border" : "TOFMAG2A.bmp", "area" : "TZFMAG2A.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBFRMAG3.def", "x" : 0, "y" : 135, "z" : -1, "border" : "TOFMAG3A.bmp", "area" : "TZFMAG3A.bmp" }, + "tavern": { "id" : 5, "animation" : "TBFRTVRN.def", "x" : 634, "y" : 219, "z" : 3, "border" : "TOFTAVA.bmp", "area" : "TZFTAVA.bmp" }, + "shipyard": { "id" : 6, "animation" : "TBFRDOCK.def", "x" : 197, "y" : 294, "border" : "TOFDCK2.bmp", "area" : "TZFDCK2.bmp" }, + "fort": { "id" : 7, "animation" : "TBFRCSTL.def", "x" : 368, "y" : 118, "z" : -1, "border" : "TOFCAS1.bmp", "area" : "TZFCAS1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBFRCAS2.def", "x" : 368, "y" : 98, "z" : -1, "border" : "TOFCAS2.bmp", "area" : "TZFCAS2.bmp" }, + "castle": { "id" : 9, "animation" : "TBFRCAS3.def", "x" : 368, "y" : 55, "z" : -1, "border" : "TOFCAS3.bmp", "area" : "TZFCAS3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBFRHALL.def", "x" : 166, "y" : 128, "z" : 1, "border" : "TOFHAL1.bmp", "area" : "TZFHAL1.bmp" }, + "townHall": { "id" : 11, "animation" : "TBFRHAL2.def", "x" : 166, "y" : 97, "z" : 1, "border" : "TOFHAL2.bmp", "area" : "TZFHAL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBFRHAL3.def", "x" : 166, "y" : 51, "z" : 1, "border" : "TOFHAL3.bmp", "area" : "TZFHAL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBFRHAL4.def", "x" : 166, "y" : 2, "z" : 1, "border" : "TOFHAL4.bmp", "area" : "TZFHAL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBFRMARK.def", "x" : 382, "y" : 219, "z" : 4, "border" : "TOFMRKAA.bmp", "area" : "TZFMRKAA.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBFRSILO.def", "x" : 448, "y" : 210, "z" : 2, "border" : "TOFMRK2A.bmp", "area" : "TZFMRK2A.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBFRBLAK.def", "x" : 360, "y" : 160, "border" : "TOFAIDA.bmp", "area" : "TZFAIDA.bmp" }, + "special1": { "id" : 17, "animation" : "TBFRSPEC.def", "x" : 703, "y" : 36, "border" : "TOFCAGE.bmp", "area" : "TZFCAGE.bmp" }, + "horde1": { "id" : 18, "animation" : "TBFRHRD1.def", "x" : 641, "y" : 121, "z" : 1, "border" : "TOFGNL1H.bmp", "area" : "TZFGNL1H.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBFRHRD2.def", "x" : 641, "y" : 68, "z" : 1, "border" : "TOFGNL2H.bmp", "area" : "TZFGNL2H.bmp", "hidden" : true, "builds" : 18 }, + "ship": { "id" : 20, "animation" : "TBFRBOAT.def", "x" : 197, "y" : 294, "z" : 1, "border" : "TOFDCK1.bmp", "area" : "TZFDCK1.bmp", "hidden" : true }, + "special2": { "id" : 21, "animation" : "TBFREXT0.def", "x" : 341, "y" : 174, "border" : "TOFCASD.bmp", "area" : "TZFCASD.bmp" }, + "special3": { "id" : 22, "animation" : "TBFREXT1.def", "x" : 349, "y" : 79, "z" : -2, "border" : "TOFCASA.bmp", "area" : "TZFCASA.bmp" }, + "grail": { "id" : 26, "animation" : "TBFRHOLY.def", "x" : 468, "y" : 260, "z" : 5, "border" : "TOFHLYAA.bmp", "area" : "TZFHLYAA.bmp" }, + "extraCapitol": { "id" : 29, "animation" : "TBFRWTRW.def", "x" : 320, "y" : 141 }, + "dwellingLvl1": { "id" : 30, "animation" : "TBFRDW_0.def", "x" : 641, "y" : 168, "z" : 1, "border" : "TOFGNL1.bmp", "area" : "TZFGNL1.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBFRDW_1.def", "x" : 141, "y" : 178, "border" : "TOFLIZ1.bmp", "area" : "TZFLIZ1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBFRDW_3.def", "x" : 192, "y" : 85, "border" : "TOFFLY1A.bmp", "area" : "TZFFLY1A.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBFRDW_4.def", "x" : 0, "y" : 292, "border" : "TOFBAS1.bmp", "area" : "TZFBAS1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBFRDW_2.def", "x" : 15, "y" : 127, "z" : -2, "border" : "TOFGOR1.bmp", "area" : "TZFGOR1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBFRDW_5.def", "x" : 0, "y" : 4, "border" : "TOFWYV1.bmp", "area" : "TZFWYV1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBFRDW_6.def", "x" : 612, "y" : 291, "z" : 5, "border" : "TOFHYD1A.bmp", "area" : "TZFHYD1A.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBFRUP_0.def", "x" : 641, "y" : 107, "z" : 1, "border" : "TOFGNL2.bmp", "area" : "TZFGNL2.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBFRUP_1.def", "x" : 125, "y" : 163, "border" : "TOFLIZ2.bmp", "area" : "TZFLIZ2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBFRUP_3.def", "x" : 159, "y" : 19, "border" : "TOFFLY2A.bmp", "area" : "TZFFLY2A.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBFRUP_4.def", "x" : 0, "y" : 257, "border" : "TOFBAS2.bmp", "area" : "TZFBAS2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBFRUP_2.def", "x" : 15, "y" : 69, "z" : -2, "border" : "TOFGOR2.bmp", "area" : "TZFGOR2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBFRUP_5.def", "x" : 0, "y" : 4, "border" : "TOFWYV2.bmp", "area" : "TZFWYV2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBFRUP_6.def", "x" : 587, "y" : 263, "z" : 5, "border" : "TOFHYD2A.bmp", "area" : "TZFHYD2A.bmp" } + }, "icons" : { "village" : {"normal" : 32, "built" : 33 }, @@ -149,49 +149,51 @@ "moatDamage" : 90, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 6 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 11, 21 ] }, - { "id" : 18, "upgrades" : 30 }, - { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 20, "upgrades" : 6 }, - { "id" : 21, "requires" : [ 7 ] }, - { "id" : 22, "requires" : [ 21 ] }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 32 ] }, - { "id" : 34, "requires" : [ 31, 32 ] }, - { "id" : 35, "requires" : [ 31 ] }, - { "id" : 36, "requires" : [ 33, 35 ] }, - { "id" : 37, "upgrades" : 30, "requires" : [ 5 ] }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33 }, - { "id" : 41, "upgrades" : 34, "requires" : [ 15 ] }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "tavern": { "id" : 5 }, + "shipyard": { "id" : 6 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 11, 21 ] }, + "horde1": { "id" : 18, "upgrades" : 30 }, + "horde1Upgr": { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, + "ship": { "id" : 20, "upgrades" : 6 }, + "special2": { "id" : 21, "requires" : [ 7 ] }, + "special3": { "id" : 22, "requires" : [ 21 ] }, + "grail": { "id" : 26, "mode" : "grail"}, + "extraCapitol": { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 32 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 31, 32 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 31 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 33, 35 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30, "requires" : [ 5 ] }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33 }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34, "requires" : [ 15 ] }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "horde2" : null, + "horde2Upgr" : null, + "mageGuild4" : null, + "mageGuild5" : null, + "special4" : null + }, "siege" : { diff --git a/config/factions/inferno.json b/config/factions/inferno.json index bd3b3e998..7a4f6c2ef 100644 --- a/config/factions/inferno.json +++ b/config/factions/inferno.json @@ -74,46 +74,46 @@ "capitol" : "AVCINFZ0.DEF" }, "structures" : - [ - { "id" : 0, "animation" : "TBINMAGE.def", "x" : 667, "y" : 127, "border" : "TOIMAG1A.bmp", "area" : "TZIMAG1A.bmp" }, - { "id" : 1, "animation" : "TBINMAG2.def", "x" : 667, "y" : 101, "border" : "TOIMAG2A.bmp", "area" : "TZIMAG2A.bmp" }, - { "id" : 2, "animation" : "TBINMAG3.def", "x" : 667, "y" : 83, "border" : "TOIMAG3A.bmp", "area" : "TZIMAG3A.bmp" }, - { "id" : 3, "animation" : "TBINMAG4.def", "x" : 667, "y" : 56, "border" : "TOIMAG4A.bmp", "area" : "TZIMAG4A.bmp" }, - { "id" : 4, "animation" : "TBINMAG5.def", "x" : 667, "y" : 35, "border" : "TOIMAG5A.bmp", "area" : "TZIMAG5A.bmp" }, - { "id" : 5, "animation" : "TBINTVRN.def", "x" : 105, "y" : 219, "z" : 1, "border" : "TOITAV.bmp", "area" : "TZITAV.bmp" }, - { "id" : 7, "animation" : "TBINCSTL.def", "x" : 222, "y" : 44, "border" : "TOICAS2A.bmp", "area" : "TZICAS2A.bmp" }, - { "id" : 8, "animation" : "TBINCAS2.def", "x" : 222, "y" : 44, "border" : "TOICAS1A.bmp", "area" : "TZICAS1A.bmp" }, - { "id" : 9, "animation" : "TBINCAS3.def", "x" : 222, "y" : 18, "border" : "TOICAS3A.bmp", "area" : "TZICAS3A.bmp" }, - { "id" : 10, "animation" : "TBINHALL.def", "x" : 0, "y" : 174, "border" : "TOIHAL1.bmp", "area" : "TZIHAL1.bmp" }, - { "id" : 11, "animation" : "TBINHAL2.def", "x" : 0, "y" : 174, "border" : "TOIHAL2.bmp", "area" : "TZIHAL2.bmp" }, - { "id" : 12, "animation" : "TBINHAL3.def", "x" : 0, "y" : 174, "border" : "TOIHAL3.bmp", "area" : "TZIHAL3.bmp" }, - { "id" : 13, "animation" : "TBINHAL4.def", "x" : 0, "y" : 131, "border" : "TOIHAL4.bmp", "area" : "TZIHAL4.bmp" }, - { "id" : 14, "animation" : "TBINMARK.def", "x" : 511, "y" : 301, "z" : 4, "border" : "TOIMAR1.bmp", "area" : "TZIMAR1.bmp" }, - { "id" : 15, "animation" : "TBINSILO.def", "x" : 497, "y" : 337, "z" : 5, "border" : "TOIMAR2.bmp", "area" : "TZIMAR2.bmp" }, - { "id" : 16, "animation" : "TBINBLAK.def", "x" : 684, "y" : 253, "z" : 1, "border" : "TOIBLKA.bmp", "area" : "TZIBLKA.bmp" }, - { "id" : 18, "animation" : "TBINHRD1.def", "x" : 614, "y" : 256, "border" : "TOIMP1HA.bmp", "area" : "TZIMP1HA.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBINHRD2.def", "x" : 614, "y" : 221, "border" : "TOIMP2HA.bmp", "area" : "TZIMP2HA.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 21, "animation" : "TBINEXT0.def", "x" : 297, "y" : 0, "z" : -1, "border" : "TOICAB1A.bmp", "area" : "TZICAB1A.bmp" }, - { "id" : 22, "animation" : "TBINEXT1.def", "x" : 227, "y" : 174, "z" : 2, "border" : "TOICASGA.bmp", "area" : "TZICASGA.bmp" }, - { "id" : 23, "animation" : "TBINEXT2.def", "x" : 593, "y" : 104, "border" : "TOIPAIN.bmp", "area" : "TZIPAIN.bmp" }, - { "id" : 24, "animation" : "TBINHRD3.def", "x" : 10, "y" : 301, "border" : "TOIHND1H.bmp", "area" : "TZIHND1H.bmp", "hidden" : true }, - { "id" : 25, "animation" : "TBINHRD4.def", "x" : 9, "y" : 273, "border" : "TOIHND2H.bmp", "area" : "TZIHND2H.bmp", "hidden" : true, "builds" : 24 }, - { "id" : 26, "animation" : "TBINHOLY.def", "x" : 24, "y" : 10, "z" : -1, "border" : "TOIHOLY.bmp", "area" : "TZIHOLY.bmp" }, - { "id" : 30, "animation" : "TBINDW_0.def", "x" : 614, "y" : 256, "border" : "TOIMP1A.bmp", "area" : "TZIMP1A.bmp" }, - { "id" : 31, "animation" : "TBINDW_1.def", "x" : 187, "y" : 248, "z" : 4, "border" : "TOIGOG1A.bmp", "area" : "TZIGOG1A.bmp" }, - { "id" : 32, "animation" : "TBINDW_2.def", "x" : 9, "y" : 325, "border" : "TOIHND1.bmp", "area" : "TZIHND1.bmp" }, - { "id" : 33, "animation" : "TBINDW_3.def", "x" : 414, "y" : 204, "z" : 2, "border" : "TOIDMN1.bmp", "area" : "TZIDMN1.bmp" }, - { "id" : 34, "animation" : "TBINDW_4.def", "x" : 359, "y" : 296, "z" : 3, "border" : "TOIPIT1.bmp", "area" : "TZIPIT1.bmp" }, - { "id" : 35, "animation" : "TBINDW_5.def", "x" : 220, "y" : 350, "z" : 5, "border" : "TOIEFR1.bmp", "area" : "TZIEFR1.bmp" }, - { "id" : 36, "animation" : "TBINDW_6.def", "x" : 420, "y" : 153, "z" : -1, "border" : "TOIDVL1.bmp", "area" : "TZIDVL1.bmp" }, - { "id" : 37, "animation" : "TBINUP_0.def", "x" : 614, "y" : 221, "border" : "TOIMP2A.bmp", "area" : "TZIMP2A.bmp" }, - { "id" : 38, "animation" : "TBINUP_1.def", "x" : 187, "y" : 212, "z" : 4, "border" : "TOIGOG2A.bmp", "area" : "TZIGOG2A.bmp" }, - { "id" : 39, "animation" : "TBINUP_2.def", "x" : 9, "y" : 273, "border" : "TOIHND2.bmp", "area" : "TZIHND2.bmp" }, - { "id" : 40, "animation" : "TBINUP_3.def", "x" : 412, "y" : 197, "z" : 2, "border" : "TOIDMN2.bmp", "area" : "TZIDMN2.bmp" }, - { "id" : 41, "animation" : "TBINUP_4.def", "x" : 359, "y" : 244, "z" : 3, "border" : "TOIPIT2.bmp", "area" : "TZIPIT2.bmp" }, - { "id" : 42, "animation" : "TBINUP_5.def", "x" : 220, "y" : 282, "z" : 5, "border" : "TOIEFR2.bmp", "area" : "TZIEFR2.bmp" }, - { "id" : 43, "animation" : "TBINUP_6.def", "x" : 420, "y" : 105, "z" : -1, "border" : "TOIDVL2.bmp", "area" : "TZIDVL2.bmp" } - ], + { + "mageGuild1": { "id" : 0, "animation" : "TBINMAGE.def", "x" : 667, "y" : 127, "border" : "TOIMAG1A.bmp", "area" : "TZIMAG1A.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBINMAG2.def", "x" : 667, "y" : 101, "border" : "TOIMAG2A.bmp", "area" : "TZIMAG2A.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBINMAG3.def", "x" : 667, "y" : 83, "border" : "TOIMAG3A.bmp", "area" : "TZIMAG3A.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBINMAG4.def", "x" : 667, "y" : 56, "border" : "TOIMAG4A.bmp", "area" : "TZIMAG4A.bmp" }, + "mageGuild5": { "id" : 4, "animation" : "TBINMAG5.def", "x" : 667, "y" : 35, "border" : "TOIMAG5A.bmp", "area" : "TZIMAG5A.bmp" }, + "tavern": { "id" : 5, "animation" : "TBINTVRN.def", "x" : 105, "y" : 219, "z" : 1, "border" : "TOITAV.bmp", "area" : "TZITAV.bmp" }, + "fort": { "id" : 7, "animation" : "TBINCSTL.def", "x" : 222, "y" : 44, "border" : "TOICAS2A.bmp", "area" : "TZICAS2A.bmp" }, + "citadel": { "id" : 8, "animation" : "TBINCAS2.def", "x" : 222, "y" : 44, "border" : "TOICAS1A.bmp", "area" : "TZICAS1A.bmp" }, + "castle": { "id" : 9, "animation" : "TBINCAS3.def", "x" : 222, "y" : 18, "border" : "TOICAS3A.bmp", "area" : "TZICAS3A.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBINHALL.def", "x" : 0, "y" : 174, "border" : "TOIHAL1.bmp", "area" : "TZIHAL1.bmp" }, + "townHall": { "id" : 11, "animation" : "TBINHAL2.def", "x" : 0, "y" : 174, "border" : "TOIHAL2.bmp", "area" : "TZIHAL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBINHAL3.def", "x" : 0, "y" : 174, "border" : "TOIHAL3.bmp", "area" : "TZIHAL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBINHAL4.def", "x" : 0, "y" : 131, "border" : "TOIHAL4.bmp", "area" : "TZIHAL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBINMARK.def", "x" : 511, "y" : 301, "z" : 4, "border" : "TOIMAR1.bmp", "area" : "TZIMAR1.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBINSILO.def", "x" : 497, "y" : 337, "z" : 5, "border" : "TOIMAR2.bmp", "area" : "TZIMAR2.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBINBLAK.def", "x" : 684, "y" : 253, "z" : 1, "border" : "TOIBLKA.bmp", "area" : "TZIBLKA.bmp" }, + "horde1": { "id" : 18, "animation" : "TBINHRD1.def", "x" : 614, "y" : 256, "border" : "TOIMP1HA.bmp", "area" : "TZIMP1HA.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBINHRD2.def", "x" : 614, "y" : 221, "border" : "TOIMP2HA.bmp", "area" : "TZIMP2HA.bmp", "hidden" : true, "builds" : 18 }, + "special2": { "id" : 21, "animation" : "TBINEXT0.def", "x" : 297, "y" : 0, "z" : -1, "border" : "TOICAB1A.bmp", "area" : "TZICAB1A.bmp" }, + "special3": { "id" : 22, "animation" : "TBINEXT1.def", "x" : 227, "y" : 174, "z" : 2, "border" : "TOICASGA.bmp", "area" : "TZICASGA.bmp" }, + "special4": { "id" : 23, "animation" : "TBINEXT2.def", "x" : 593, "y" : 104, "border" : "TOIPAIN.bmp", "area" : "TZIPAIN.bmp" }, + "horde2": { "id" : 24, "animation" : "TBINHRD3.def", "x" : 10, "y" : 301, "border" : "TOIHND1H.bmp", "area" : "TZIHND1H.bmp", "hidden" : true }, + "horde2Upgr": { "id" : 25, "animation" : "TBINHRD4.def", "x" : 9, "y" : 273, "border" : "TOIHND2H.bmp", "area" : "TZIHND2H.bmp", "hidden" : true, "builds" : 24 }, + "grail": { "id" : 26, "animation" : "TBINHOLY.def", "x" : 24, "y" : 10, "z" : -1, "border" : "TOIHOLY.bmp", "area" : "TZIHOLY.bmp" }, + "dwellingLvl1": { "id" : 30, "animation" : "TBINDW_0.def", "x" : 614, "y" : 256, "border" : "TOIMP1A.bmp", "area" : "TZIMP1A.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBINDW_1.def", "x" : 187, "y" : 248, "z" : 4, "border" : "TOIGOG1A.bmp", "area" : "TZIGOG1A.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBINDW_2.def", "x" : 9, "y" : 325, "border" : "TOIHND1.bmp", "area" : "TZIHND1.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBINDW_3.def", "x" : 414, "y" : 204, "z" : 2, "border" : "TOIDMN1.bmp", "area" : "TZIDMN1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBINDW_4.def", "x" : 359, "y" : 296, "z" : 3, "border" : "TOIPIT1.bmp", "area" : "TZIPIT1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBINDW_5.def", "x" : 220, "y" : 350, "z" : 5, "border" : "TOIEFR1.bmp", "area" : "TZIEFR1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBINDW_6.def", "x" : 420, "y" : 153, "z" : -1, "border" : "TOIDVL1.bmp", "area" : "TZIDVL1.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBINUP_0.def", "x" : 614, "y" : 221, "border" : "TOIMP2A.bmp", "area" : "TZIMP2A.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBINUP_1.def", "x" : 187, "y" : 212, "z" : 4, "border" : "TOIGOG2A.bmp", "area" : "TZIGOG2A.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBINUP_2.def", "x" : 9, "y" : 273, "border" : "TOIHND2.bmp", "area" : "TZIHND2.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBINUP_3.def", "x" : 412, "y" : 197, "z" : 2, "border" : "TOIDMN2.bmp", "area" : "TZIDMN2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBINUP_4.def", "x" : 359, "y" : 244, "z" : 3, "border" : "TOIPIT2.bmp", "area" : "TZIPIT2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBINUP_5.def", "x" : 220, "y" : 282, "z" : 5, "border" : "TOIEFR2.bmp", "area" : "TZIEFR2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBINUP_6.def", "x" : 420, "y" : 105, "z" : -1, "border" : "TOIDVL2.bmp", "area" : "TZIDVL2.bmp" } + }, "icons" : { "village" : {"normal" : 24, "built" : 25 }, @@ -150,50 +150,50 @@ "moatDamage" : 90, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 18, "upgrades" : 30 }, - { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 21, "requires" : [ 7 ] }, - { "id" : 22, "requires" : [ 8 ] }, - { "id" : 23, "requires" : [ 0 ] }, - { "id" : 24, "upgrades" : 32 }, - { "id" : 25, "upgrades" : 39, "requires" : [ 24 ], "mode" : "auto" }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 26 }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 31 ] }, - { "id" : 34, "requires" : [ 33 ] }, - { "id" : 35, "requires" : [ 0, 33 ] }, - { "id" : 36, "requires" : [ 34, 35 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33 }, - { "id" : 41, "upgrades" : 34, "requires" : [ 1 ] }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "mageGuild5": { "id" : 4, "upgrades" : 3 }, + "tavern": { "id" : 5 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "horde1": { "id" : 18, "upgrades" : 30 }, + "horde1Upgr": { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, + "special2": { "id" : 21, "requires" : [ 7 ] }, + "special3": { "id" : 22, "requires" : [ 8 ] }, + "special4": { "id" : 23, "requires" : [ 0 ] }, + "horde2": { "id" : 24, "upgrades" : 32 }, + "horde2Upgr": { "id" : 25, "upgrades" : 39, "requires" : [ 24 ], "mode" : "auto" }, + "grail": { "id" : 26, "mode" : "grail"}, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 31 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 33 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 0, 33 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 34, 35 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33 }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34, "requires" : [ 1 ] }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "ship" : null, + "shipyard" : null, + "special1" : null + }, "siege" : { diff --git a/config/factions/necropolis.json b/config/factions/necropolis.json index 8e749b8eb..9084e4d74 100644 --- a/config/factions/necropolis.json +++ b/config/factions/necropolis.json @@ -74,50 +74,50 @@ "capitol" : "AVCNECZ0.DEF" }, "structures" : - [ - { "animation" : "TBNCEXT2.def", "x" : 25, "y" : 279 }, - { "id" : 0, "animation" : "TBNCMAGE.def", "x" : 341, "y" : 116, "z" : -1, "border" : "TONMAG1.bmp", "area" : "TZNMAG1.bmp" }, - { "id" : 1, "animation" : "TBNCMAG2.def", "x" : 341, "y" : 97, "z" : -1, "border" : "TONMAG2.bmp", "area" : "TZNMAG2.bmp" }, - { "id" : 2, "animation" : "TBNCMAG3.def", "x" : 341, "y" : 78, "z" : -1, "border" : "TONMAG3.bmp", "area" : "TZNMAG3.bmp" }, - { "id" : 3, "animation" : "TBNCMAG4.def", "x" : 340, "y" : 62, "z" : -1, "border" : "TONMAG4.bmp", "area" : "TZNMAG4.bmp" }, - { "id" : 4, "animation" : "TBNCMAG5.def", "x" : 343, "y" : 35, "z" : -1, "border" : "TONMAG5.bmp", "area" : "TZNMAG5.bmp" }, - { "id" : 5, "animation" : "TBNCTVRN.def", "x" : 508, "y" : 189, "border" : "TONTAV.bmp", "area" : "TZNTAV.bmp" }, - { "id" : 6, "animation" : "TBNCDOCK.def", "x" : 617, "y" : 265, "z" : -2, "border" : "TONSHPBA.bmp", "area" : "TZNSHPBA.bmp" }, - { "id" : 7, "animation" : "TBNCCSTL.def", "x" : 138, "y" : 66, "border" : "TONCAS1.bmp", "area" : "TZNCAS1.bmp" }, - { "id" : 8, "animation" : "TBNCCAS2.def", "x" : 139, "y" : 66, "border" : "TONCAS2.bmp", "area" : "TZNCAS2.bmp" }, - { "id" : 9, "animation" : "TBNCCAS3.def", "x" : 34, "y" : 18, "border" : "TONCAS3.bmp", "area" : "TZNCAS3.bmp" }, - { "id" : 10, "animation" : "TBNCHALL.def", "x" : 468, "y" : 76, "z" : -1, "border" : "TONHAL1.bmp", "area" : "TZNHAL1.bmp" }, - { "id" : 11, "animation" : "TBNCHAL2.def", "x" : 482, "y" : 56, "z" : -1, "border" : "TONHAL2.bmp", "area" : "TZNHAL2.bmp" }, - { "id" : 12, "animation" : "TBNCHAL3.def", "x" : 478, "y" : 26, "z" : -1, "border" : "TONHAL3.bmp", "area" : "TZNHAL3.bmp" }, - { "id" : 13, "animation" : "TBNCHAL4.def", "x" : 481, "y" : 26, "z" : -1, "border" : "TONHAL4.bmp", "area" : "TZNHAL4.bmp" }, - { "id" : 14, "animation" : "TBNCMARK.def", "x" : 347, "y" : 215, "z" : 2, "border" : "TONMRK1.bmp", "area" : "TZNMRK1.bmp" }, - { "id" : 15, "animation" : "TBNCSILO.def", "x" : 276, "y" : 185, "z" : 1, "border" : "TONMRK2.bmp", "area" : "TZNMRK2.bmp" }, - { "id" : 16, "animation" : "TBNCBLAK.def", "x" : 382, "y" : 252, "z" : 4, "border" : "TONSMITA.bmp", "area" : "TZNSMITA.bmp" }, - { "id" : 17, "animation" : "TBNCSPEC.def", "x" : 18, "y" : 0, "z" : -1, "border" : "TONSHRDA.bmp", "area" : "TZNSHRDA.bmp" }, - { "id" : 18, "animation" : "TBNCHRD1.def", "x" : 80, "y" : 222, "z" : 4, "border" : "TONSKE1H.bmp", "area" : "TZNSKE1H.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBNCHRD2.def", "x" : 64, "y" : 222, "z" : 4, "border" : "TONSKE2H.bmp", "area" : "TZNSKE2H.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 20, "animation" : "TBNCBOAT.def", "x" : 617, "y" : 265, "z" : -2, "border" : "TONSHPNA.bmp", "area" : "TZNSHPNA.bmp", "hidden" : true }, - { "id" : 21, "animation" : "TBNCEXT0.def", "x" : 307, "y" : 61, "z" : -2, "border" : "TONNECRA.bmp", "area" : "TZNNECRA.bmp" }, - { "id" : 22, "animation" : "TBNCEXT1.def", "x" : 247, "y" : 275, "z" : 4, "border" : "TONSKELT.bmp", "area" : "TZNSKELT.bmp" }, - { "id" : 26, "animation" : "TBNCHOLY.def", "x" : 410, "y" : 88, "border" : "TONHOLYA.bmp", "area" : "TZNHOLYA.bmp" }, - { "id" : 27, "animation" : "TBNCEXT3.def", "x" : 0, "y" : 241 }, - { "id" : 28, "animation" : "TBNCEXT4.def", "x" : 321, "y" : 255 }, - { "id" : 29, "animation" : "TBNCEXT5.def", "x" : 475, "y" : 257 }, - { "id" : 30, "animation" : "TBNCDW_0.def", "x" : 80, "y" : 222, "z" : 4, "border" : "TONSKEL1.bmp", "area" : "TZNSKEL1.bmp" }, - { "id" : 31, "animation" : "TBNCDW_1.def", "x" : 502, "y" : 223, "border" : "TONZOMB1.bmp", "area" : "TZNZOMB1.bmp" }, - { "id" : 32, "animation" : "TBNCDW_2.def", "x" : 0, "y" : 187, "z" : 2, "border" : "TONWIGH1.bmp", "area" : "TZNWIGH1.bmp" }, - { "id" : 33, "animation" : "TBNCDW_3.def", "x" : 607, "y" : 212, "z" : 2, "border" : "TONVAM1.bmp", "area" : "TZNVAM1.bmp" }, - { "id" : 34, "animation" : "TBNCDW_4.def", "x" : 206, "y" : 207, "z" : 3, "border" : "TONLICH1.bmp", "area" : "TZNLICH1.bmp" }, - { "id" : 35, "animation" : "TBNCDW_5.def", "x" : 0, "y" : 31, "border" : "TONBKN1.bmp", "area" : "TZNBKN1.bmp" }, - { "id" : 36, "animation" : "TBNCDW_6.def", "x" : 663, "y" : 25, "border" : "TONBON1.bmp", "area" : "TZNBON1.bmp" }, - { "id" : 37, "animation" : "TBNCUP_0.def", "x" : 64, "y" : 222, "z" : 4, "border" : "TONSKEL2.bmp", "area" : "TZNSKEL2.bmp" }, - { "id" : 38, "animation" : "TBNCUP_1.def", "x" : 498, "y" : 224, "border" : "TONZOMB2.bmp", "area" : "TZNZOMB2.bmp" }, - { "id" : 39, "animation" : "TBNCUP_2.def", "x" : 0, "y" : 179, "z" : 2, "border" : "TONWIGH2.bmp", "area" : "TZNWIGH2.bmp" }, - { "id" : 40, "animation" : "TBNCUP_3.def", "x" : 615, "y" : 193, "z" : 2, "border" : "TONVAM2.bmp", "area" : "TZNVAM2.bmp" }, - { "id" : 41, "animation" : "TBNCUP_4.def", "x" : 222, "y" : 171, "z" : 3, "border" : "TONLICH2.bmp", "area" : "TZNLICH2.bmp" }, - { "id" : 42, "animation" : "TBNCUP_5.def", "x" : 0, "y" : 30, "border" : "TONBKN2.bmp", "area" : "TZNBKN2.bmp" }, - { "id" : 43, "animation" : "TBNCUP_6.def", "x" : 662, "y" : 23, "border" : "TONBON2.bmp", "area" : "TZNBON2.bmp" } - ], + { + "extraAnimation": { "animation" : "TBNCEXT2.def", "x" : 25, "y" : 279 }, + "mageGuild1": { "id" : 0, "animation" : "TBNCMAGE.def", "x" : 341, "y" : 116, "z" : -1, "border" : "TONMAG1.bmp", "area" : "TZNMAG1.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBNCMAG2.def", "x" : 341, "y" : 97, "z" : -1, "border" : "TONMAG2.bmp", "area" : "TZNMAG2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBNCMAG3.def", "x" : 341, "y" : 78, "z" : -1, "border" : "TONMAG3.bmp", "area" : "TZNMAG3.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBNCMAG4.def", "x" : 340, "y" : 62, "z" : -1, "border" : "TONMAG4.bmp", "area" : "TZNMAG4.bmp" }, + "mageGuild5": { "id" : 4, "animation" : "TBNCMAG5.def", "x" : 343, "y" : 35, "z" : -1, "border" : "TONMAG5.bmp", "area" : "TZNMAG5.bmp" }, + "tavern": { "id" : 5, "animation" : "TBNCTVRN.def", "x" : 508, "y" : 189, "border" : "TONTAV.bmp", "area" : "TZNTAV.bmp" }, + "shipyard": { "id" : 6, "animation" : "TBNCDOCK.def", "x" : 617, "y" : 265, "z" : -2, "border" : "TONSHPBA.bmp", "area" : "TZNSHPBA.bmp" }, + "fort": { "id" : 7, "animation" : "TBNCCSTL.def", "x" : 138, "y" : 66, "border" : "TONCAS1.bmp", "area" : "TZNCAS1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBNCCAS2.def", "x" : 139, "y" : 66, "border" : "TONCAS2.bmp", "area" : "TZNCAS2.bmp" }, + "castle": { "id" : 9, "animation" : "TBNCCAS3.def", "x" : 34, "y" : 18, "border" : "TONCAS3.bmp", "area" : "TZNCAS3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBNCHALL.def", "x" : 468, "y" : 76, "z" : -1, "border" : "TONHAL1.bmp", "area" : "TZNHAL1.bmp" }, + "townHall": { "id" : 11, "animation" : "TBNCHAL2.def", "x" : 482, "y" : 56, "z" : -1, "border" : "TONHAL2.bmp", "area" : "TZNHAL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBNCHAL3.def", "x" : 478, "y" : 26, "z" : -1, "border" : "TONHAL3.bmp", "area" : "TZNHAL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBNCHAL4.def", "x" : 481, "y" : 26, "z" : -1, "border" : "TONHAL4.bmp", "area" : "TZNHAL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBNCMARK.def", "x" : 347, "y" : 215, "z" : 2, "border" : "TONMRK1.bmp", "area" : "TZNMRK1.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBNCSILO.def", "x" : 276, "y" : 185, "z" : 1, "border" : "TONMRK2.bmp", "area" : "TZNMRK2.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBNCBLAK.def", "x" : 382, "y" : 252, "z" : 4, "border" : "TONSMITA.bmp", "area" : "TZNSMITA.bmp" }, + "special1": { "id" : 17, "animation" : "TBNCSPEC.def", "x" : 18, "y" : 0, "z" : -1, "border" : "TONSHRDA.bmp", "area" : "TZNSHRDA.bmp" }, + "horde1": { "id" : 18, "animation" : "TBNCHRD1.def", "x" : 80, "y" : 222, "z" : 4, "border" : "TONSKE1H.bmp", "area" : "TZNSKE1H.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBNCHRD2.def", "x" : 64, "y" : 222, "z" : 4, "border" : "TONSKE2H.bmp", "area" : "TZNSKE2H.bmp", "hidden" : true, "builds" : 18 }, + "ship": { "id" : 20, "animation" : "TBNCBOAT.def", "x" : 617, "y" : 265, "z" : -2, "border" : "TONSHPNA.bmp", "area" : "TZNSHPNA.bmp", "hidden" : true }, + "special2": { "id" : 21, "animation" : "TBNCEXT0.def", "x" : 307, "y" : 61, "z" : -2, "border" : "TONNECRA.bmp", "area" : "TZNNECRA.bmp" }, + "special3": { "id" : 22, "animation" : "TBNCEXT1.def", "x" : 247, "y" : 275, "z" : 4, "border" : "TONSKELT.bmp", "area" : "TZNSKELT.bmp" }, + "grail": { "id" : 26, "animation" : "TBNCHOLY.def", "x" : 410, "y" : 88, "border" : "TONHOLYA.bmp", "area" : "TZNHOLYA.bmp" }, + "extraTownHall": { "id" : 27, "animation" : "TBNCEXT3.def", "x" : 0, "y" : 241 }, + "extraCityHall": { "id" : 28, "animation" : "TBNCEXT4.def", "x" : 321, "y" : 255 }, + "extraCapitol": { "id" : 29, "animation" : "TBNCEXT5.def", "x" : 475, "y" : 257 }, + "dwellingLvl1": { "id" : 30, "animation" : "TBNCDW_0.def", "x" : 80, "y" : 222, "z" : 4, "border" : "TONSKEL1.bmp", "area" : "TZNSKEL1.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBNCDW_1.def", "x" : 502, "y" : 223, "border" : "TONZOMB1.bmp", "area" : "TZNZOMB1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBNCDW_2.def", "x" : 0, "y" : 187, "z" : 2, "border" : "TONWIGH1.bmp", "area" : "TZNWIGH1.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBNCDW_3.def", "x" : 607, "y" : 212, "z" : 2, "border" : "TONVAM1.bmp", "area" : "TZNVAM1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBNCDW_4.def", "x" : 206, "y" : 207, "z" : 3, "border" : "TONLICH1.bmp", "area" : "TZNLICH1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBNCDW_5.def", "x" : 0, "y" : 31, "border" : "TONBKN1.bmp", "area" : "TZNBKN1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBNCDW_6.def", "x" : 663, "y" : 25, "border" : "TONBON1.bmp", "area" : "TZNBON1.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBNCUP_0.def", "x" : 64, "y" : 222, "z" : 4, "border" : "TONSKEL2.bmp", "area" : "TZNSKEL2.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBNCUP_1.def", "x" : 498, "y" : 224, "border" : "TONZOMB2.bmp", "area" : "TZNZOMB2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBNCUP_2.def", "x" : 0, "y" : 179, "z" : 2, "border" : "TONWIGH2.bmp", "area" : "TZNWIGH2.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBNCUP_3.def", "x" : 615, "y" : 193, "z" : 2, "border" : "TONVAM2.bmp", "area" : "TZNVAM2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBNCUP_4.def", "x" : 222, "y" : 171, "z" : 3, "border" : "TONLICH2.bmp", "area" : "TZNLICH2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBNCUP_5.def", "x" : 0, "y" : 30, "border" : "TONBKN2.bmp", "area" : "TZNBKN2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBNCUP_6.def", "x" : 662, "y" : 23, "border" : "TONBON2.bmp", "area" : "TZNBON2.bmp" } + }, "icons" : { "village" : {"normal" : 26, "built" : 27 }, @@ -153,49 +153,53 @@ "moatDamage" : 70, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 6 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 7 ] }, - { "id" : 18, "upgrades" : 30, "requires" : [ 22 ] }, - { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 20, "upgrades" : 6 }, - { "id" : 21, "requires" : [ 0 ] }, - { "id" : 22, "requires" : [ 30 ] }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 31 ] }, - { "id" : 34, "requires" : [ 0, 31 ] }, - { "id" : 35, "requires" : [ 33, 34 ] }, - { "id" : 36, "requires" : [ 35 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33, "requires" : [ 21 ] }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "mageGuild5": { "id" : 4, "upgrades" : 3 }, + "tavern": { "id" : 5 }, + "shipyard": { "id" : 6 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 7 ] }, + "horde1": { "id" : 18, "upgrades" : 30, "requires" : [ 22 ] }, + "horde1Upgr": { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, + "ship": { "id" : 20, "upgrades" : 6 }, + "special2": { "id" : 21, "requires" : [ 0 ] }, + "special3": { "id" : 22, "requires" : [ 30 ] }, + "grail": { "id" : 26, "mode" : "grail"}, + "extraTownHall": { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, + "extraCityHall": { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, + "extraCapitol": { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 31 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 0, 31 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 33, 34 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 35 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33, "requires" : [ 21 ] }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "horde2" : null, + "horde2Upgr" : null, + "special4" : null + }, "siege" : { diff --git a/config/factions/rampart.json b/config/factions/rampart.json index 07cd76a42..23f05c68e 100644 --- a/config/factions/rampart.json +++ b/config/factions/rampart.json @@ -74,50 +74,50 @@ "capitol" : "AVCRAMZ0.DEF" }, "structures" : - [ - { "animation" : "TBRMEXT2.def", "x" : 327, "y" : 236 }, - { "id" : 0, "animation" : "TBRMMAGE.def", "x" : 454, "y" : 200, "z" : -1, "border" : "TORMAG1.bmp", "area" : "TZRMAG1.bmp" }, - { "id" : 1, "animation" : "TBRMMAG2.def", "x" : 438, "y" : 178, "z" : -1, "border" : "TORMAG2.bmp", "area" : "TZRMAG2.bmp" }, - { "id" : 2, "animation" : "TBRMMAG3.def", "x" : 418, "y" : 153, "z" : -1, "border" : "TORMAG3.bmp", "area" : "TZRMAG3.bmp" }, - { "id" : 3, "animation" : "TBRMMAG4.def", "x" : 406, "y" : 129, "z" : -1, "border" : "TORMAG4.bmp", "area" : "TZRMAG4.bmp" }, - { "id" : 4, "animation" : "TBRMMAG5.def", "x" : 384, "y" : 104, "z" : -1, "border" : "TORMAG5.bmp", "area" : "TZRMAG5.bmp" }, - { "id" : 5, "animation" : "TBRMTVRN.def", "x" : 181, "y" : 229, "z" : 1, "border" : "TORTAV.bmp", "area" : "TZRTAV.bmp" }, - { "id" : 7, "animation" : "TBRMCSTL.def", "x" : 63, "y" : 25, "z" : -2, "border" : "TORCAS1.bmp", "area" : "TZRCAS1.bmp" }, - { "id" : 8, "animation" : "TBRMCAS2.def", "x" : 79, "y" : 18, "z" : -2, "border" : "TORCAS3.bmp", "area" : "TZRCAS3.bmp" }, - { "id" : 9, "animation" : "TBRMCAS3.def", "x" : 79, "y" : 18, "z" : -2, "border" : "TORCAS2.bmp", "area" : "TZRCAS2.bmp" }, - { "id" : 10, "animation" : "TBRMHALL.def", "x" : 565, "y" : 216, "border" : "TORHAL1.bmp", "area" : "TZRHAL1.bmp" }, - { "id" : 11, "animation" : "TBRMHAL2.def", "x" : 538, "y" : 187, "border" : "TORHAL2.bmp", "area" : "TZRHAL2.bmp" }, - { "id" : 12, "animation" : "TBRMHAL3.def", "x" : 538, "y" : 187, "border" : "TORHAL3.bmp", "area" : "TZRHAL3.bmp" }, - { "id" : 13, "animation" : "TBRMHAL4.def", "x" : 534, "y" : 187, "border" : "TORHAL4.bmp", "area" : "TZRHAL4.bmp" }, - { "id" : 14, "animation" : "TBRMMARK.def", "x" : 129, "y" : 301, "z" : 3, "border" : "TORMRK1.bmp", "area" : "TZRMRK1.bmp" }, - { "id" : 15, "animation" : "TBRMSILO.def", "x" : 245, "y" : 324, "z" : 4, "border" : "TORMRK2.bmp", "area" : "TZRMRK2.bmp" }, - { "id" : 16, "animation" : "TBRMBLAK.def", "x" : 558, "y" : 105, "z" : -3, "border" : "TORAID.bmp", "area" : "TZRAID.bmp" }, - { "id" : 17, "animation" : "TBRMSPEC.def", "x" : 555, "y" : 297, "border" : "TORGAR1A.bmp", "area" : "TZRGAR1A.bmp" }, - { "id" : 18, "animation" : "TBRMHRD1.def", "x" : 0, "y" : 154, "border" : "TORDWF1H.bmp", "area" : "TZRDWF1H.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBRMHRD2.def", "x" : 0, "y" : 143, "border" : "TORDWF2H.bmp", "area" : "TZRDWF2H.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 21, "animation" : "TBRMEXT0.def", "x" : 555, "y" : 297, "z" : 2, "border" : "TORGAR2A.bmp", "area" : "TZRGAR2A.bmp" }, - { "id" : 22, "animation" : "TBRMEXT1.def", "x" : 0, "y" : 181, "z" : 1, "border" : "TORDWFT.bmp", "area" : "TZRDWFT.bmp" }, - { "id" : 24, "animation" : "TBRMHRD3.def", "x" : 47, "y" : 142, "z" : -1, "border" : "TORTRE1H.bmp", "area" : "TZRTRE1H.bmp", "hidden" : true }, - { "id" : 25, "animation" : "TBRMHRD4.def", "x" : 47, "y" : 142, "z" : -1, "border" : "TORTRE2H.bmp", "area" : "TZRTRE2H.bmp", "hidden" : true, "builds" : 24 }, - { "id" : 26, "animation" : "TBRMHOLY.def", "x" : 0, "y" : 54, "z" : -1, "border" : "TORHOLY.bmp", "area" : "TZRHOLY.bmp" }, - { "id" : 27, "animation" : "TBRMEXT3.def", "x" : 293, "y" : 235 }, - { "id" : 28, "animation" : "TBRMEXT4.def", "x" : 295, "y" : 191 }, - { "id" : 29, "animation" : "TBRMEXT5.def", "x" : 260, "y" : 171 }, - { "id" : 30, "animation" : "TBRMDW_0.def", "x" : 0, "y" : 236, "z" : 2, "border" : "TORCEN1A.bmp", "area" : "TZRCEN1A.bmp" }, - { "id" : 31, "animation" : "TBRMDW_1.def", "x" : 0, "y" : 154, "border" : "TORDWF1.bmp", "area" : "TZRDWF1.bmp" }, - { "id" : 32, "animation" : "TBRMDW_2.def", "x" : 668, "y" : 101, "border" : "TORELF1.bmp", "area" : "TZRELF1.bmp" }, - { "id" : 33, "animation" : "TBRMDW_3.def", "x" : 287, "y" : 73, "z" : -1, "border" : "TORPEG1A.bmp", "area" : "TZRPEG1A.bmp" }, - { "id" : 34, "animation" : "TBRMDW_4.def", "x" : 68, "y" : 146, "z" : -1, "border" : "TORTRE1.bmp", "area" : "TZRTRE1.bmp" }, - { "id" : 35, "animation" : "TBRMDW_5.def", "x" : 362, "y" : 90, "z" : -2, "border" : "TORUNI1.bmp", "area" : "TZRUNI1.bmp" }, - { "id" : 36, "animation" : "TBRMDW_6.def", "x" : 502, "y" : 27, "z" : -5, "border" : "TORDR1AA.bmp", "area" : "TZRDR1AA.bmp" }, - { "id" : 37, "animation" : "TBRMUP_0.def", "x" : 0, "y" : 236, "z" : 2, "border" : "TORCEN2A.bmp", "area" : "TZRCEN2A.bmp" }, - { "id" : 38, "animation" : "TBRMUP_1.def", "x" : 0, "y" : 143, "border" : "TORDWF2.bmp", "area" : "TZRDWF2.bmp" }, - { "id" : 39, "animation" : "TBRMUP_2.def", "x" : 665, "y" : 101, "border" : "TORELF2.bmp", "area" : "TZRELF2.bmp" }, - { "id" : 40, "animation" : "TBRMUP_3.def", "x" : 287, "y" : 28, "z" : -1, "border" : "TORPEG2A.bmp", "area" : "TZRPEG2A.bmp" }, - { "id" : 41, "animation" : "TBRMUP_4.def", "x" : 63, "y" : 146, "z" : -1, "border" : "TORTRE2.bmp", "area" : "TZRTRE2.bmp" }, - { "id" : 42, "animation" : "TBRMUP_5.def", "x" : 362, "y" : 90, "z" : -2, "border" : "TORUNI2.bmp", "area" : "TZRUNI2.bmp" }, - { "id" : 43, "animation" : "TBRMUP_6.def", "x" : 502, "y" : 5, "z" : -5, "border" : "TORDR2AA.bmp", "area" : "TZRDR2AA.bmp" } - ], + { + "extraAnimation": { "animation" : "TBRMEXT2.def", "x" : 327, "y" : 236 }, + "mageGuild1": { "id" : 0, "animation" : "TBRMMAGE.def", "x" : 454, "y" : 200, "z" : -1, "border" : "TORMAG1.bmp", "area" : "TZRMAG1.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBRMMAG2.def", "x" : 438, "y" : 178, "z" : -1, "border" : "TORMAG2.bmp", "area" : "TZRMAG2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBRMMAG3.def", "x" : 418, "y" : 153, "z" : -1, "border" : "TORMAG3.bmp", "area" : "TZRMAG3.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBRMMAG4.def", "x" : 406, "y" : 129, "z" : -1, "border" : "TORMAG4.bmp", "area" : "TZRMAG4.bmp" }, + "mageGuild5": { "id" : 4, "animation" : "TBRMMAG5.def", "x" : 384, "y" : 104, "z" : -1, "border" : "TORMAG5.bmp", "area" : "TZRMAG5.bmp" }, + "tavern": { "id" : 5, "animation" : "TBRMTVRN.def", "x" : 181, "y" : 229, "z" : 1, "border" : "TORTAV.bmp", "area" : "TZRTAV.bmp" }, + "fort": { "id" : 7, "animation" : "TBRMCSTL.def", "x" : 63, "y" : 25, "z" : -2, "border" : "TORCAS1.bmp", "area" : "TZRCAS1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBRMCAS2.def", "x" : 79, "y" : 18, "z" : -2, "border" : "TORCAS3.bmp", "area" : "TZRCAS3.bmp" }, + "castle": { "id" : 9, "animation" : "TBRMCAS3.def", "x" : 79, "y" : 18, "z" : -2, "border" : "TORCAS2.bmp", "area" : "TZRCAS2.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBRMHALL.def", "x" : 565, "y" : 216, "border" : "TORHAL1.bmp", "area" : "TZRHAL1.bmp" }, + "townHall": { "id" : 11, "animation" : "TBRMHAL2.def", "x" : 538, "y" : 187, "border" : "TORHAL2.bmp", "area" : "TZRHAL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBRMHAL3.def", "x" : 538, "y" : 187, "border" : "TORHAL3.bmp", "area" : "TZRHAL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBRMHAL4.def", "x" : 534, "y" : 187, "border" : "TORHAL4.bmp", "area" : "TZRHAL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBRMMARK.def", "x" : 129, "y" : 301, "z" : 3, "border" : "TORMRK1.bmp", "area" : "TZRMRK1.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBRMSILO.def", "x" : 245, "y" : 324, "z" : 4, "border" : "TORMRK2.bmp", "area" : "TZRMRK2.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBRMBLAK.def", "x" : 558, "y" : 105, "z" : -3, "border" : "TORAID.bmp", "area" : "TZRAID.bmp" }, + "special1": { "id" : 17, "animation" : "TBRMSPEC.def", "x" : 555, "y" : 297, "border" : "TORGAR1A.bmp", "area" : "TZRGAR1A.bmp" }, + "horde1": { "id" : 18, "animation" : "TBRMHRD1.def", "x" : 0, "y" : 154, "border" : "TORDWF1H.bmp", "area" : "TZRDWF1H.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBRMHRD2.def", "x" : 0, "y" : 143, "border" : "TORDWF2H.bmp", "area" : "TZRDWF2H.bmp", "hidden" : true, "builds" : 18 }, + "special2": { "id" : 21, "animation" : "TBRMEXT0.def", "x" : 555, "y" : 297, "z" : 2, "border" : "TORGAR2A.bmp", "area" : "TZRGAR2A.bmp" }, + "special3": { "id" : 22, "animation" : "TBRMEXT1.def", "x" : 0, "y" : 181, "z" : 1, "border" : "TORDWFT.bmp", "area" : "TZRDWFT.bmp" }, + "horde2": { "id" : 24, "animation" : "TBRMHRD3.def", "x" : 47, "y" : 142, "z" : -1, "border" : "TORTRE1H.bmp", "area" : "TZRTRE1H.bmp", "hidden" : true }, + "horde2Upgr": { "id" : 25, "animation" : "TBRMHRD4.def", "x" : 47, "y" : 142, "z" : -1, "border" : "TORTRE2H.bmp", "area" : "TZRTRE2H.bmp", "hidden" : true, "builds" : 24 }, + "grail": { "id" : 26, "animation" : "TBRMHOLY.def", "x" : 0, "y" : 54, "z" : -1, "border" : "TORHOLY.bmp", "area" : "TZRHOLY.bmp" }, + "extraTownHall": { "id" : 27, "animation" : "TBRMEXT3.def", "x" : 293, "y" : 235 }, + "extraCityHall": { "id" : 28, "animation" : "TBRMEXT4.def", "x" : 295, "y" : 191 }, + "extraCapitol": { "id" : 29, "animation" : "TBRMEXT5.def", "x" : 260, "y" : 171 }, + "dwellingLvl1": { "id" : 30, "animation" : "TBRMDW_0.def", "x" : 0, "y" : 236, "z" : 2, "border" : "TORCEN1A.bmp", "area" : "TZRCEN1A.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBRMDW_1.def", "x" : 0, "y" : 154, "border" : "TORDWF1.bmp", "area" : "TZRDWF1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBRMDW_2.def", "x" : 668, "y" : 101, "border" : "TORELF1.bmp", "area" : "TZRELF1.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBRMDW_3.def", "x" : 287, "y" : 73, "z" : -1, "border" : "TORPEG1A.bmp", "area" : "TZRPEG1A.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBRMDW_4.def", "x" : 68, "y" : 146, "z" : -1, "border" : "TORTRE1.bmp", "area" : "TZRTRE1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBRMDW_5.def", "x" : 362, "y" : 90, "z" : -2, "border" : "TORUNI1.bmp", "area" : "TZRUNI1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBRMDW_6.def", "x" : 502, "y" : 27, "z" : -5, "border" : "TORDR1AA.bmp", "area" : "TZRDR1AA.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBRMUP_0.def", "x" : 0, "y" : 236, "z" : 2, "border" : "TORCEN2A.bmp", "area" : "TZRCEN2A.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBRMUP_1.def", "x" : 0, "y" : 143, "border" : "TORDWF2.bmp", "area" : "TZRDWF2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBRMUP_2.def", "x" : 665, "y" : 101, "border" : "TORELF2.bmp", "area" : "TZRELF2.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBRMUP_3.def", "x" : 287, "y" : 28, "z" : -1, "border" : "TORPEG2A.bmp", "area" : "TZRPEG2A.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBRMUP_4.def", "x" : 63, "y" : 146, "z" : -1, "border" : "TORTRE2.bmp", "area" : "TZRTRE2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBRMUP_5.def", "x" : 362, "y" : 90, "z" : -2, "border" : "TORUNI2.bmp", "area" : "TZRUNI2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBRMUP_6.def", "x" : 502, "y" : 5, "z" : -5, "border" : "TORDR2AA.bmp", "area" : "TZRDR2AA.bmp" } + }, "icons" : { "village" : {"normal" : 20, "built" : 21 }, @@ -155,50 +155,53 @@ "moatDamage" : 70, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17 }, - { "id" : 18, "upgrades" : 31 }, - { "id" : 19, "upgrades" : 38, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 21, "requires" : [ 17 ] }, - { "id" : 22, "requires" : [ 18, 19 ] }, - { "id" : 24, "upgrades" : 34 }, - { "id" : 25, "upgrades" : 41, "requires" : [ 24 ], "mode" : "auto" }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 26 }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 32 ] }, - { "id" : 34, "requires" : [ 32 ] }, - { "id" : 35, "requires" : [ 33, 34 ] }, - { "id" : 36, "requires" : [ 35, 1 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33 }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36, "requires" : [ 2 ] } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "mageGuild5": { "id" : 4, "upgrades" : 3 }, + "tavern": { "id" : 5 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17 }, + "horde1": { "id" : 18, "upgrades" : 31 }, + "horde1Upgr": { "id" : 19, "upgrades" : 38, "requires" : [ 18 ], "mode" : "auto" }, + "special2": { "id" : 21, "requires" : [ 17 ] }, + "special3": { "id" : 22, "requires" : [ 18, 19 ] }, + "horde2": { "id" : 24, "upgrades" : 34 }, + "horde2Upgr": { "id" : 25, "upgrades" : 41, "requires" : [ 24 ], "mode" : "auto" }, + "grail": { "id" : 26, "mode" : "grail"}, + "extraTownHall": { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, + "extraCityHall": { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, + "extraCapitol": { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 32 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 32 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 33, 34 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 35, 1 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33 }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36, "requires" : [ 2 ] }, + + "ship" : null, + "shipyard" : null, + "special4" : null + }, "siege" : { diff --git a/config/factions/stronghold.json b/config/factions/stronghold.json index d7ef30af4..c5bbf5a8d 100644 --- a/config/factions/stronghold.json +++ b/config/factions/stronghold.json @@ -74,44 +74,44 @@ "capitol" : "AVCSTRZ0.DEF" }, "structures" : - [ - { "animation" : "TBSTEXT3.def", "x" : 23, "y" : 20 }, - { "id" : 0, "animation" : "TBSTMAGE.def", "x" : 473, "y" : 67, "z" : -1, "border" : "TOSMAG1.bmp", "area" : "TZSMAG1.bmp" }, - { "id" : 1, "animation" : "TBSTMAG2.def", "x" : 473, "y" : 37, "z" : -1, "border" : "TOSMAG2.bmp", "area" : "TZSMAG2.bmp" }, - { "id" : 2, "animation" : "TBSTMAG3.def", "x" : 473, "y" : 1, "z" : -1, "border" : "TOSMAG3.bmp", "area" : "TZSMAG3.bmp" }, - { "id" : 5, "animation" : "TBSTTVRN.def", "x" : 170, "y" : 280, "z" : 2, "border" : "TOSTAV.bmp", "area" : "TZSTAV.bmp" }, - { "id" : 7, "animation" : "TBSTCSTL.def", "x" : 402, "y" : 148, "z" : -1, "border" : "TOSCA1.bmp", "area" : "TZSCA1.bmp" }, - { "id" : 8, "animation" : "TBSTCAS2.def", "x" : 402, "y" : 114, "z" : -1, "border" : "TOSCA2.bmp", "area" : "TZSCA2.bmp" }, - { "id" : 9, "animation" : "TBSTCAS3.def", "x" : 402, "y" : 114, "z" : -1, "border" : "TOSCA3.bmp", "area" : "TZSCA3.bmp" }, - { "id" : 10, "animation" : "TBSTHALL.def", "x" : 0, "y" : 259, "border" : "TOSHAL1A.bmp", "area" : "TZSHAL1A.bmp" }, - { "id" : 11, "animation" : "TBSTHAL2.def", "x" : 0, "y" : 225, "border" : "TOSHAL2A.bmp", "area" : "TZSHAL2A.bmp" }, - { "id" : 12, "animation" : "TBSTHAL3.def", "x" : 0, "y" : 201, "border" : "TOSHAL3A.bmp", "area" : "TZSHAL3A.bmp" }, - { "id" : 13, "animation" : "TBSTHAL4.def", "x" : 0, "y" : 148, "border" : "TOSHAL4A.bmp", "area" : "TZSHAL4A.bmp" }, - { "id" : 14, "animation" : "TBSTMARK.def", "x" : 397, "y" : 308, "z" : 1, "border" : "TOSMRK1.bmp", "area" : "TZSMRK1.bmp" }, - { "id" : 15, "animation" : "TBSTSILO.def", "x" : 458, "y" : 248, "z" : 1, "border" : "TOSMRK2.bmp", "area" : "TZSMRK2.bmp" }, - { "id" : 16, "animation" : "TBSTBLAK.def", "x" : 660, "y" : 286, "border" : "TOSBLK1.bmp", "area" : "TZSBLK1.bmp" }, - { "id" : 17, "animation" : "TBSTSPEC.def", "x" : 550, "y" : 229, "border" : "TOSCA1EA.bmp", "area" : "TZSCA1EA.bmp" }, - { "id" : 18, "animation" : "TBSTHRD1.def", "x" : 373, "y" : 239, "border" : "TOSGOB1H.bmp", "area" : "TZSGOB1H.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBSTHRD2.def", "x" : 373, "y" : 220, "border" : "TOSGOB2H.bmp", "area" : "TZSGOB2H.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 21, "animation" : "TBSTEXT0.def", "x" : 473, "y" : 282, "z" : 3, "border" : "TOSMRK1C.bmp", "area" : "TZSMRK1C.bmp" }, - { "id" : 22, "animation" : "TBSTEXT1.def", "x" : 617, "y" : 286, "z" : 1, "border" : "TOSBLK2.bmp", "area" : "TZSBLK2.bmp" }, - { "id" : 23, "animation" : "TBSTEXT2.def", "x" : 313, "y" : 13, "z" : -1, "border" : "TOSVAH.bmp", "area" : "TZSVAH.bmp" }, - { "id" : 26, "animation" : "TBSTHOLY.def", "x" : 321, "y" : 105, "z" : 2, "border" : "TOSHOLYA.bmp", "area" : "TZSHOLYA.bmp" }, - { "id" : 30, "animation" : "TBSTDW_0.def", "x" : 373, "y" : 239, "border" : "TOSGOB1.bmp", "area" : "TZSGOB1.bmp" }, - { "id" : 31, "animation" : "TBSTDW_1.def", "x" : 266, "y" : 246, "z" : 1, "border" : "TOSWOL1.bmp", "area" : "TZSWOL1.bmp" }, - { "id" : 32, "animation" : "TBSTDW_2.def", "x" : 566, "y" : 232, "z" : 2, "border" : "TOSORC1.bmp", "area" : "TZSORC1.bmp" }, - { "id" : 33, "animation" : "TBSTDW_3.def", "x" : 197, "y" : 204, "border" : "TOSOGR1.bmp", "area" : "TZSOGR1.bmp" }, - { "id" : 34, "animation" : "TBSTDW_4.def", "x" : 137, "y" : 30, "z" : -1, "border" : "TOSROC1.bmp", "area" : "TZSROC1.bmp" }, - { "id" : 35, "animation" : "TBSTDW_5.def", "x" : 622, "y" : 160, "z" : -2, "border" : "TOSCYC1.bmp", "area" : "TZSCYC1.bmp" }, - { "id" : 36, "animation" : "TBSTDW_6.def", "x" : 604, "y" : 0, "border" : "TOSBEH1A.bmp", "area" : "TZSBEH1A.bmp" }, - { "id" : 37, "animation" : "TBSTUP_0.def", "x" : 373, "y" : 220, "border" : "TOSGOB2.bmp", "area" : "TZSGOB2.bmp" }, - { "id" : 38, "animation" : "TBSTUP_1.def", "x" : 266, "y" : 225, "z" : 1, "border" : "TOSWOL2.bmp", "area" : "TZSWOL2.bmp" }, - { "id" : 39, "animation" : "TBSTUP_2.def", "x" : 566, "y" : 158, "z" : 2, "border" : "TOSORC2.bmp", "area" : "TZSORC2.bmp" }, - { "id" : 40, "animation" : "TBSTUP_3.def", "x" : 197, "y" : 137, "border" : "TOSOGR2.bmp", "area" : "TZSOGR2.bmp" }, - { "id" : 41, "animation" : "TBSTUP_4.def", "x" : 129, "y" : 15, "z" : -1, "border" : "TOSROC2.bmp", "area" : "TZSROC2.bmp" }, - { "id" : 42, "animation" : "TBSTUP_5.def", "x" : 616, "y" : 93, "z" : -2, "border" : "TOSCYC2A.bmp", "area" : "TZSCYC2A.bmp" }, - { "id" : 43, "animation" : "TBSTUP_6.def", "x" : 604, "y" : 0, "border" : "TOSBEH2A.bmp", "area" : "TZSBEH2A.bmp" } - ], + { + "extraAnimation": { "animation" : "TBSTEXT3.def", "x" : 23, "y" : 20 }, + "mageGuild1": { "id" : 0, "animation" : "TBSTMAGE.def", "x" : 473, "y" : 67, "z" : -1, "border" : "TOSMAG1.bmp", "area" : "TZSMAG1.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBSTMAG2.def", "x" : 473, "y" : 37, "z" : -1, "border" : "TOSMAG2.bmp", "area" : "TZSMAG2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBSTMAG3.def", "x" : 473, "y" : 1, "z" : -1, "border" : "TOSMAG3.bmp", "area" : "TZSMAG3.bmp" }, + "tavern": { "id" : 5, "animation" : "TBSTTVRN.def", "x" : 170, "y" : 280, "z" : 2, "border" : "TOSTAV.bmp", "area" : "TZSTAV.bmp" }, + "fort": { "id" : 7, "animation" : "TBSTCSTL.def", "x" : 402, "y" : 148, "z" : -1, "border" : "TOSCA1.bmp", "area" : "TZSCA1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBSTCAS2.def", "x" : 402, "y" : 114, "z" : -1, "border" : "TOSCA2.bmp", "area" : "TZSCA2.bmp" }, + "castle": { "id" : 9, "animation" : "TBSTCAS3.def", "x" : 402, "y" : 114, "z" : -1, "border" : "TOSCA3.bmp", "area" : "TZSCA3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBSTHALL.def", "x" : 0, "y" : 259, "border" : "TOSHAL1A.bmp", "area" : "TZSHAL1A.bmp" }, + "townHall": { "id" : 11, "animation" : "TBSTHAL2.def", "x" : 0, "y" : 225, "border" : "TOSHAL2A.bmp", "area" : "TZSHAL2A.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBSTHAL3.def", "x" : 0, "y" : 201, "border" : "TOSHAL3A.bmp", "area" : "TZSHAL3A.bmp" }, + "capitol": { "id" : 13, "animation" : "TBSTHAL4.def", "x" : 0, "y" : 148, "border" : "TOSHAL4A.bmp", "area" : "TZSHAL4A.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBSTMARK.def", "x" : 397, "y" : 308, "z" : 1, "border" : "TOSMRK1.bmp", "area" : "TZSMRK1.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBSTSILO.def", "x" : 458, "y" : 248, "z" : 1, "border" : "TOSMRK2.bmp", "area" : "TZSMRK2.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBSTBLAK.def", "x" : 660, "y" : 286, "border" : "TOSBLK1.bmp", "area" : "TZSBLK1.bmp" }, + "special1": { "id" : 17, "animation" : "TBSTSPEC.def", "x" : 550, "y" : 229, "border" : "TOSCA1EA.bmp", "area" : "TZSCA1EA.bmp" }, + "horde1": { "id" : 18, "animation" : "TBSTHRD1.def", "x" : 373, "y" : 239, "border" : "TOSGOB1H.bmp", "area" : "TZSGOB1H.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBSTHRD2.def", "x" : 373, "y" : 220, "border" : "TOSGOB2H.bmp", "area" : "TZSGOB2H.bmp", "hidden" : true, "builds" : 18 }, + "special2": { "id" : 21, "animation" : "TBSTEXT0.def", "x" : 473, "y" : 282, "z" : 3, "border" : "TOSMRK1C.bmp", "area" : "TZSMRK1C.bmp" }, + "special3": { "id" : 22, "animation" : "TBSTEXT1.def", "x" : 617, "y" : 286, "z" : 1, "border" : "TOSBLK2.bmp", "area" : "TZSBLK2.bmp" }, + "special4": { "id" : 23, "animation" : "TBSTEXT2.def", "x" : 313, "y" : 13, "z" : -1, "border" : "TOSVAH.bmp", "area" : "TZSVAH.bmp" }, + "grail": { "id" : 26, "animation" : "TBSTHOLY.def", "x" : 321, "y" : 105, "z" : 2, "border" : "TOSHOLYA.bmp", "area" : "TZSHOLYA.bmp" }, + "dwellingLvl1": { "id" : 30, "animation" : "TBSTDW_0.def", "x" : 373, "y" : 239, "border" : "TOSGOB1.bmp", "area" : "TZSGOB1.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBSTDW_1.def", "x" : 266, "y" : 246, "z" : 1, "border" : "TOSWOL1.bmp", "area" : "TZSWOL1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBSTDW_2.def", "x" : 566, "y" : 232, "z" : 2, "border" : "TOSORC1.bmp", "area" : "TZSORC1.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBSTDW_3.def", "x" : 197, "y" : 204, "border" : "TOSOGR1.bmp", "area" : "TZSOGR1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBSTDW_4.def", "x" : 137, "y" : 30, "z" : -1, "border" : "TOSROC1.bmp", "area" : "TZSROC1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBSTDW_5.def", "x" : 622, "y" : 160, "z" : -2, "border" : "TOSCYC1.bmp", "area" : "TZSCYC1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBSTDW_6.def", "x" : 604, "y" : 0, "border" : "TOSBEH1A.bmp", "area" : "TZSBEH1A.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBSTUP_0.def", "x" : 373, "y" : 220, "border" : "TOSGOB2.bmp", "area" : "TZSGOB2.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBSTUP_1.def", "x" : 266, "y" : 225, "z" : 1, "border" : "TOSWOL2.bmp", "area" : "TZSWOL2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBSTUP_2.def", "x" : 566, "y" : 158, "z" : 2, "border" : "TOSORC2.bmp", "area" : "TZSORC2.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBSTUP_3.def", "x" : 197, "y" : 137, "border" : "TOSOGR2.bmp", "area" : "TZSOGR2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBSTUP_4.def", "x" : 129, "y" : 15, "z" : -1, "border" : "TOSROC2.bmp", "area" : "TZSROC2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBSTUP_5.def", "x" : 616, "y" : 93, "z" : -2, "border" : "TOSCYC2A.bmp", "area" : "TZSCYC2A.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBSTUP_6.def", "x" : 604, "y" : 0, "border" : "TOSBEH2A.bmp", "area" : "TZSBEH2A.bmp" } + }, "icons" : { "village" : {"normal" : 30, "built" : 31 }, @@ -147,48 +147,50 @@ "moatDamage" : 70, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 7 ] }, - { "id" : 18, "upgrades" : 30 }, - { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 21, "requires" : [ 14 ] }, - { "id" : 22, "requires" : [ 16 ] }, - { "id" : 23, "requires" : [ 7 ] }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 32 ] }, - { "id" : 34, "requires" : [ 31 ] }, - { "id" : 35, "requires" : [ 33 ] }, - { "id" : 36, "requires" : [ 34 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31, "requires" : [ 37 ] }, - { "id" : 39, "upgrades" : 32, "requires" : [ 16 ] }, - { "id" : 40, "upgrades" : 33, "requires" : [ 0 ] }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "tavern": { "id" : 5 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 7 ] }, + "horde1": { "id" : 18, "upgrades" : 30 }, + "horde1Upgr": { "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, + "special2": { "id" : 21, "requires" : [ 14 ] }, + "special3": { "id" : 22, "requires" : [ 16 ] }, + "special4": { "id" : 23, "requires" : [ 7 ] }, + "grail": { "id" : 26, "mode" : "grail"}, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 32 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 31 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 33 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 34 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31, "requires" : [ 37 ] }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32, "requires" : [ 16 ] }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33, "requires" : [ 0 ] }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "horde2" : null, + "horde2Upgr" : null, + "mageGuild4" : null, + "mageGuild5" : null, + "ship" : null, + "shipyard" : null + }, "siege" : { diff --git a/config/factions/tower.json b/config/factions/tower.json index 175edecb8..a8e060418 100644 --- a/config/factions/tower.json +++ b/config/factions/tower.json @@ -74,45 +74,45 @@ "capitol" : "AVCTOWZ0.DEF" }, "structures" : - [ - { "id" : 0, "animation" : "TBTWMAGE.def", "x" : 597, "y" : 82, "border" : "TOTGLD1.bmp", "area" : "TZTGLD1.bmp" }, - { "id" : 1, "animation" : "TBTWMAG2.def", "x" : 593, "y" : 65, "border" : "TOTGLD2.bmp", "area" : "TZTGLD2.bmp" }, - { "id" : 2, "animation" : "TBTWMAG3.def", "x" : 593, "y" : 48, "border" : "TOTGLD3.bmp", "area" : "TZTGLD3.bmp" }, - { "id" : 3, "animation" : "TBTWMAG4.def", "x" : 593, "y" : 31, "border" : "TOTGLD4.bmp", "area" : "TZTGLD4.bmp" }, - { "id" : 4, "animation" : "TBTWMAG5.def", "x" : 593, "y" : 14, "border" : "TOTGLD5.bmp", "area" : "TZTGLD5.bmp" }, - { "id" : 5, "animation" : "TBTWTVRN.def", "x" : 375, "y" : 278, "z" : 1, "border" : "TOTTAV.bmp", "area" : "TZTTAV.bmp" }, - { "id" : 7, "animation" : "TBTWCSTL.def", "x" : 304, "y" : 0, "border" : "TOTCAS1.bmp", "area" : "TZTCAS1.bmp" }, - { "id" : 8, "animation" : "TBTWCAS2.def", "x" : 301, "y" : 0, "border" : "TOTCAS2.bmp", "area" : "TZTCAS2.bmp" }, - { "id" : 9, "animation" : "TBTWCAS3.def", "x" : 301, "y" : 0, "border" : "TOTCAS3.bmp", "area" : "TZTCAS3.bmp" }, - { "id" : 10, "animation" : "TBTWHALL.def", "x" : 0, "y" : 259, "z" : 1, "border" : "TOTHAL1.bmp", "area" : "TZTHAL1.bmp" }, - { "id" : 11, "animation" : "TBTWHAL2.def", "x" : 0, "y" : 220, "z" : 1, "border" : "TOTHAL2.bmp", "area" : "TZTHAL2.bmp" }, - { "id" : 12, "animation" : "TBTWHAL3.def", "x" : 0, "y" : 82, "z" : 1, "border" : "TOTHAL3.bmp", "area" : "TZTHAL3.bmp" }, - { "id" : 13, "animation" : "TBTWHAL4.def", "x" : 0, "y" : 82, "z" : 1, "border" : "TOTHAL4.bmp", "area" : "TZTHAL4.bmp" }, - { "id" : 14, "animation" : "TBTWMARK.def", "x" : 614, "y" : 292, "border" : "TOTMRK.bmp", "area" : "TZTMRK.bmp" }, - { "id" : 15, "animation" : "TBTWSILO.def", "x" : 763, "y" : 214, "z" : 3, "border" : "TOTMRKS.bmp", "area" : "TZTMRKS.bmp" }, - { "id" : 16, "animation" : "TBTWBLAK.def", "x" : 478, "y" : 211, "border" : "TOTBLKA.bmp", "area" : "TZTBLKA.bmp" }, - { "id" : 17, "animation" : "TBTWSPEC.def", "x" : 674, "y" : 276, "z" : 2, "border" : "TOTMRKA.bmp", "area" : "TZTMRKA.bmp" }, - { "id" : 18, "animation" : "TBTWHRD1.def", "x" : 0, "y" : 47, "border" : "TOTGAR1H.bmp", "area" : "TZTGAR1H.bmp", "hidden" : true }, - { "id" : 19, "animation" : "TBTWHRD2.def", "x" : 0, "y" : 28, "border" : "TOTGAR2H.bmp", "area" : "TZTGAR2H.bmp", "hidden" : true, "builds" : 18 }, - { "id" : 21, "animation" : "TBTWEXT0.def", "x" : 409, "y" : 82, "border" : "TOTCASW.bmp", "area" : "TZTCASW.bmp" }, - { "id" : 22, "animation" : "TBTWEXT1.def", "x" : 702, "y" : 115, "border" : "TOTGLDL.bmp", "area" : "TZTGLDL.bmp" }, - { "id" : 23, "animation" : "TBTWEXT2.def", "x" : 592, "y" : 189, "z" : 1, "border" : "TOTGLDW.bmp", "area" : "TZTGLDW.bmp" }, - { "id" : 26, "animation" : "TBTWHOLY.def", "x" : 237, "y" : 14, "z" : -1, "border" : "TOTHOLYA.bmp", "area" : "TZTHOLYA.bmp" }, - { "id" : 30, "animation" : "TBTWDW_0.def", "x" : 453, "y" : 221, "z" : 1, "border" : "TOTGRM1A.bmp", "area" : "TZTGRM1A.bmp" }, - { "id" : 31, "animation" : "TBTWDW_1.def", "x" : 4, "y" : 46, "border" : "TOTGAR1.bmp", "area" : "TZTGAR1.bmp" }, - { "id" : 32, "animation" : "TBTWDW_2.def", "x" : 209, "y" : 177, "z" : 1, "border" : "TOTGOL1A.bmp", "area" : "TZTGOL1A.bmp" }, - { "id" : 33, "animation" : "TBTWDW_3.def", "x" : 613, "y" : 95, "border" : "TOTMAG1.bmp", "area" : "TZTMAG1.bmp" }, - { "id" : 34, "animation" : "TBTWDW_4.def", "x" : 511, "y" : 75, "border" : "TOTGEN1.bmp", "area" : "TZTGEN1.bmp" }, - { "id" : 35, "animation" : "TBTWDW_5.def", "x" : 681, "y" : 208, "z" : 2, "border" : "TOTNAG1.bmp", "area" : "TZTNAG1.bmp" }, - { "id" : 36, "animation" : "TBTWDW_6.def", "x" : 75, "y" : 144, "z" : -1, "border" : "TOTTIT1.bmp", "area" : "TZTTIT1.bmp" }, - { "id" : 37, "animation" : "TBTWUP_0.def", "x" : 446, "y" : 221, "z" : 1, "border" : "TOTGRM2A.bmp", "area" : "TZTGRM2A.bmp" }, - { "id" : 38, "animation" : "TBTWUP_1.def", "x" : 4, "y" : 28, "border" : "TOTGAR2.bmp", "area" : "TZTGAR2.bmp" }, - { "id" : 39, "animation" : "TBTWUP_2.def", "x" : 209, "y" : 177, "z" : 1, "border" : "TOTGOL2A.bmp", "area" : "TZTGOL2A.bmp" }, - { "id" : 40, "animation" : "TBTWUP_3.def", "x" : 613, "y" : 74, "border" : "TOTMAG2.bmp", "area" : "TZTMAG2.bmp" }, - { "id" : 41, "animation" : "TBTWUP_4.def", "x" : 511, "y" : 8, "border" : "TOTGEN2.bmp", "area" : "TZTGEN2.bmp" }, - { "id" : 42, "animation" : "TBTWUP_5.def", "x" : 681, "y" : 157, "z" : 2, "border" : "TOTNAG2.bmp", "area" : "TZTNAG2.bmp" }, - { "id" : 43, "animation" : "TBTWUP_6.def", "x" : 75, "y" : 91, "z" : -1, "border" : "TOTTIT2.bmp", "area" : "TZTTIT2.bmp" } - ], + { + "mageGuild1": { "id" : 0, "animation" : "TBTWMAGE.def", "x" : 597, "y" : 82, "border" : "TOTGLD1.bmp", "area" : "TZTGLD1.bmp" }, + "mageGuild2": { "id" : 1, "animation" : "TBTWMAG2.def", "x" : 593, "y" : 65, "border" : "TOTGLD2.bmp", "area" : "TZTGLD2.bmp" }, + "mageGuild3": { "id" : 2, "animation" : "TBTWMAG3.def", "x" : 593, "y" : 48, "border" : "TOTGLD3.bmp", "area" : "TZTGLD3.bmp" }, + "mageGuild4": { "id" : 3, "animation" : "TBTWMAG4.def", "x" : 593, "y" : 31, "border" : "TOTGLD4.bmp", "area" : "TZTGLD4.bmp" }, + "mageGuild5": { "id" : 4, "animation" : "TBTWMAG5.def", "x" : 593, "y" : 14, "border" : "TOTGLD5.bmp", "area" : "TZTGLD5.bmp" }, + "tavern": { "id" : 5, "animation" : "TBTWTVRN.def", "x" : 375, "y" : 278, "z" : 1, "border" : "TOTTAV.bmp", "area" : "TZTTAV.bmp" }, + "fort": { "id" : 7, "animation" : "TBTWCSTL.def", "x" : 304, "y" : 0, "border" : "TOTCAS1.bmp", "area" : "TZTCAS1.bmp" }, + "citadel": { "id" : 8, "animation" : "TBTWCAS2.def", "x" : 301, "y" : 0, "border" : "TOTCAS2.bmp", "area" : "TZTCAS2.bmp" }, + "castle": { "id" : 9, "animation" : "TBTWCAS3.def", "x" : 301, "y" : 0, "border" : "TOTCAS3.bmp", "area" : "TZTCAS3.bmp" }, + "villageHall": { "id" : 10, "animation" : "TBTWHALL.def", "x" : 0, "y" : 259, "z" : 1, "border" : "TOTHAL1.bmp", "area" : "TZTHAL1.bmp" }, + "townHall": { "id" : 11, "animation" : "TBTWHAL2.def", "x" : 0, "y" : 220, "z" : 1, "border" : "TOTHAL2.bmp", "area" : "TZTHAL2.bmp" }, + "cityHall": { "id" : 12, "animation" : "TBTWHAL3.def", "x" : 0, "y" : 82, "z" : 1, "border" : "TOTHAL3.bmp", "area" : "TZTHAL3.bmp" }, + "capitol": { "id" : 13, "animation" : "TBTWHAL4.def", "x" : 0, "y" : 82, "z" : 1, "border" : "TOTHAL4.bmp", "area" : "TZTHAL4.bmp" }, + "marketplace": { "id" : 14, "animation" : "TBTWMARK.def", "x" : 614, "y" : 292, "border" : "TOTMRK.bmp", "area" : "TZTMRK.bmp" }, + "resourceSilo": { "id" : 15, "animation" : "TBTWSILO.def", "x" : 763, "y" : 214, "z" : 3, "border" : "TOTMRKS.bmp", "area" : "TZTMRKS.bmp" }, + "blacksmith": { "id" : 16, "animation" : "TBTWBLAK.def", "x" : 478, "y" : 211, "border" : "TOTBLKA.bmp", "area" : "TZTBLKA.bmp" }, + "special1": { "id" : 17, "animation" : "TBTWSPEC.def", "x" : 674, "y" : 276, "z" : 2, "border" : "TOTMRKA.bmp", "area" : "TZTMRKA.bmp" }, + "horde1": { "id" : 18, "animation" : "TBTWHRD1.def", "x" : 0, "y" : 47, "border" : "TOTGAR1H.bmp", "area" : "TZTGAR1H.bmp", "hidden" : true }, + "horde1Upgr": { "id" : 19, "animation" : "TBTWHRD2.def", "x" : 0, "y" : 28, "border" : "TOTGAR2H.bmp", "area" : "TZTGAR2H.bmp", "hidden" : true, "builds" : 18 }, + "special2": { "id" : 21, "animation" : "TBTWEXT0.def", "x" : 409, "y" : 82, "border" : "TOTCASW.bmp", "area" : "TZTCASW.bmp" }, + "special3": { "id" : 22, "animation" : "TBTWEXT1.def", "x" : 702, "y" : 115, "border" : "TOTGLDL.bmp", "area" : "TZTGLDL.bmp" }, + "special4": { "id" : 23, "animation" : "TBTWEXT2.def", "x" : 592, "y" : 189, "z" : 1, "border" : "TOTGLDW.bmp", "area" : "TZTGLDW.bmp" }, + "grail": { "id" : 26, "animation" : "TBTWHOLY.def", "x" : 237, "y" : 14, "z" : -1, "border" : "TOTHOLYA.bmp", "area" : "TZTHOLYA.bmp" }, + "dwellingLvl1": { "id" : 30, "animation" : "TBTWDW_0.def", "x" : 453, "y" : 221, "z" : 1, "border" : "TOTGRM1A.bmp", "area" : "TZTGRM1A.bmp" }, + "dwellingLvl2": { "id" : 31, "animation" : "TBTWDW_1.def", "x" : 4, "y" : 46, "border" : "TOTGAR1.bmp", "area" : "TZTGAR1.bmp" }, + "dwellingLvl3": { "id" : 32, "animation" : "TBTWDW_2.def", "x" : 209, "y" : 177, "z" : 1, "border" : "TOTGOL1A.bmp", "area" : "TZTGOL1A.bmp" }, + "dwellingLvl4": { "id" : 33, "animation" : "TBTWDW_3.def", "x" : 613, "y" : 95, "border" : "TOTMAG1.bmp", "area" : "TZTMAG1.bmp" }, + "dwellingLvl5": { "id" : 34, "animation" : "TBTWDW_4.def", "x" : 511, "y" : 75, "border" : "TOTGEN1.bmp", "area" : "TZTGEN1.bmp" }, + "dwellingLvl6": { "id" : 35, "animation" : "TBTWDW_5.def", "x" : 681, "y" : 208, "z" : 2, "border" : "TOTNAG1.bmp", "area" : "TZTNAG1.bmp" }, + "dwellingLvl7": { "id" : 36, "animation" : "TBTWDW_6.def", "x" : 75, "y" : 144, "z" : -1, "border" : "TOTTIT1.bmp", "area" : "TZTTIT1.bmp" }, + "dwellingUpLvl1": { "id" : 37, "animation" : "TBTWUP_0.def", "x" : 446, "y" : 221, "z" : 1, "border" : "TOTGRM2A.bmp", "area" : "TZTGRM2A.bmp" }, + "dwellingUpLvl2": { "id" : 38, "animation" : "TBTWUP_1.def", "x" : 4, "y" : 28, "border" : "TOTGAR2.bmp", "area" : "TZTGAR2.bmp" }, + "dwellingUpLvl3": { "id" : 39, "animation" : "TBTWUP_2.def", "x" : 209, "y" : 177, "z" : 1, "border" : "TOTGOL2A.bmp", "area" : "TZTGOL2A.bmp" }, + "dwellingUpLvl4": { "id" : 40, "animation" : "TBTWUP_3.def", "x" : 613, "y" : 74, "border" : "TOTMAG2.bmp", "area" : "TZTMAG2.bmp" }, + "dwellingUpLvl5": { "id" : 41, "animation" : "TBTWUP_4.def", "x" : 511, "y" : 8, "border" : "TOTGEN2.bmp", "area" : "TZTGEN2.bmp" }, + "dwellingUpLvl6": { "id" : 42, "animation" : "TBTWUP_5.def", "x" : 681, "y" : 157, "z" : 2, "border" : "TOTNAG2.bmp", "area" : "TZTNAG2.bmp" }, + "dwellingUpLvl7": { "id" : 43, "animation" : "TBTWUP_6.def", "x" : 75, "y" : 91, "z" : -1, "border" : "TOTTIT2.bmp", "area" : "TZTTIT2.bmp" } + }, "icons" : { "village" : {"normal" : 22, "built" : 23 }, @@ -150,48 +150,50 @@ "moatDamage" : -1, "buildings" : - [ - { "id" : 0 }, - { "id" : 1, "upgrades" : 0 }, - { "id" : 2, "upgrades" : 1 }, - { "id" : 3, "upgrades" : 2 }, - { "id" : 4, "upgrades" : 3 }, - { "id" : 5 }, - { "id" : 7 }, - { "id" : 8, "upgrades" : 7 }, - { "id" : 9, "upgrades" : 8 }, - { "id" : 10, "mode" : "auto" }, - { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, - { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, - { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, - { "id" : 14 }, - { "id" : 15, "requires" : [ 14 ] }, - { "id" : 16 }, - { "id" : 17, "requires" : [ 14 ] }, - { "id" : 18, "upgrades" : 31 }, - { "id" : 19, "upgrades" : 38, "requires" : [ 18 ], "mode" : "auto" }, - { "id" : 21, "requires" : [ 7 ] }, - { "id" : 22, "requires" : [ 0 ] }, - { "id" : 23, "requires" : [ 0 ] }, - { "id" : 26, "mode" : "grail"}, - { "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, - { "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, - { "id" : 29, "requires" : [ 13 ], "mode" : "auto" }, - { "id" : 30, "requires" : [ 7 ] }, - { "id" : 31, "requires" : [ 30 ] }, - { "id" : 32, "requires" : [ 30 ] }, - { "id" : 33, "requires" : [ 0, 31, 32 ] }, - { "id" : 34, "requires" : [ 33 ] }, - { "id" : 35, "requires" : [ 33 ] }, - { "id" : 36, "requires" : [ 34, 35 ] }, - { "id" : 37, "upgrades" : 30 }, - { "id" : 38, "upgrades" : 31 }, - { "id" : 39, "upgrades" : 32 }, - { "id" : 40, "upgrades" : 33, "requires" : [ 22 ] }, - { "id" : 41, "upgrades" : 34 }, - { "id" : 42, "upgrades" : 35 }, - { "id" : 43, "upgrades" : 36 } - ], + { + "mageGuild1": { "id" : 0 }, + "mageGuild2": { "id" : 1, "upgrades" : 0 }, + "mageGuild3": { "id" : 2, "upgrades" : 1 }, + "mageGuild4": { "id" : 3, "upgrades" : 2 }, + "mageGuild5": { "id" : 4, "upgrades" : 3 }, + "tavern": { "id" : 5 }, + "fort": { "id" : 7 }, + "citadel": { "id" : 8, "upgrades" : 7 }, + "castle": { "id" : 9, "upgrades" : 8 }, + "villageHall": { "id" : 10, "mode" : "auto" }, + "townHall": { "id" : 11, "upgrades" : 10, "requires" : [ 5 ] }, + "cityHall": { "id" : 12, "upgrades" : 11, "requires" : [ 0, 14, 16 ] }, + "capitol": { "id" : 13, "upgrades" : 12, "requires" : [ 9 ] }, + "marketplace": { "id" : 14 }, + "resourceSilo": { "id" : 15, "requires" : [ 14 ] }, + "blacksmith": { "id" : 16 }, + "special1": { "id" : 17, "requires" : [ 14 ] }, + "horde1": { "id" : 18, "upgrades" : 31 }, + "horde1Upgr": { "id" : 19, "upgrades" : 38, "requires" : [ 18 ], "mode" : "auto" }, + "special2": { "id" : 21, "requires" : [ 7 ] }, + "special3": { "id" : 22, "requires" : [ 0 ] }, + "special4": { "id" : 23, "requires" : [ 0 ] }, + "grail": { "id" : 26, "mode" : "grail"}, + "dwellingLvl1": { "id" : 30, "requires" : [ 7 ] }, + "dwellingLvl2": { "id" : 31, "requires" : [ 30 ] }, + "dwellingLvl3": { "id" : 32, "requires" : [ 30 ] }, + "dwellingLvl4": { "id" : 33, "requires" : [ 0, 31, 32 ] }, + "dwellingLvl5": { "id" : 34, "requires" : [ 33 ] }, + "dwellingLvl6": { "id" : 35, "requires" : [ 33 ] }, + "dwellingLvl7": { "id" : 36, "requires" : [ 34, 35 ] }, + "dwellingUpLvl1": { "id" : 37, "upgrades" : 30 }, + "dwellingUpLvl2": { "id" : 38, "upgrades" : 31 }, + "dwellingUpLvl3": { "id" : 39, "upgrades" : 32 }, + "dwellingUpLvl4": { "id" : 40, "upgrades" : 33, "requires" : [ 22 ] }, + "dwellingUpLvl5": { "id" : 41, "upgrades" : 34 }, + "dwellingUpLvl6": { "id" : 42, "upgrades" : 35 }, + "dwellingUpLvl7": { "id" : 43, "upgrades" : 36 }, + + "horde2" : null, + "horde2Upgr" : null, + "ship" : null, + "shipyard" : null + }, "siege" : { diff --git a/config/gameConfig.json b/config/gameConfig.json index 8bc34cd74..94c477969 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -45,7 +45,17 @@ "config/heroes/conflux.json", "config/heroes/special.json" ], + + "artifacts" : + [ + "config/artifacts.json" + ], + "heroClasses" : + [ + "config/heroClasses.json" + ], + "bonuses" : [ "config/bonuses.json", diff --git a/config/heroClasses.json b/config/heroClasses.json index 62399c821..bf40a338d 100644 --- a/config/heroClasses.json +++ b/config/heroClasses.json @@ -1,7 +1,7 @@ { "knight": { - "id": 0, + "index": 0, "faction" : "castle", "animation": { @@ -11,7 +11,7 @@ }, "cleric" : { - "id": 1, + "index": 1, "faction" : "castle", "animation": { @@ -21,7 +21,7 @@ }, "ranger" : { - "id": 2, + "index": 2, "faction" : "rampart", "animation": { @@ -31,7 +31,7 @@ }, "druid" : { - "id": 3, + "index": 3, "faction" : "rampart", "animation": { @@ -41,7 +41,7 @@ }, "alchemist" : { - "id": 4, + "index": 4, "faction" : "tower", "animation": { @@ -51,7 +51,7 @@ }, "wizard" : { - "id": 5, + "index": 5, "faction" : "tower", "animation": { @@ -61,7 +61,7 @@ }, "demoniac" : { - "id": 6, + "index": 6, "faction" : "inferno", "animation": { @@ -71,7 +71,7 @@ }, "heretic" : { - "id": 7, + "index": 7, "faction" : "inferno", "animation": { @@ -81,7 +81,7 @@ }, "deathknight" : { - "id": 8, + "index": 8, "faction" : "necropolis", "animation": { @@ -91,7 +91,7 @@ }, "necromancer" : { - "id": 9, + "index": 9, "faction" : "necropolis", "animation": { @@ -101,7 +101,7 @@ }, "warlock" : { - "id": 10, + "index": 10, "faction" : "dungeon", "animation": { @@ -111,7 +111,7 @@ }, "overlord" : { - "id": 11, + "index": 11, "faction" : "dungeon", "animation": { @@ -121,7 +121,7 @@ }, "barbarian" : { - "id": 12, + "index": 12, "faction" : "stronghold", "animation": { @@ -131,7 +131,7 @@ }, "battlemage" : { - "id": 13, + "index": 13, "faction" : "stronghold", "animation": { @@ -141,7 +141,7 @@ }, "beastmaster" : { - "id": 14, + "index": 14, "faction" : "fortress", "animation": { @@ -151,7 +151,7 @@ }, "witch" : { - "id": 15, + "index": 15, "faction" : "fortress", "animation": { @@ -161,7 +161,7 @@ }, "planeswalker" : { - "id": 16, + "index": 16, "faction" : "conflux", "animation": { @@ -171,7 +171,7 @@ }, "elementalist" : { - "id": 17, + "index": 17, "faction" : "conflux", "animation": { diff --git a/config/heroes/castle.json b/config/heroes/castle.json index 65988440f..89b3bc66f 100644 --- a/config/heroes/castle.json +++ b/config/heroes/castle.json @@ -1,7 +1,7 @@ { "orrin": { - "id": 0, + "index": 0, "class" : "knight", "female": false, "skills": @@ -16,7 +16,7 @@ }, "valeska": { - "id": 1, + "index": 1, "class" : "knight", "female": true, "skills": @@ -31,7 +31,7 @@ }, "edric": { - "id": 2, + "index": 2, "class" : "knight", "female": false, "skills": @@ -46,7 +46,7 @@ }, "sylvia": { - "id": 3, + "index": 3, "class" : "knight", "female": true, "skills": @@ -61,7 +61,7 @@ }, "lordHaart": { - "id": 4, + "index": 4, "class" : "knight", "female": false, "special" : true, // Lord Haart in his living form. Disabled in H3 expansions @@ -77,7 +77,7 @@ }, "sorsha": { - "id": 5, + "index": 5, "class" : "knight", "female": true, "skills": @@ -92,7 +92,7 @@ }, "christian": { - "id": 6, + "index": 6, "class" : "knight", "female": false, "skills": @@ -107,7 +107,7 @@ }, "tyris": { - "id": 7, + "index": 7, "class" : "knight", "female": true, "skills": @@ -122,7 +122,7 @@ }, "rion": { - "id": 8, + "index": 8, "class" : "cleric", "female": false, "spellbook": [ "stoneSkin" ], @@ -138,7 +138,7 @@ }, "adela": { - "id": 9, + "index": 9, "class" : "cleric", "female": true, "spellbook": [ "bless" ], @@ -154,7 +154,7 @@ }, "cuthbert": { - "id": 10, + "index": 10, "class" : "cleric", "female": false, "spellbook": [ "weakness" ], @@ -170,7 +170,7 @@ }, "adelaide": { - "id": 11, + "index": 11, "class" : "cleric", "female": true, "spellbook": [ "frostRing" ], @@ -185,7 +185,7 @@ }, "ingham": { - "id": 12, + "index": 12, "class" : "cleric", "female": false, "spellbook": [ "curse" ], @@ -201,7 +201,7 @@ }, "sanya": { - "id": 13, + "index": 13, "class" : "cleric", "female": true, "spellbook": [ "dispel" ], @@ -217,7 +217,7 @@ }, "loynis": { - "id": 14, + "index": 14, "class" : "cleric", "spellbook": [ "prayer" ], "female": false, @@ -233,7 +233,7 @@ }, "caitlin": { - "id": 15, + "index": 15, "class" : "cleric", "female": true, "spellbook": [ "cure" ], diff --git a/config/heroes/conflux.json b/config/heroes/conflux.json index 20bcd5274..64b5aef86 100644 --- a/config/heroes/conflux.json +++ b/config/heroes/conflux.json @@ -1,7 +1,7 @@ { "pasis": { - "id": 128, + "index": 128, "class" : "planeswalker", "female": true, "skills": @@ -17,7 +17,7 @@ }, "thunar": { - "id": 129, + "index": 129, "class" : "planeswalker", "female": true, "skills": @@ -34,7 +34,7 @@ }, "ignissa": { - "id": 130, + "index": 130, "class" : "planeswalker", "female": true, "skills": @@ -51,7 +51,7 @@ }, "lacus": { - "id": 131, + "index": 131, "class" : "planeswalker", "female": true, "skills": @@ -65,7 +65,7 @@ }, "monere": { - "id": 132, + "index": 132, "class" : "planeswalker", "female": false, "skills": @@ -81,7 +81,7 @@ }, "erdamon": { - "id": 133, + "index": 133, "class" : "planeswalker", "female": false, "skills": @@ -98,7 +98,7 @@ }, "fiur": { - "id": 134, + "index": 134, "class" : "planeswalker", "female": false, "skills": @@ -114,7 +114,7 @@ }, "kalt": { - "id": 135, + "index": 135, "class" : "planeswalker", "female": false, "skills": @@ -129,7 +129,7 @@ }, "luna": { - "id": 136, + "index": 136, "class" : "elementalist", "spellbook": [ "fireWall" ], "female": true, @@ -145,7 +145,7 @@ }, "brissa": { - "id": 137, + "index": 137, "class" : "elementalist", "female": true, "spellbook": [ "haste" ], @@ -161,7 +161,7 @@ }, "ciele": { - "id": 138, + "index": 138, "class" : "elementalist", "female": true, "spellbook": [ "magicArrow" ], @@ -177,7 +177,7 @@ }, "labetha": { - "id": 139, + "index": 139, "class" : "elementalist", "female": true, "spellbook": [ "stoneSkin" ], @@ -193,7 +193,7 @@ }, "inteus": { - "id": 140, + "index": 140, "class" : "elementalist", "female": false, "spellbook": [ "bloodlust" ], @@ -209,7 +209,7 @@ }, "aenain": { - "id": 141, + "index": 141, "class" : "elementalist", "female": false, "spellbook": [ "disruptingRay" ], @@ -225,7 +225,7 @@ }, "gelare": { - "id": 142, + "index": 142, "class" : "elementalist", "female": false, "spellbook": [ "dispel" ], @@ -241,7 +241,7 @@ }, "grindan": { - "id": 143, + "index": 143, "class" : "elementalist", "female": false, "spellbook": [ "slow" ], diff --git a/config/heroes/dungeon.json b/config/heroes/dungeon.json index acff2ab41..3e3b93ab3 100644 --- a/config/heroes/dungeon.json +++ b/config/heroes/dungeon.json @@ -1,7 +1,7 @@ { "lorelei": { - "id": 80, + "index": 80, "class" : "warlock", "female": true, "skills": @@ -16,7 +16,7 @@ }, "arlach": { - "id": 81, + "index": 81, "class" : "warlock", "female": false, "skills": @@ -31,7 +31,7 @@ }, "dace": { - "id": 82, + "index": 82, "class" : "warlock", "female": false, "skills": @@ -46,7 +46,7 @@ }, "ajit": { - "id": 83, + "index": 83, "class" : "warlock", "female": false, "skills": @@ -61,7 +61,7 @@ }, "damacon": { - "id": 84, + "index": 84, "class" : "warlock", "female": false, "skills": @@ -75,7 +75,7 @@ }, "gunnar": { - "id": 85, + "index": 85, "class" : "warlock", "female": false, "skills": @@ -90,7 +90,7 @@ }, "synca": { - "id": 86, + "index": 86, "class" : "warlock", "female": true, "skills": @@ -105,7 +105,7 @@ }, "shakti": { - "id": 87, + "index": 87, "class" : "warlock", "female": false, "skills": @@ -120,7 +120,7 @@ }, "alamar": { - "id": 88, + "index": 88, "class" : "overlord", "spellbook": [ "resurrection" ], "female": false, @@ -136,7 +136,7 @@ }, "jaegar": { - "id": 89, + "index": 89, "class" : "overlord", "female": false, "spellbook": [ "shield" ], @@ -152,7 +152,7 @@ }, "malekith": { - "id": 90, + "index": 90, "class" : "overlord", "female": false, "spellbook": [ "bloodlust" ], @@ -168,7 +168,7 @@ }, "jeddite": { - "id": 91, + "index": 91, "class" : "overlord", "female": true, "spellbook": [ "resurrection" ], @@ -183,7 +183,7 @@ }, "geon": { - "id": 92, + "index": 92, "class" : "overlord", "female": false, "spellbook": [ "slow" ], @@ -199,7 +199,7 @@ }, "deemer": { - "id": 93, + "index": 93, "class" : "overlord", "female": false, "spellbook": [ "meteorShower" ], @@ -215,7 +215,7 @@ }, "sephinroth": { - "id": 94, + "index": 94, "class" : "overlord", "female": true, "spellbook": [ "protectAir" ], @@ -231,7 +231,7 @@ }, "darkstorn": { - "id": 95, + "index": 95, "class" : "overlord", "female": false, "spellbook": [ "stoneSkin" ], diff --git a/config/heroes/fortress.json b/config/heroes/fortress.json index 43d10ca26..ca7f8124a 100644 --- a/config/heroes/fortress.json +++ b/config/heroes/fortress.json @@ -1,7 +1,7 @@ { "bron": { - "id": 112, + "index": 112, "class" : "beastmaster", "female": false, "skills": @@ -16,7 +16,7 @@ }, "drakon": { - "id": 113, + "index": 113, "class" : "beastmaster", "female": false, "skills": @@ -31,7 +31,7 @@ }, "wystan": { - "id": 114, + "index": 114, "class" : "beastmaster", "female": false, "skills": @@ -46,7 +46,7 @@ }, "tazar": { - "id": 115, + "index": 115, "class" : "beastmaster", "female": false, "skills": @@ -60,7 +60,7 @@ }, "alkin": { - "id": 116, + "index": 116, "class" : "beastmaster", "female": false, "skills": @@ -75,7 +75,7 @@ }, "korbac": { - "id": 117, + "index": 117, "class" : "beastmaster", "female": false, "skills": @@ -90,7 +90,7 @@ }, "gerwulf": { - "id": 118, + "index": 118, "class" : "beastmaster", "female": false, "skills": @@ -105,7 +105,7 @@ }, "broghild": { - "id": 119, + "index": 119, "class" : "beastmaster", "female": false, "skills": @@ -120,7 +120,7 @@ }, "mirlanda": { - "id": 120, + "index": 120, "class" : "witch", "spellbook": [ "weakness" ], "female": true, @@ -135,7 +135,7 @@ }, "rosic": { - "id": 121, + "index": 121, "class" : "witch", "female": true, "spellbook": [ "magicArrow" ], @@ -151,7 +151,7 @@ }, "voy": { - "id": 122, + "index": 122, "class" : "witch", "female": true, "spellbook": [ "slow" ], @@ -167,7 +167,7 @@ }, "verdish": { - "id": 123, + "index": 123, "class" : "witch", "female": true, "spellbook": [ "protectFire" ], @@ -183,7 +183,7 @@ }, "merist": { - "id": 124, + "index": 124, "class" : "witch", "female": true, "spellbook": [ "stoneSkin" ], @@ -199,7 +199,7 @@ }, "styg": { - "id": 125, + "index": 125, "class" : "witch", "female": true, "spellbook": [ "shield" ], @@ -215,7 +215,7 @@ }, "andra": { - "id": 126, + "index": 126, "class" : "witch", "female": true, "spellbook": [ "dispel" ], @@ -231,7 +231,7 @@ }, "tiva": { - "id": 127, + "index": 127, "class" : "witch", "female": true, "spellbook": [ "stoneSkin" ], diff --git a/config/heroes/inferno.json b/config/heroes/inferno.json index 53d74c0dc..0019d5aa6 100644 --- a/config/heroes/inferno.json +++ b/config/heroes/inferno.json @@ -1,7 +1,7 @@ { "fiona": { - "id": 48, + "index": 48, "class" : "demoniac", "female": true, "skills": @@ -15,7 +15,7 @@ }, "rashka": { - "id": 49, + "index": 49, "class" : "demoniac", "female": false, "skills": @@ -30,7 +30,7 @@ }, "marius": { - "id": 50, + "index": 50, "class" : "demoniac", "female": true, "skills": @@ -44,7 +44,7 @@ }, "ignatius": { - "id": 51, + "index": 51, "class" : "demoniac", "female": false, "skills": @@ -59,7 +59,7 @@ }, "octavia": { - "id": 52, + "index": 52, "class" : "demoniac", "female": true, "skills": @@ -74,7 +74,7 @@ }, "calh": { - "id": 53, + "index": 53, "class" : "demoniac", "female": false, "skills": @@ -89,7 +89,7 @@ }, "pyre": { - "id": 54, + "index": 54, "class" : "demoniac", "female": true, "skills": @@ -104,7 +104,7 @@ }, "nymus": { - "id": 55, + "index": 55, "class" : "demoniac", "female": true, "skills": @@ -118,7 +118,7 @@ }, "ayden": { - "id": 56, + "index": 56, "class" : "heretic", "spellbook": [ "viewEarth" ], "female": false, @@ -134,7 +134,7 @@ }, "xyron": { - "id": 57, + "index": 57, "class" : "heretic", "female": false, "spellbook": [ "inferno" ], @@ -150,7 +150,7 @@ }, "axsis": { - "id": 58, + "index": 58, "class" : "heretic", "female": false, "spellbook": [ "protectAir" ], @@ -166,7 +166,7 @@ }, "olema": { - "id": 59, + "index": 59, "class" : "heretic", "female": true, "spellbook": [ "weakness" ], @@ -182,7 +182,7 @@ }, "calid": { - "id": 60, + "index": 60, "class" : "heretic", "female": false, "spellbook": [ "haste" ], @@ -198,7 +198,7 @@ }, "ash": { - "id": 61, + "index": 61, "class" : "heretic", "female": true, "spellbook": [ "bloodlust" ], @@ -214,7 +214,7 @@ }, "zydar": { - "id": 62, + "index": 62, "class" : "heretic", "female": false, "spellbook": [ "stoneSkin" ], @@ -230,7 +230,7 @@ }, "xarfax": { - "id": 63, + "index": 63, "class" : "heretic", "female": false, "spellbook": [ "fireball" ], diff --git a/config/heroes/necropolis.json b/config/heroes/necropolis.json index abd5ea5d8..d64feb6f9 100644 --- a/config/heroes/necropolis.json +++ b/config/heroes/necropolis.json @@ -1,7 +1,7 @@ { "straker": { - "id": 64, + "index": 64, "class" : "deathknight", "female": false, "spellbook": [ "haste" ], @@ -17,7 +17,7 @@ }, "vokial": { - "id": 65, + "index": 65, "class" : "deathknight", "female": false, "spellbook": [ "stoneSkin" ], @@ -33,7 +33,7 @@ }, "moandor": { - "id": 66, + "index": 66, "class" : "deathknight", "female": false, "spellbook": [ "slow" ], @@ -49,7 +49,7 @@ }, "charna": { - "id": 67, + "index": 67, "class" : "deathknight", "female": true, "spellbook": [ "magicArrow" ], @@ -65,7 +65,7 @@ }, "tamika": { - "id": 68, + "index": 68, "class" : "deathknight", "female": true, "spellbook": [ "magicArrow" ], @@ -81,7 +81,7 @@ }, "isra": { - "id": 69, + "index": 69, "class" : "deathknight", "female": true, "spellbook": [ "magicArrow" ], @@ -96,7 +96,7 @@ }, "clavius": { - "id": 70, + "index": 70, "class" : "deathknight", "female": false, "spellbook": [ "magicArrow" ], @@ -112,7 +112,7 @@ }, "galthran": { - "id": 71, + "index": 71, "class" : "deathknight", "female": false, "spellbook": [ "shield" ], @@ -128,7 +128,7 @@ }, "septienna": { - "id": 72, + "index": 72, "class" : "necromancer", "female": true, "spellbook": [ "deathRipple" ], @@ -144,7 +144,7 @@ }, "aislinn": { - "id": 73, + "index": 73, "class" : "necromancer", "female": true, "spellbook": [ "meteorShower" ], @@ -160,7 +160,7 @@ }, "sandro": { - "id": 74, + "index": 74, "class" : "necromancer", "female": false, "spellbook": [ "slow" ], @@ -176,7 +176,7 @@ }, "nimbus": { - "id": 75, + "index": 75, "class" : "necromancer", "female": false, "spellbook": [ "shield" ], @@ -192,7 +192,7 @@ }, "thant": { - "id": 76, + "index": 76, "class" : "necromancer", "female": false, "spellbook": [ "animateDead" ], @@ -208,7 +208,7 @@ }, "xsi": { - "id": 77, + "index": 77, "class" : "necromancer", "female": true, "spellbook": [ "stoneSkin" ], @@ -224,7 +224,7 @@ }, "vidomina": { - "id": 78, + "index": 78, "class" : "necromancer", "female": true, "spellbook": [ "curse" ], @@ -239,7 +239,7 @@ }, "nagash": { - "id": 79, + "index": 79, "class" : "necromancer", "female": false, "spellbook": [ "protectAir" ], diff --git a/config/heroes/rampart.json b/config/heroes/rampart.json index 505eb4c1a..7d4282fa5 100644 --- a/config/heroes/rampart.json +++ b/config/heroes/rampart.json @@ -1,7 +1,7 @@ { "mephala": { - "id": 16, + "index": 16, "class" : "ranger", "female": true, "skills": @@ -16,7 +16,7 @@ }, "ufretin": { - "id": 17, + "index": 17, "class" : "ranger", "female": false, "skills": @@ -31,7 +31,7 @@ }, "jenova": { - "id": 18, + "index": 18, "class" : "ranger", "female": true, "skills": @@ -45,7 +45,7 @@ }, "ryland": { - "id": 19, + "index": 19, "class" : "ranger", "female": false, "skills": @@ -60,7 +60,7 @@ }, "thorgrim": { - "id": 20, + "index": 20, "class" : "ranger", "female": false, "skills": @@ -74,7 +74,7 @@ }, "ivor": { - "id": 21, + "index": 21, "class" : "ranger", "female": false, "skills": @@ -89,7 +89,7 @@ }, "clancy": { - "id": 22, + "index": 22, "class" : "ranger", "female": false, "skills": @@ -104,7 +104,7 @@ }, "kyrre": { - "id": 23, + "index": 23, "class" : "ranger", "female": true, "skills": @@ -119,7 +119,7 @@ }, "coronius": { - "id": 24, + "index": 24, "class" : "druid", "spellbook": [ "slayer" ], "female": false, @@ -135,7 +135,7 @@ }, "uland": { - "id": 25, + "index": 25, "class" : "druid", "female": false, "spellbook": [ "cure" ], @@ -151,7 +151,7 @@ }, "elleshar": { - "id": 26, + "index": 26, "class" : "druid", "female": false, "spellbook": [ "curse" ], @@ -167,7 +167,7 @@ }, "gem": { - "id": 27, + "index": 27, "class" : "druid", "female": true, "spellbook": [ "summonBoat" ], @@ -183,7 +183,7 @@ }, "malcom": { - "id": 28, + "index": 28, "class" : "druid", "female": false, "spellbook": [ "magicArrow" ], @@ -199,7 +199,7 @@ }, "melodia": { - "id": 29, + "index": 29, "class" : "druid", "spellbook": [ "fortune" ], "female": true, @@ -215,7 +215,7 @@ }, "alagar": { - "id": 30, + "index": 30, "class" : "druid", "female": false, "spellbook": [ "iceBolt" ], @@ -231,7 +231,7 @@ }, "aeris": { - "id": 31, + "index": 31, "class" : "druid", "female": false, "spellbook": [ "protectAir" ], diff --git a/config/heroes/special.json b/config/heroes/special.json index 8c345fa05..4227c2c77 100644 --- a/config/heroes/special.json +++ b/config/heroes/special.json @@ -2,7 +2,7 @@ // "special" heroes for campaigns "sirMullich": { - "id": 144, + "index": 144, "class" : "knight", "female": false, "special" : true, @@ -17,7 +17,7 @@ }, "adrienne": { - "id": 145, + "index": 145, "class" : "witch", "female": true, "special" : true, @@ -33,7 +33,7 @@ }, "catherine": { - "id": 146, + "index": 146, "class" : "knight", "female": true, "special" : true, @@ -49,7 +49,7 @@ }, "dracon": { - "id": 147, + "index": 147, "class" : "wizard", "female": false, "special" : true, @@ -66,7 +66,7 @@ }, "gelu": { - "id": 148, + "index": 148, "class" : "ranger", "female": false, "special" : true, @@ -83,7 +83,7 @@ }, "kilgor": { - "id": 149, + "index": 149, "class" : "barbarian", "female": false, "special" : true, @@ -100,7 +100,7 @@ }, "undeadHaart": // undead version of Lord Haart { - "id": 150, + "index": 150, "class" : "deathknight", "female": false, "special" : true, @@ -118,7 +118,7 @@ }, "mutare": { - "id": 151, + "index": 151, "class" : "warlock", "female": true, "special" : true, @@ -136,7 +136,7 @@ }, "roland": { - "id": 152, + "index": 152, "class" : "knight", "female": false, "special" : true, @@ -152,7 +152,7 @@ }, "mutareDrake": { - "id": 153, + "index": 153, "class" : "warlock", "female": true, "special" : true, @@ -182,7 +182,7 @@ }, "boragus": { - "id": 154, + "index": 154, "class" : "barbarian", "female": false, "special" : true, @@ -210,7 +210,7 @@ }, "xeron": { - "id": 155, + "index": 155, "class" : "demoniac", "female": false, "special" : true, diff --git a/config/heroes/stronghold.json b/config/heroes/stronghold.json index 38e54ddae..825e63fe2 100644 --- a/config/heroes/stronghold.json +++ b/config/heroes/stronghold.json @@ -1,7 +1,7 @@ { "yog": { - "id": 96, + "index": 96, "class" : "barbarian", "female": false, "skills": @@ -16,7 +16,7 @@ }, "gurnisson": { - "id": 97, + "index": 97, "class" : "barbarian", "female": false, "skills": @@ -31,7 +31,7 @@ }, "jabarkas": { - "id": 98, + "index": 98, "class" : "barbarian", "female": false, "skills": @@ -46,7 +46,7 @@ }, "shiva": { - "id": 99, + "index": 99, "class" : "barbarian", "female": true, "skills": @@ -61,7 +61,7 @@ }, "gretchin": { - "id": 100, + "index": 100, "class" : "barbarian", "female": true, "skills": @@ -72,7 +72,7 @@ }, "krellion": { - "id": 101, + "index": 101, "class" : "barbarian", "female": false, "skills": @@ -87,7 +87,7 @@ }, "cragHack": { - "id": 102, + "index": 102, "class" : "barbarian", "female": false, "skills": @@ -101,7 +101,7 @@ }, "tyraxor": { - "id": 103, + "index": 103, "class" : "barbarian", "female": false, "skills": @@ -116,7 +116,7 @@ }, "gird": { - "id": 104, + "index": 104, "class" : "battlemage", "spellbook": [ "bloodlust" ], "female": true, @@ -132,7 +132,7 @@ }, "vey": { - "id": 105, + "index": 105, "class" : "battlemage", "female": false, "spellbook": [ "magicArrow" ], @@ -148,7 +148,7 @@ }, "dessa": { - "id": 106, + "index": 106, "class" : "battlemage", "female": true, "spellbook": [ "stoneSkin" ], @@ -164,7 +164,7 @@ }, "terek": { - "id": 107, + "index": 107, "class" : "battlemage", "female": false, "spellbook": [ "haste" ], @@ -180,7 +180,7 @@ }, "zubin": { - "id": 108, + "index": 108, "class" : "battlemage", "female": false, "spellbook": [ "precision" ], @@ -196,7 +196,7 @@ }, "gundula": { - "id": 109, + "index": 109, "class" : "battlemage", "spellbook": [ "slow" ], "female": true, @@ -212,7 +212,7 @@ }, "oris": { - "id": 110, + "index": 110, "class" : "battlemage", "female": true, "spellbook": [ "protectAir" ], @@ -228,7 +228,7 @@ }, "saurug": { - "id": 111, + "index": 111, "class" : "battlemage", "female": false, "spellbook": [ "bloodlust" ], diff --git a/config/heroes/tower.json b/config/heroes/tower.json index 7e1380765..b57de5b8a 100644 --- a/config/heroes/tower.json +++ b/config/heroes/tower.json @@ -1,7 +1,7 @@ { "piquedram": { - "id": 32, + "index": 32, "class" : "alchemist", "female": false, "spellbook": [ "shield" ], @@ -17,7 +17,7 @@ }, "thane": { - "id": 33, + "index": 33, "class" : "alchemist", "female": false, "spellbook": [ "magicArrow" ], @@ -32,7 +32,7 @@ }, "josephine": { - "id": 34, + "index": 34, "class" : "alchemist", "spellbook": [ "haste" ], "female": true, @@ -48,7 +48,7 @@ }, "neela": { - "id": 35, + "index": 35, "class" : "alchemist", "female": true, "spellbook": [ "shield" ], @@ -64,7 +64,7 @@ }, "torosar ": { - "id": 36, + "index": 36, "class" : "alchemist", "female": false, "spellbook": [ "magicArrow" ], @@ -80,7 +80,7 @@ }, "fafner": { - "id": 37, + "index": 37, "class" : "alchemist", "female": false, "spellbook": [ "haste" ], @@ -96,7 +96,7 @@ }, "rissa": { - "id": 38, + "index": 38, "class" : "alchemist", "female": true, "spellbook": [ "magicArrow" ], @@ -112,7 +112,7 @@ }, "iona": { - "id": 39, + "index": 39, "class" : "alchemist", "spellbook": [ "magicArrow" ], "female": true, @@ -128,7 +128,7 @@ }, "astral": { - "id": 40, + "index": 40, "class" : "wizard", "female": false, "spellbook": [ "hypnotize" ], @@ -143,7 +143,7 @@ }, "halon": { - "id": 41, + "index": 41, "class" : "wizard", "female": false, "spellbook": [ "stoneSkin" ], @@ -159,7 +159,7 @@ }, "serena": { - "id": 42, + "index": 42, "class" : "wizard", "female": true, "spellbook": [ "dispel" ], @@ -175,7 +175,7 @@ }, "daremyth": { - "id": 43, + "index": 43, "class" : "wizard", "female": true, "spellbook": [ "fortune" ], @@ -191,7 +191,7 @@ }, "theodorus": { - "id": 44, + "index": 44, "class" : "wizard", "spellbook": [ "shield" ], "female": false, @@ -207,7 +207,7 @@ }, "solmyr": { - "id": 45, + "index": 45, "class" : "wizard", "female": false, "spellbook": [ "chainLightning" ], @@ -223,7 +223,7 @@ }, "cyra": { - "id": 46, + "index": 46, "class" : "wizard", "female": true, "spellbook": [ "haste" ], @@ -239,7 +239,7 @@ }, "aine": { - "id": 47, + "index": 47, "class" : "wizard", "female": true, "spellbook": [ "curse" ], diff --git a/config/schemas/artifact.json b/config/schemas/artifact.json index 10b39d8ae..beefbd931 100644 --- a/config/schemas/artifact.json +++ b/config/schemas/artifact.json @@ -33,7 +33,7 @@ "enum" : [ "SPECIAL", "TREASURE", "MINOR", "MAJOR", "RELIC" ], "description": "Artifact class, treasure, minor, major or relic" }, - "id" : { + "index" : { "type" : "number", "description" : "Private field to break things, do not use." }, diff --git a/config/schemas/creature.json b/config/schemas/creature.json index 054ad33e6..e6ccb16e7 100644 --- a/config/schemas/creature.json +++ b/config/schemas/creature.json @@ -39,7 +39,7 @@ "type" : "string", "description" : "Text version of creature abilities. Used only with original creature window" }, - "id" : { + "index" : { "type" : "number", "description" : "Private field to break things, do not use." }, diff --git a/config/schemas/faction.json b/config/schemas/faction.json index 6ecbe0344..3f24e6a78 100644 --- a/config/schemas/faction.json +++ b/config/schemas/faction.json @@ -141,8 +141,8 @@ "description": "Path to .def file with building icons" }, "buildings": { - "type" : "array", - "items" : { + "type" : "object", + "additionalProperties" : { "$ref" : "vcmi:townBuilding" } }, @@ -242,8 +242,8 @@ "$ref" : "vcmi:townSiege" }, "structures": { - "type" : "array", - "items" : { + "type" : "object", + "additionalProperties" : { "$ref" : "vcmi:townStructure" } }, diff --git a/config/schemas/hero.json b/config/schemas/hero.json index 7c2bd3f62..194a9cbb8 100644 --- a/config/schemas/hero.json +++ b/config/schemas/hero.json @@ -32,7 +32,7 @@ } } }, - "id" : { + "index" : { "type" : "number", "description" : "Private field to break things, do not use." }, diff --git a/config/schemas/heroClass.json b/config/schemas/heroClass.json index 37265b028..12c62ae9d 100644 --- a/config/schemas/heroClass.json +++ b/config/schemas/heroClass.json @@ -50,7 +50,7 @@ } } }, - "id" : { + "index" : { "type" : "number", "description" : "Private field to break things, do not use." }, diff --git a/lib/BattleState.cpp b/lib/BattleState.cpp index ffbc730fd..f42624382 100644 --- a/lib/BattleState.cpp +++ b/lib/BattleState.cpp @@ -372,7 +372,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp { curB->town = town; curB->siege = town->fortLevel(); - curB->terrainType = VLC->townh->factions[town->town->typeID].nativeTerrain; + curB->terrainType = VLC->townh->factions[town->subID]->nativeTerrain; } else { diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index d7662c568..8a3d0a1e5 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -148,10 +148,11 @@ CArtHandler::~CArtHandler() { } -void CArtHandler::load(bool onlyTxt) +std::vector CArtHandler::loadLegacyData(size_t dataSize) { - if (onlyTxt) - return; // looks to be broken anyway... + artifacts.resize(dataSize); + std::vector h3Data; + h3Data.reserve(dataSize); #define ART_POS(x) ( #x) const std::vector artSlots = boost::assign::list_of ART_POS_LIST; @@ -166,11 +167,7 @@ void CArtHandler::load(bool onlyTxt) parser.endLine(); // header parser.endLine(); - std::map::iterator itr; - - std::vector h3Data; - - for (size_t i = 0; i < GameConstants::ARTIFACTS_QUANTITY; i++) + for (size_t i = 0; i < dataSize; i++) { JsonNode artData; @@ -194,42 +191,31 @@ void CArtHandler::load(bool onlyTxt) events.endLine(); h3Data.push_back(artData); } - - artifacts.resize(GameConstants::ARTIFACTS_QUANTITY); - - JsonNode config(ResourceID("config/artifacts.json")); - - BOOST_FOREACH(auto & node, config["artifacts"].Struct()) - { - int numeric = node.second["id"].Float(); - JsonNode & artData = h3Data[numeric]; - JsonUtils::merge(artData, node.second); - - //JsonUtils::validate(artData, "vcmi:artifact", node.first); - artifacts[numeric] = loadArtifact(artData); - artifacts[numeric]->id = ArtifactID(numeric); - - VLC->modh->identifiers.registerObject ("artifact." + node.first, numeric); - } - - for (size_t i=0; i < artifacts.size(); i++) - { - if (artifacts[i] == nullptr) - logGlobal->warnStream() << "Warning: artifact with id " << i << " is missing!"; - } + return h3Data; } -void CArtHandler::load(std::string objectID, const JsonNode & node) +void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode & data) { - CArtifact * art = loadArtifact(node); - art->id = ArtifactID(artifacts.size()); + auto object = loadFromJson(data); + object->id = ArtifactID(artifacts.size()); - artifacts.push_back(art); - logGlobal->traceStream() << "Added artifact: " << objectID; - VLC->modh->identifiers.registerObject ("artifact." + objectID, art->id); + artifacts.push_back(object); + + VLC->modh->identifiers.registerObject(scope, "artifact", name, object->id); } -CArtifact * CArtHandler::loadArtifact(const JsonNode & node) +void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) +{ + auto object = loadFromJson(data); + object->id = ArtifactID(index); + + assert(artifacts[index] == nullptr); // ensure that this id was not loaded before + artifacts[index] = object; + + VLC->modh->identifiers.registerObject(scope, "artifact", name, object->id); +} + +CArtifact * CArtHandler::loadFromJson(const JsonNode & node) { CArtifact * art; @@ -586,7 +572,7 @@ void CArtHandler::initAllowedArtifactsList(const std::vector &allowed) } } -std::vector CArtHandler::getDefaultAllowedArtifacts() const +std::vector CArtHandler::getDefaultAllowed() const { std::vector allowedArtifacts; allowedArtifacts.resize(127, true); diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index bd6db0337..a4ad31ba9 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -5,6 +5,7 @@ #include "../lib/ConstTransitivePtr.h" #include "JsonNode.h" #include "GameConstants.h" +#include "IHandlerBase.h" /* * CArtHandler.h, part of VCMI engine @@ -185,8 +186,10 @@ public: } }; -class DLL_LINKAGE CArtHandler //handles artifacts +class DLL_LINKAGE CArtHandler : public IHandlerBase //handles artifacts { + CArtifact * loadFromJson(const JsonNode & node); + void addSlot(CArtifact * art, const std::string & slotID); void loadSlots(CArtifact * art, const JsonNode & node); void loadClass(CArtifact * art, const JsonNode & node); @@ -205,12 +208,6 @@ public: std::set bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines. std::set growingArtifacts; - void load(bool onlyTxt = false); - /// load artifact from json structure - void load(std::string objectID, const JsonNode & node); - /// load one artifact from json config - CArtifact * loadArtifact(const JsonNode & node); - void addBonuses(CArtifact *art, const JsonNode &bonusList); void fillList(std::vector &listToBeFilled, CArtifact::EartClass artifactClass); //fills given empty list with allowed artifacts of gibven class. No side effects @@ -230,15 +227,16 @@ public: void makeItCreatureArt (ArtifactID aid, bool onlyCreature = true); void makeItCommanderArt (CArtifact * a, bool onlyCommander = true); void makeItCommanderArt (ArtifactID aid, bool onlyCommander = true); + CArtHandler(); ~CArtHandler(); - /** - * Gets a list of default allowed artifacts. - * - * @return a list of allowed artifacts, the index is the artifact id - */ - std::vector getDefaultAllowedArtifacts() const; + std::vector loadLegacyData(size_t dataSize) 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; + + std::vector getDefaultAllowed() const override; template void serialize(Handler &h, const int version) { diff --git a/lib/CBonusTypeHandler.cpp b/lib/CBonusTypeHandler.cpp index 66d2c7050..46986688b 100644 --- a/lib/CBonusTypeHandler.cpp +++ b/lib/CBonusTypeHandler.cpp @@ -119,6 +119,8 @@ CBonusTypeHandler::CBonusTypeHandler() BONUS_LIST; #undef BONUS_NAME + + load(); } CBonusTypeHandler::~CBonusTypeHandler() @@ -262,7 +264,6 @@ void CBonusTypeHandler::load() { const JsonNode gameConf(ResourceID("config/gameConfig.json")); const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo >())); - load(config); } diff --git a/lib/CBonusTypeHandler.h b/lib/CBonusTypeHandler.h index 3b1f0aa51..95cfe6fd7 100644 --- a/lib/CBonusTypeHandler.h +++ b/lib/CBonusTypeHandler.h @@ -11,6 +11,7 @@ #pragma once #include "IBonusTypeHandler.h" +#include "IHandlerBase.h" #include "HeroBonus.h" diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index d1c7e0302..29ebd5440 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -78,7 +78,7 @@ bool CCreature::isUndead() const */ bool CCreature::isGood () const { - return VLC->townh->factions[faction].alignment == EAlignment::GOOD; + return VLC->townh->factions[faction]->alignment == EAlignment::GOOD; } /** @@ -87,7 +87,7 @@ bool CCreature::isGood () const */ bool CCreature::isEvil () const { - return VLC->townh->factions[faction].alignment == EAlignment::EVIL; + return VLC->townh->factions[faction]->alignment == EAlignment::EVIL; } si32 CCreature::maxAmount(const std::vector &res) const //how many creatures can be bought @@ -129,7 +129,7 @@ std::string CCreature::nodeName() const bool CCreature::isItNativeTerrain(int terrain) const { - return VLC->townh->factions[faction].nativeTerrain == terrain; + return VLC->townh->factions[faction]->nativeTerrain == terrain; } static void AddAbility(CCreature *cre, const JsonVector &ability_vec) @@ -263,16 +263,18 @@ void CCreatureHandler::loadBonuses(JsonNode & creature, std::string bonuses) } } -void CCreatureHandler::load() +std::vector CCreatureHandler::loadLegacyData(size_t dataSize) { + creatures.resize(dataSize); std::vector h3Data; + h3Data.reserve(dataSize); CLegacyConfigParser parser("DATA/ZCRTRAIT.TXT"); parser.endLine(); // header parser.endLine(); - do + for (size_t i=0; i >())); + return h3Data; +} - creatures.resize(GameConstants::CREATURES_COUNT); +void CCreatureHandler::loadObject(std::string scope, std::string name, const JsonNode & data) +{ + auto object = loadFromJson(data); + object->idNumber = CreatureID(creatures.size()); - BOOST_FOREACH(auto & node, config.Struct()) + creatures.push_back(object); + + VLC->modh->identifiers.registerObject(scope, "creature", name, object->idNumber); + + BOOST_FOREACH(auto node, data["extraNames"].Vector()) { - int numeric = node.second["id"].Float(); - - JsonUtils::merge(h3Data[numeric], node.second); - - //JsonUtils::validate(h3Data[numeric], "vcmi:creature", node.first); - - creatures[numeric] = loadCreature(h3Data[numeric]); - creatures[numeric]->idNumber = CreatureID(numeric); - - VLC->modh->identifiers.registerObject ("creature." + node.first, numeric); - - // Alternative names, if any - BOOST_FOREACH(const JsonNode &name, h3Data[numeric]["extraNames"].Vector()) - VLC->modh->identifiers.registerObject ("creature." + name.String(), numeric); + VLC->modh->identifiers.registerObject(scope, "creature", node.String(), object->idNumber); } +} - for (size_t i=0; i < creatures.size(); i++) +void CCreatureHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) +{ + auto object = loadFromJson(data); + object->idNumber = CreatureID(index); + + assert(creatures[index] == nullptr); // ensure that this id was not loaded before + creatures[index] = object; + + VLC->modh->identifiers.registerObject(scope, "creature", name, object->idNumber); + BOOST_FOREACH(auto node, data["extraNames"].Vector()) { - if (creatures[i] == nullptr) - logGlobal->warnStream() << "Warning: creature with id " << i << " is missing!"; + VLC->modh->identifiers.registerObject(scope, "creature", node.String(), object->idNumber); } +} - loadCrExpBon(); +std::vector CCreatureHandler::getDefaultAllowed() const +{ + std::vector ret; + + BOOST_FOREACH(const CCreature * crea, creatures) + { + ret.push_back(crea ? !crea->special : false); + } + return ret; } void CCreatureHandler::loadCrExpBon() @@ -508,19 +521,7 @@ void CCreatureHandler::loadUnitAnimInfo(JsonNode & graphics, CLegacyConfigParser graphics.Struct().erase("missile"); } -void CCreatureHandler::load(std::string creatureID, const JsonNode & node) -{ - CCreature * creature = loadCreature(node); - creature->nameRef = creatureID; - creature->idNumber = CreatureID(creatures.size()); - - creatures.push_back(creature); - logGlobal->traceStream() << "Added creature: " << creatureID; - - VLC->modh->identifiers.registerObject ("creature." + creature->nameRef, creature->idNumber); -} - -CCreature * CCreatureHandler::loadCreature(const JsonNode & node) +CCreature * CCreatureHandler::loadFromJson(const JsonNode & node) { CCreature * cre = new CCreature(); diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index 9d53d0d8a..3141f93cd 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -6,6 +6,7 @@ #include "ResourceSet.h" #include "GameConstants.h" #include "JsonNode.h" +#include "IHandlerBase.h" /* * CCreatureHandler.h, part of VCMI engine @@ -132,15 +133,37 @@ public: CCreature(); }; -class DLL_LINKAGE CCreatureHandler +class DLL_LINKAGE CCreatureHandler : public IHandlerBase { private: CBonusSystemNode allCreatures; CBonusSystemNode creaturesOfLevel[GameConstants::CREATURES_PER_TOWN + 1];//index 0 is used for creatures of unknown tier or outside <1-7> range + /// load one creature from json config + CCreature * loadFromJson(const JsonNode & node); + void loadJsonAnimation(CCreature * creature, const JsonNode & graphics); void loadStackExperience(CCreature * creature, const JsonNode &input); void loadCreatureJson(CCreature * creature, const JsonNode & config); + + /// loading functions + + /// adding abilities from ZCRTRAIT.TXT + void loadBonuses(JsonNode & creature, std::string bonuses); + /// load all creatures from H3 files + void load(); + void loadCommanders(); + /// load creature from json structure + void load(std::string creatureID, const JsonNode & node); + /// read cranim.txt file from H3 + void loadAnimationInfo(std::vector & h3Data); + /// read one line from cranim.txt + void loadUnitAnimInfo(JsonNode & unit, CLegacyConfigParser &parser); + /// parse crexpbon.txt file from H3 + void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser); + /// help function for parsing CREXPBON.txt + int stringToNumber(std::string & s); + public: std::set doubledCreatures; //they get double week std::vector > creatures; //creature ID -> creature info. @@ -155,38 +178,26 @@ public: std::vector< std::vector > skillLevels; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE std::vector > > skillRequirements; // first - Bonus, second - which two skills are needed to use it - /// loading functions - - /// adding abilities from ZCRTRAIT.TXT - void loadBonuses(JsonNode & creature, std::string bonuses); - /// load all creatures from H3 files - void load(); - void loadCommanders(); - /// load creature from json structure - void load(std::string creatureID, const JsonNode & node); - /// load one creature from json config - CCreature * loadCreature(const JsonNode & node); - /// generates tier-specific bonus tree entries - void buildBonusTreeForTiers(); - /// read cranim.txt file from H3 - void loadAnimationInfo(std::vector & h3Data); - /// read one line from cranim.txt - void loadUnitAnimInfo(JsonNode & unit, CLegacyConfigParser &parser); - /// load all creatures from H3 files - void loadCrExpBon(); - /// parse crexpbon.txt file from H3 - void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser); - /// help function for parsing CREXPBON.txt - int stringToNumber(std::string & s); - - CCreatureHandler(); - ~CCreatureHandler(); - void deserializationFix(); CreatureID pickRandomMonster(const boost::function &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any void addBonusForTier(int tier, Bonus *b); //tier must be <1-7> void addBonusForAllCreatures(Bonus *b); + CCreatureHandler(); + ~CCreatureHandler(); + + /// load all creatures from H3 files + void loadCrExpBon(); + /// generates tier-specific bonus tree entries + void buildBonusTreeForTiers(); + + std::vector loadLegacyData(size_t dataSize) 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; + + std::vector getDefaultAllowed() const override; + template void serialize(Handler &h, const int version) { //TODO: should be optimized, not all these informations needs to be serialized (same for ccreature) diff --git a/lib/CDefObjInfoHandler.cpp b/lib/CDefObjInfoHandler.cpp index 202abf6ee..2835166b4 100644 --- a/lib/CDefObjInfoHandler.cpp +++ b/lib/CDefObjInfoHandler.cpp @@ -46,8 +46,10 @@ void CGDefInfo::fetchInfoFromMSK() } } -void CDefObjInfoHandler::load() +CDefObjInfoHandler::CDefObjInfoHandler() { + VLC->dobjinfo = this; + auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/ZOBJCTS.TXT")); std::istringstream inp(std::string((char*)textFile.first.get(), textFile.second)); @@ -132,8 +134,17 @@ void CDefObjInfoHandler::load() //coverageMap calculating nobj->fetchInfoFromMSK(); + auto dest = nobj->id.toDefObjInfo(); + if (dest.find(nobj->subid) != dest.end() && dest[nobj->subid] != nullptr) + { + // there is just too many of these. Note that this data is almost unused + // exceptions are: town(village-capitol) and creation of new objects (holes, creatures, heroes, etc) + //logGlobal->warnStream() << "Warning: overwriting def info for " << dest[nobj->subid]->name << " with " << nobj->name; + dest[nobj->subid].dellNull(); // do not leak + } nobj->id.toDefObjInfo()[nobj->subid] = nobj; + } for (int i = 0; i < 8 ; i++) diff --git a/lib/CDefObjInfoHandler.h b/lib/CDefObjInfoHandler.h index a802b8450..1ddfd5645 100644 --- a/lib/CDefObjInfoHandler.h +++ b/lib/CDefObjInfoHandler.h @@ -54,7 +54,7 @@ public: bmap > capitols; bmap > villages; - void load(); + CDefObjInfoHandler(); ~CDefObjInfoHandler(); template void serialize(Handler &h, const int version) diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 2d463dc2a..680b9b0aa 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -381,7 +381,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl if(player>=PlayerColor::PLAYER_LIMIT) { - logGlobal->errorStream() << "Cannot pick hero for " << town->typeID << ". Wrong owner!"; + logGlobal->errorStream() << "Cannot pick hero for " << town->faction->index << ". Wrong owner!"; return NULL; } @@ -392,7 +392,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl for(auto i=available.begin(); i!=available.end(); i++) { if(pavailable.find(i->first)->second & 1<second->type->heroClass->faction == town->typeID) + && i->second->type->heroClass->faction == town->faction->index) { pool.push_back(i->second); //get all available heroes } @@ -413,11 +413,11 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl for(auto i=available.begin(); i!=available.end(); i++) { - if ((!bannedClass && (pavailable.find(i->first)->second & (1<second->type->heroClass != bannedClass) + if (pavailable.find(i->first)->second & (1<second->type->heroClass != bannedClass) ) // and his class is not same as other hero { pool.push_back(i->second); - sum += i->second->type->heroClass->selectionProbability[town->typeID]; //total weight + sum += i->second->type->heroClass->selectionProbability[town->faction->index]; //total weight } } if(!pool.size() || sum == 0) @@ -429,7 +429,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl r = rand()%sum; for (ui32 i=0; itype->heroClass->selectionProbability[town->typeID]; + r -= pool[i]->type->heroClass->selectionProbability[town->faction->index]; if(r < 0) { ret = pool[i]; @@ -549,9 +549,11 @@ std::pair CGameState::pickObject (CGObjectInstance *obj) } if(f<0) { - auto iter = VLC->townh->towns.begin(); - std::advance(iter, ran()%VLC->townh->towns.size()); - f = iter->first; + do + { + f = ran()%VLC->townh->factions.size(); + } + while (VLC->townh->factions[f]->town == nullptr); // find playable faction } return std::make_pair(Obj::TOWN,f); } @@ -619,7 +621,7 @@ std::pair CGameState::pickObject (CGObjectInstance *obj) dwl->info = nullptr; std::pair result(Obj::NO_OBJ, -1); - CreatureID cid = VLC->townh->towns[faction].creatures[level][0]; + CreatureID cid = VLC->townh->factions[faction]->town->creatures[level][0]; //golem factory is not in list of cregens but can be placed as random object static const CreatureID factoryCreatures[] = {CreatureID::STONE_GOLEM, CreatureID::IRON_GOLEM, @@ -656,7 +658,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur) if(cur->ID==Obj::TOWN) //town - set def { CGTownInstance *t = dynamic_cast(cur); - t->town = &VLC->townh->towns[t->subID]; + t->town = VLC->townh->factions[t->subID]->town; if(t->hasCapitol()) t->defInfo = VLC->dobjinfo->capitols[t->subID]; else if(t->hasFort()) @@ -685,7 +687,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur) cur->ID = ran.first; cur->subID = ran.second; //FIXME: copy-pasted from above - t->town = &VLC->townh->towns[t->subID]; + t->town = VLC->townh->factions[t->subID]->town; if(t->hasCapitol()) t->defInfo = VLC->dobjinfo->capitols[t->subID]; else if(t->hasFort()) @@ -1394,8 +1396,8 @@ void CGameState::init(StartInfo * si) break; case PlayerSettings::RESOURCE: { - int res = VLC->townh->towns[scenarioOps->playerInfos[k->first].castle].primaryRes; - if(res == 127) + int res = VLC->townh->factions[scenarioOps->playerInfos[k->first].castle]->town->primaryRes; + if(res == Res::WOOD_AND_ORE) { k->second.resources[Res::WOOD] += 5 + ran()%6; k->second.resources[Res::ORE] += 5 + ran()%6; @@ -1443,7 +1445,7 @@ void CGameState::init(StartInfo * si) map->towns[g]->pos == pi.posOfMainTown + int3(2, 0, 0)) { map->towns[g]->builtBuildings.insert( - CBuildingHandler::campToERMU(chosenBonus->info1, map->towns[g]->town->typeID, map->towns[g]->builtBuildings)); + CBuildingHandler::campToERMU(chosenBonus->info1, map->towns[g]->subID, map->towns[g]->builtBuildings)); break; } } @@ -1459,7 +1461,7 @@ void CGameState::init(StartInfo * si) { CGTownInstance * vti =(map->towns[i]); if(!vti->town) - vti->town = &VLC->townh->towns[vti->subID]; + vti->town = VLC->townh->factions[vti->subID]->town; if (vti->name.length()==0) // if town hasn't name we draw it vti->name = vti->town->names[ran()%vti->town->names.size()]; diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index ff3bed933..5c34a869c 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -149,7 +149,7 @@ void CGeneralTextHandler::readToVector(std::string sourceName, std::vector > campaignRegionNames; void readToVector(std::string sourceName, std::vector & dest); - void load(); CGeneralTextHandler(); }; diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index d6c7052c7..be5738548 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -42,7 +42,7 @@ SecondarySkill CHeroClass::chooseSecSkill(const std::set & possi EAlignment::EAlignment CHeroClass::getAlignment() const { - return EAlignment::EAlignment(VLC->townh->factions[faction].alignment); + return EAlignment::EAlignment(VLC->townh->factions[faction]->alignment); } std::vector CObstacleInfo::getBlocked(BattleHex hex) const @@ -78,79 +78,9 @@ bool CObstacleInfo::isAppropriate(ETerrainType terrainType, int specialBattlefie return vstd::contains(allowedTerrains, terrainType); } -void CHeroClassHandler::load() +CHeroClass *CHeroClassHandler::loadFromJson(const JsonNode & node) { - CLegacyConfigParser parser("DATA/HCTRAITS.TXT"); - - parser.endLine(); // header - parser.endLine(); - - std::vector h3Data; - - do - { - JsonNode entry; - - entry["name"].String() = parser.readString(); - - parser.readNumber(); // unused aggression - - for (size_t i=0; i < GameConstants::PRIMARY_SKILLS; i++) - entry["primarySkills"][PrimarySkill::names[i]].Float() = parser.readNumber(); - - for (size_t i=0; i < GameConstants::PRIMARY_SKILLS; i++) - entry["lowLevelChance"][PrimarySkill::names[i]].Float() = parser.readNumber(); - - for (size_t i=0; i < GameConstants::PRIMARY_SKILLS; i++) - entry["highLevelChance"][PrimarySkill::names[i]].Float() = parser.readNumber(); - - for (size_t i=0; i < GameConstants::SKILL_QUANTITY; i++) - entry["secondarySkills"][NSecondarySkill::names[i]].Float() = parser.readNumber(); - - for(size_t i = 0; i < GameConstants::F_NUMBER; i++) - entry["tavern"][ETownType::names[i]].Float() = parser.readNumber(); - - h3Data.push_back(entry); - } - while (parser.endLine() && !parser.isNextEntryEmpty()); - - JsonNode classConf = JsonNode(ResourceID("config/heroClasses.json")); - heroClasses.resize(GameConstants::F_NUMBER * 2); - - BOOST_FOREACH(auto & node, classConf.Struct()) - { - int numeric = node.second["id"].Float(); - JsonNode & classData = h3Data[numeric]; - JsonUtils::merge(classData, node.second); - - //JsonUtils::validate(classData, "vcmi:heroClass", node.first); - heroClasses[numeric] = loadClass(classData); - heroClasses[numeric]->id = numeric; - - VLC->modh->identifiers.registerObject ("heroClass." + node.first, numeric); - } - - for (size_t i=0; i < heroClasses.size(); i++) - { - if (heroClasses[i] == nullptr) - logGlobal->warnStream() << "Warning: class with id " << i << " is missing!"; - } -} - -void CHeroClassHandler::load(std::string objectID, const JsonNode & input) -{ - CHeroClass * heroClass = loadClass(input); - heroClass->identifier = objectID; - heroClass->id = heroClasses.size(); - - heroClasses.push_back(heroClass); - logGlobal->traceStream() << "Added hero class: " << objectID; - VLC->modh->identifiers.registerObject("heroClass." + heroClass->identifier, heroClass->id); -} - -CHeroClass *CHeroClassHandler::loadClass(const JsonNode & node) -{ - CHeroClass * heroClass = new CHeroClass; + CHeroClass * heroClass = new CHeroClass(); heroClass->imageBattleFemale = node["animation"]["battle"]["female"].String(); heroClass->imageBattleMale = node["animation"]["battle"]["male"].String(); @@ -191,6 +121,72 @@ CHeroClass *CHeroClassHandler::loadClass(const JsonNode & node) return heroClass; } +std::vector CHeroClassHandler::loadLegacyData(size_t dataSize) +{ + heroClasses.resize(GameConstants::F_NUMBER * 2); + std::vector h3Data; + h3Data.reserve(dataSize); + + CLegacyConfigParser parser("DATA/HCTRAITS.TXT"); + + parser.endLine(); // header + parser.endLine(); + + for (size_t i=0; iid = heroClasses.size(); + + heroClasses.push_back(object); + + VLC->modh->identifiers.registerObject(scope, "heroClass", name, object->id); +} + +void CHeroClassHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) +{ + auto object = loadFromJson(data); + object->id = index; + + assert(heroClasses[index] == nullptr); // ensure that this id was not loaded before + heroClasses[index] = object; + + VLC->modh->identifiers.registerObject(scope, "heroClass", name, object->id); +} + +std::vector CHeroClassHandler::getDefaultAllowed() const +{ + return std::vector(heroClasses.size(), true); +} + CHeroClassHandler::~CHeroClassHandler() { BOOST_FOREACH(auto heroClass, heroClasses) @@ -207,19 +203,19 @@ CHeroHandler::~CHeroHandler() CHeroHandler::CHeroHandler() { + VLC->heroh = this; + + for (int i = 0; i < GameConstants::SKILL_QUANTITY; ++i) + { + VLC->modh->identifiers.registerObject("core", "skill", NSecondarySkill::names[i], i); + } + loadObstacles(); + loadTerrains(); + loadBallistics(); + loadExperience(); } -void CHeroHandler::load(std::string objectID, const JsonNode & input) -{ - CHero * hero = loadHero(input); - hero->ID = heroes.size(); - - heroes.push_back(hero); - logGlobal->traceStream() << "Added hero: " << objectID; - VLC->modh->identifiers.registerObject("hero." + objectID, hero->ID); -} - -CHero * CHeroHandler::loadHero(const JsonNode & node) +CHero * CHeroHandler::loadFromJson(const JsonNode & node) { CHero * hero = new CHero; @@ -332,22 +328,6 @@ void CHeroHandler::loadHeroSpecialty(CHero * hero, const JsonNode & node) } } -void CHeroHandler::load() -{ - VLC->heroh = this; - - for (int i = 0; i < GameConstants::SKILL_QUANTITY; ++i) - { - VLC->modh->identifiers.registerObject("skill." + NSecondarySkill::names[i], i); - } - classes.load(); - loadHeroes(); - loadObstacles(); - loadTerrains(); - loadBallistics(); - loadExperience(); -} - void CHeroHandler::loadExperience() { expPerLevel.push_back(0); @@ -406,8 +386,39 @@ static std::string genRefName(std::string input) return input; } -void CHeroHandler::loadHeroes() +void CHeroHandler::loadBallistics() { + CLegacyConfigParser ballParser("DATA/BALLIST.TXT"); + + ballParser.endLine(); //header + ballParser.endLine(); + + do + { + ballParser.readString(); + ballParser.readString(); + + CHeroHandler::SBallisticsLevelInfo bli; + bli.keep = ballParser.readNumber(); + bli.tower = ballParser.readNumber(); + bli.gate = ballParser.readNumber(); + bli.wall = ballParser.readNumber(); + bli.shots = ballParser.readNumber(); + bli.noDmg = ballParser.readNumber(); + bli.oneDmg = ballParser.readNumber(); + bli.twoDmg = ballParser.readNumber(); + bli.sum = ballParser.readNumber(); + ballistics.push_back(bli); + } + while (ballParser.endLine()); +} + +std::vector CHeroHandler::loadLegacyData(size_t dataSize) +{ + heroes.resize(dataSize); + std::vector h3Data; + h3Data.reserve(dataSize); + CLegacyConfigParser specParser("DATA/HEROSPEC.TXT"); CLegacyConfigParser bioParser("DATA/HEROBIOS.TXT"); CLegacyConfigParser parser("DATA/HOTRAITS.TXT"); @@ -418,8 +429,6 @@ void CHeroHandler::loadHeroes() specParser.endLine(); //ignore header specParser.endLine(); - std::vector h3Data; - for (int i=0; i >())); - - BOOST_FOREACH(auto &entry, config.Struct()) - { - ui32 identifier = entry.second["id"].Float(); - JsonUtils::merge(h3Data[identifier], entry.second); - - //JsonUtils::validate(h3Data[identifier], "vcmi:hero", entry.first); - CHero * hero = loadHero(h3Data[identifier]); - hero->ID = identifier; - heroes[identifier] = hero; - - VLC->modh->identifiers.registerObject("hero." + entry.first, identifier); - } - - for (size_t i=0; i < heroes.size(); i++) - { - if (heroes[i] == nullptr) - logGlobal->warnStream() << "Warning: hero with id " << i << " is missing!"; - } + return h3Data; } -void CHeroHandler::loadBallistics() +void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNode & data) { - CLegacyConfigParser ballParser("DATA/BALLIST.TXT"); + auto object = loadFromJson(data); + object->ID = heroes.size(); - ballParser.endLine(); //header - ballParser.endLine(); + heroes.push_back(object); - do - { - ballParser.readString(); - ballParser.readString(); + VLC->modh->identifiers.registerObject(scope, "hero", name, object->ID); +} - CHeroHandler::SBallisticsLevelInfo bli; - bli.keep = ballParser.readNumber(); - bli.tower = ballParser.readNumber(); - bli.gate = ballParser.readNumber(); - bli.wall = ballParser.readNumber(); - bli.shots = ballParser.readNumber(); - bli.noDmg = ballParser.readNumber(); - bli.oneDmg = ballParser.readNumber(); - bli.twoDmg = ballParser.readNumber(); - bli.sum = ballParser.readNumber(); - ballistics.push_back(bli); - } - while (ballParser.endLine()); +void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) +{ + auto object = loadFromJson(data); + object->ID = index; + + assert(heroes[index] == nullptr); // ensure that this id was not loaded before + heroes[index] = object; + + VLC->modh->identifiers.registerObject(scope, "hero", name, object->ID); } ui32 CHeroHandler::level (ui64 experience) const @@ -531,7 +510,7 @@ void CHeroHandler::loadTerrains() terrCosts.push_back(config[name]["moveCost"].Float()); } -std::vector CHeroHandler::getDefaultAllowedHeroes() const +std::vector CHeroHandler::getDefaultAllowed() const { // Look Data/HOTRAITS.txt for reference std::vector allowedHeroes; diff --git a/lib/CHeroHandler.h b/lib/CHeroHandler.h index d6f05a020..863554758 100644 --- a/lib/CHeroHandler.h +++ b/lib/CHeroHandler.h @@ -3,6 +3,7 @@ #include "../lib/ConstTransitivePtr.h" #include "GameConstants.h" #include "HeroBonus.h" +#include "IHandlerBase.h" /* * CHeroHandler.h, part of VCMI engine @@ -149,19 +150,18 @@ struct DLL_LINKAGE CObstacleInfo } }; -class DLL_LINKAGE CHeroClassHandler +class DLL_LINKAGE CHeroClassHandler : public IHandlerBase { + CHeroClass *loadFromJson(const JsonNode & node); public: std::vector< ConstTransitivePtr > heroClasses; - /// load from H3 config - void load(); + std::vector loadLegacyData(size_t dataSize) override; - /// load any number of classes from json - void load(std::string objectID, const JsonNode & classes); + 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; - /// load one class from json - CHeroClass * loadClass(const JsonNode & node); + std::vector getDefaultAllowed() const; ~CHeroClassHandler(); @@ -171,7 +171,7 @@ public: } }; -class DLL_LINKAGE CHeroHandler +class DLL_LINKAGE CHeroHandler : public IHandlerBase { /// expPerLEvel[i] is amount of exp needed to reach level i; /// consists of 201 values. Any higher levels require experience larger that ui64 can hold @@ -181,6 +181,15 @@ class DLL_LINKAGE CHeroHandler void loadHeroArmy(CHero * hero, const JsonNode & node); void loadHeroSkills(CHero * hero, const JsonNode & node); void loadHeroSpecialty(CHero * hero, const JsonNode & node); + + void loadExperience(); + void loadBallistics(); + void loadTerrains(); + void loadObstacles(); + + /// Load single hero from json + CHero * loadFromJson(const JsonNode & node); + public: CHeroClassHandler classes; @@ -208,34 +217,15 @@ public: ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount ui64 reqExp(ui32 level) const; //calculates experience required for given level - /// Load multiple heroes from json - void load(std::string objectID, const JsonNode & heroes); + std::vector loadLegacyData(size_t dataSize) override; - /// Load single hero from json - CHero * loadHero(const JsonNode & node); - - /// Load everything (calls functions below + classes.load()) - void load(); - - void loadHeroes(); - void loadExperience(); - void loadBallistics(); - void loadTerrains(); - void loadObstacles(); + 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; CHeroHandler(); //c-tor ~CHeroHandler(); //d-tor - /** - * Gets a list of default allowed heroes. - * - * TODO Proposal for hero modding: Replace hero id with a unique machine readable hero name and - * create a JSON config file or merge it with a existing config file which describes which heroes can be used for - * random map generation / map editor(default map settings). (Gelu, ... should be excluded) - * - * @return a list of allowed heroes, the index is the hero id and the value either 0 for not allowed or 1 for allowed - */ - std::vector getDefaultAllowedHeroes() const; + std::vector getDefaultAllowed() const; /** * Gets a list of default allowed abilities. OH3 abilities/skills are all allowed by default. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 6598faa39..da7bc4911 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -70,6 +70,7 @@ set(lib_HEADERS GameConstants.h StringConstants.h IGameEventsReceiver.h + IHandlerBase.h int3.h Interprocess.h NetPacks.h diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index aca26fcfb..d8d5e3627 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -11,6 +11,8 @@ #include "CHeroHandler.h" #include "CObjectHandler.h" #include "StringConstants.h" +#include "CStopWatch.h" +#include "IHandlerBase.h" /* * CModHandler.cpp, part of VCMI engine @@ -46,7 +48,8 @@ void CIdentifierStorage::requestIdentifier(std::string name, const boost::functi { checkIdentifier(name); - auto iter = registeredObjects.find(name); + // old version with immediate callback posibility. Can't be used for some cases +/* auto iter = registeredObjects.find(name); if (iter != registeredObjects.end()) callback(iter->second); //already registered - trigger callback immediately @@ -56,19 +59,24 @@ void CIdentifierStorage::requestIdentifier(std::string name, const boost::functi logGlobal->warnStream() << "incorrect primSkill name requested"; missingObjects[name].push_back(callback); // queue callback - } + }*/ + + missingObjects[name].push_back(callback); // queue callback } -void CIdentifierStorage::registerObject(std::string name, si32 identifier) +void CIdentifierStorage::registerObject(std::string scope, std::string type, std::string name, si32 identifier) { - checkIdentifier(name); + //TODO: use scope + std::string fullID = type + '.' + name; + checkIdentifier(fullID); // do not allow to register same object twice - assert(registeredObjects.find(name) == registeredObjects.end()); + assert(registeredObjects.find(fullID) == registeredObjects.end()); - registeredObjects[name] = identifier; + registeredObjects[fullID] = identifier; - auto iter = missingObjects.find(name); + // old version with immediate callback posibility. Can't be used for some cases + /*auto iter = missingObjects.find(fullID); if (iter != missingObjects.end()) { //call all awaiting callbacks @@ -77,11 +85,26 @@ void CIdentifierStorage::registerObject(std::string name, si32 identifier) function(identifier); } missingObjects.erase(iter); - } + }*/ } -void CIdentifierStorage::finalize() const +void CIdentifierStorage::finalize() { + for (auto it = missingObjects.begin(); it!= missingObjects.end();) + { + auto object = registeredObjects.find(it->first); + if (object != registeredObjects.end()) + { + BOOST_FOREACH(auto function, it->second) + { + function(object->second); + } + it = missingObjects.erase(it); + } + else + it++; + } + // print list of missing objects and crash // in future should try to do some cleanup (like returning all id's as 0) if (!missingObjects.empty()) @@ -99,15 +122,115 @@ void CIdentifierStorage::finalize() const assert(missingObjects.empty()); } +CContentHandler::ContentTypeHandler::ContentTypeHandler(IHandlerBase * handler, size_t size, std::string objectName): + handler(handler), + objectName(objectName), + originalData(handler->loadLegacyData(size)) +{ +} + +void CContentHandler::ContentTypeHandler::preloadModData(std::string modName, std::vector fileList) +{ + JsonNode data = JsonUtils::assembleFromFiles(fileList); + + ModInfo & modInfo = modData[modName]; + + BOOST_FOREACH(auto entry, data.Struct()) + { + size_t colon = entry.first.find(':'); + + if (colon == std::string::npos) + { + // normal object, local to this mod + modInfo.modData[entry.first].swap(entry.second); + } + else + { + std::string remoteName = entry.first.substr(0, colon); + std::string objectName = entry.first.substr(colon + 1); + + // patching this mod? Send warning and continue - this situation can be handled normally + if (remoteName == modName) + logGlobal->warnStream() << "Redundant namespace definition for " << objectName; + + JsonNode & remoteConf = modData[remoteName].patches[objectName]; + + JsonUtils::merge(remoteConf, entry.second); + } + } +} + +void CContentHandler::ContentTypeHandler::loadMod(std::string modName) +{ + ModInfo & modInfo = modData[modName]; + + // apply patches + if (!modInfo.patches.isNull()) + JsonUtils::merge(modInfo.modData, modInfo.patches); + + BOOST_FOREACH(auto entry, modInfo.modData.Struct()) + { + const std::string & name = entry.first; + JsonNode & data = entry.second; + + if (vstd::contains(data.Struct(), "index") && !data["index"].isNull()) + { + // try to add H3 object data + size_t index = data["index"].Float(); + + if (originalData.size() > index) + { + JsonUtils::merge(originalData[index], data); + JsonUtils::validate(originalData[index], "vcmi:" + objectName, name); + handler->loadObject(modName, name, originalData[index], index); + + originalData[index].clear(); // do not use same data twice (same ID) + + continue; + } + } + // normal new object + JsonUtils::validate(data, "vcmi:" + objectName, name); + handler->loadObject(modName, name, data); + } +} + +CContentHandler::CContentHandler() +{ + handlers.insert(std::make_pair("heroClasses", ContentTypeHandler(&VLC->heroh->classes, GameConstants::F_NUMBER * 2, "heroClass"))); + handlers.insert(std::make_pair("artifacts", ContentTypeHandler(VLC->arth, GameConstants::ARTIFACTS_QUANTITY, "artifact"))); + handlers.insert(std::make_pair("creatures", ContentTypeHandler(VLC->creh, GameConstants::CREATURES_COUNT, "creature"))); + handlers.insert(std::make_pair("factions", ContentTypeHandler(VLC->townh, GameConstants::F_NUMBER, "faction"))); + handlers.insert(std::make_pair("heroes", ContentTypeHandler(VLC->heroh, GameConstants::HEROES_QUANTITY, "hero"))); + + //TODO: spells, bonuses, something else? +} + +void CContentHandler::preloadModData(std::string modName, JsonNode modConfig) +{ + BOOST_FOREACH(auto & handler, handlers) + { + handler.second.preloadModData(modName, modConfig[handler.first].convertTo >()); + } +} + +void CContentHandler::loadMod(std::string modName) +{ + BOOST_FOREACH(auto & handler, handlers) + { + handler.second.loadMod(modName); + } +} + CModHandler::CModHandler() { for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i) { - identifiers.registerObject("resource." + GameConstants::RESOURCE_NAMES[i], i); + identifiers.registerObject("core", "resource", GameConstants::RESOURCE_NAMES[i], i); } for(int i=0; i & input) const std::vector CModHandler::resolveDependencies(std::vector input) const { - // Algorithm may not be the fastest one but VCMI does not needs any speed here - // Unless user have dozens of mods with complex dependencies this cide should be fine + // Topological sort algorithm + // May not be the fastest one but VCMI does not needs any speed here + // Unless user have dozens of mods with complex dependencies this code should be fine + + // first - sort input to have input strictly based on name (and not on hashmap or anything else) + boost::range::sort(input); std::vector output; output.reserve(input.size()); @@ -211,17 +338,20 @@ std::vector CModHandler::resolveDependencies(std::vector input while (!input.empty()) { + std::set toResolve; // list of mods resolved on this iteration + for (auto it = input.begin(); it != input.end();) { if (isResolved(allMods.at(*it))) { - resolvedMods.insert(*it); + toResolve.insert(*it); output.push_back(*it); it = input.erase(it); continue; } it++; } + resolvedMods.insert(toResolve.begin(), toResolve.end()); } return output; @@ -238,8 +368,6 @@ void CModHandler::initialize(std::vector availableMods) else modConfig = JsonNode(ResourceID(confName)); - CResourceHandler::get()->createResource("config/modSettings.json"); - const JsonNode & modList = modConfig["activeMods"]; JsonNode resultingList; @@ -312,28 +440,48 @@ void CModHandler::handleData(Handler handler, const JsonNode & source, std::stri } } -void CModHandler::loadActiveMods() +void CModHandler::loadGameContent() { + CStopWatch timer, totalTime; + + CContentHandler content; + logGlobal->infoStream() << "\tInitializing content hander: " << timer.getDiff() << " ms"; + + // first - load virtual "core" mod tht contains all data + // TODO? move all data into real mods? RoE, AB, SoD, WoG + content.preloadModData("core", JsonNode(ResourceID("config/gameConfig.json"))); + logGlobal->infoStream() << "\tParsing original game data: " << timer.getDiff() << " ms"; + BOOST_FOREACH(const TModID & modName, activeMods) { - logGlobal->infoStream() << "\t\tLoading mod " << allMods[modName].name; + logGlobal->infoStream() << "\t\t" << allMods[modName].name; std::string modFileName = "mods/" + modName + "/mod.json"; const JsonNode config = JsonNode(ResourceID(modFileName)); JsonUtils::validate(config, "vcmi:mod", modName); - handleData(VLC->townh, config, "factions", "vcmi:faction"); - handleData(VLC->creh, config, "creatures", "vcmi:creature"); - handleData(VLC->arth, config, "artifacts", "vcmi:artifact"); - //todo: spells - - handleData(&VLC->heroh->classes, config,"heroClasses", "vcmi:heroClass"); - handleData(VLC->heroh, config, "heroes", "vcmi:hero"); + content.preloadModData(modName, config); } + logGlobal->infoStream() << "\tParsing mod data: " << timer.getDiff() << " ms"; + content.loadMod("core"); + logGlobal->infoStream() << "\tLoading original game data: " << timer.getDiff() << " ms"; + + BOOST_FOREACH(const TModID & modName, activeMods) + { + content.loadMod(modName); + logGlobal->infoStream() << "\t\t" << allMods[modName].name; + } + logGlobal->infoStream() << "\tLoading mod data: " << timer.getDiff() << "ms"; + + logGlobal->infoStream() << "\tDone loading data"; + + VLC->creh->loadCrExpBon(); VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded identifiers.finalize(); + + logGlobal->infoStream() << "\tAll game content loaded in " << totalTime.getDiff() << " ms"; } void CModHandler::reload() @@ -380,37 +528,42 @@ void CModHandler::reload() const CGDefInfo * baseInfo = VLC->dobjinfo->gobjs[Obj::TOWN].begin()->second; auto & townInfos = VLC->dobjinfo->gobjs[Obj::TOWN]; - BOOST_FOREACH(auto & town, VLC->townh->towns) + BOOST_FOREACH(auto & faction, VLC->townh->factions) { - auto & cientInfo = town.second.clientInfo; - - if (!vstd::contains(VLC->dobjinfo->gobjs[Obj::TOWN], town.first)) // no obj info for this type + TFaction index = faction->index; + CTown * town = faction->town; + if (town) { - CGDefInfo * info = new CGDefInfo(*baseInfo); - info->subid = town.first; + auto & cientInfo = town->clientInfo; - townInfos[town.first] = info; - } - townInfos[town.first]->name = cientInfo.advMapCastle; - - VLC->dobjinfo->villages[town.first] = new CGDefInfo(*townInfos[town.first]); - VLC->dobjinfo->villages[town.first]->name = cientInfo.advMapVillage; - - VLC->dobjinfo->capitols[town.first] = new CGDefInfo(*townInfos[town.first]); - VLC->dobjinfo->capitols[town.first]->name = cientInfo.advMapCapitol; - - for (int i = 0; i < town.second.dwellings.size(); ++i) - { - const CGDefInfo * baseInfo = VLC->dobjinfo->gobjs[Obj::CREATURE_GENERATOR1][i]; //get same blockmap as first dwelling of tier i - - BOOST_FOREACH (auto cre, town.second.creatures[i]) //both unupgraded and upgraded get same dwelling + if (!vstd::contains(VLC->dobjinfo->gobjs[Obj::TOWN], index)) // no obj info for this type { CGDefInfo * info = new CGDefInfo(*baseInfo); - info->subid = cre; - info->name = town.second.dwellings[i]; - VLC->dobjinfo->gobjs[Obj::CREATURE_GENERATOR1][cre] = info; + info->subid = index; - VLC->objh->cregens[cre] = cre; //map of dwelling -> creature id + townInfos[index] = info; + } + townInfos[index]->name = cientInfo.advMapCastle; + + VLC->dobjinfo->villages[index] = new CGDefInfo(*townInfos[index]); + VLC->dobjinfo->villages[index]->name = cientInfo.advMapVillage; + + VLC->dobjinfo->capitols[index] = new CGDefInfo(*townInfos[index]); + VLC->dobjinfo->capitols[index]->name = cientInfo.advMapCapitol; + + for (int i = 0; i < town->dwellings.size(); ++i) + { + const CGDefInfo * baseInfo = VLC->dobjinfo->gobjs[Obj::CREATURE_GENERATOR1][i]; //get same blockmap as first dwelling of tier i + + BOOST_FOREACH (auto cre, town->creatures[i]) //both unupgraded and upgraded get same dwelling + { + CGDefInfo * info = new CGDefInfo(*baseInfo); + info->subid = cre; + info->name = town->dwellings[i]; + VLC->dobjinfo->gobjs[Obj::CREATURE_GENERATOR1][cre] = info; + + VLC->objh->cregens[cre] = cre; //map of dwelling -> creature id + } } } } diff --git a/lib/CModHandler.h b/lib/CModHandler.h index e2dd6896d..a640dea1e 100644 --- a/lib/CModHandler.h +++ b/lib/CModHandler.h @@ -3,6 +3,7 @@ #include "filesystem/CResourceLoader.h" #include "VCMI_Lib.h" +#include "JsonNode.h" /* * CModHandler.h, part of VCMI engine @@ -18,6 +19,7 @@ class CModHandler; class CModIndentifier; class CModInfo; class JsonNode; +class IHandlerBase; /// class that stores all object identifiers strings and maps them to numeric ID's /// if possible, objects ID's should be in format ., camelCase e.g. "creature.grandElf" @@ -26,17 +28,60 @@ class CIdentifierStorage std::map registeredObjects; std::map > > missingObjects; - //Check if identifier can be valid (camelCase, point as separator) + /// Check if identifier can be valid (camelCase, point as separator) void checkIdentifier(std::string & ID); public: /// request identifier for specific object name. If ID is not yet resolved callback will be queued /// and will be called later void requestIdentifier(std::string name, const boost::function & callback); /// registers new object, calls all associated callbacks - void registerObject(std::string name, si32 identifier); + void registerObject(std::string scope, std::string type, std::string name, si32 identifier); /// called at the very end of loading to check for any missing ID's - void finalize() const; + void finalize(); +}; + +/// class used to load all game data into handlers. Used only during loading +class CContentHandler +{ + /// internal type to handle loading of one data type (e.g. artifacts, creatures) + class ContentTypeHandler + { + struct ModInfo + { + /// mod data from this mod and for this mod + JsonNode modData; + /// mod data for this mod from other mods (patches) + JsonNode patches; + }; + + /// handler to which all data will be loaded + IHandlerBase * handler; + + std::string objectName; + + /// contains all loaded H3 data + std::vector originalData; + std::map modData; + + public: + ContentTypeHandler(IHandlerBase * handler, size_t size, std::string objectName); + + /// local version of methods in ContentHandler + void preloadModData(std::string modName, std::vector fileList); + void loadMod(std::string modName); + }; + + std::map handlers; +public: + /// fully initialize object. Will cause reading of H3 config files + CContentHandler(); + + /// preloads all data from fileList as data from modName + void preloadModData(std::string modName, JsonNode modConfig); + + /// actually loads data in mod + void loadMod(std::string modName); }; typedef std::string TModID; @@ -99,7 +144,7 @@ public: std::vector getActiveMods(); /// load content from all available mods - void loadActiveMods(); + void loadGameContent(); /// actions that should be triggered on map restart /// TODO: merge into appropriate handlers? diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 9f306573b..bd656e2ef 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -213,7 +213,7 @@ static void readBankLevel(const JsonNode &level, BankConfig &bc) bc.easiest = level["easiest"].Float(); } -void CObjectHandler::load() +CObjectHandler::CObjectHandler() { logGlobal->traceStream() << "\t\tReading cregens "; @@ -614,7 +614,7 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainTile &fro bool nativeArmy = true; BOOST_FOREACH(auto stack, stacks) { - int nativeTerrain = VLC->townh->factions[stack.second->type->faction].nativeTerrain; + int nativeTerrain = VLC->townh->factions[stack.second->type->faction]->nativeTerrain; if (nativeTerrain != -1 && nativeTerrain != from.terType) { @@ -813,7 +813,7 @@ void CGHeroInstance::initHero() if (VLC->modh->modules.COMMANDERS && !commander) { - commander = new CCommanderInstance (VLC->townh->factions[type->heroClass->faction].commander); + commander = new CCommanderInstance (VLC->townh->factions[type->heroClass->faction]->commander); commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders commander->giveStackExp (exp); //after our exp is set } @@ -1672,9 +1672,9 @@ void CGDwelling::initObj() creatures[0].second.push_back(crid); if (subID >= VLC->generaltexth->creGens.size()) //very messy workaround { - TFaction faction = VLC->creh->creatures[subID]->faction; - assert (VLC->townh->towns[faction].dwellingNames.size()); - hoverName = VLC->townh->towns[faction].dwellingNames[VLC->creh->creatures[subID]->level - 1]; + auto & dwellingNames = VLC->townh->factions[crs->faction]->town->dwellingNames; + assert (!dwellingNames.empty()); + hoverName = dwellingNames[VLC->creh->creatures[subID]->level - 1]; } else hoverName = VLC->generaltexth->creGens[subID]; @@ -2201,7 +2201,7 @@ void CGTownInstance::initObj() ///initialize town structures { blockVisit = true; - hoverName = name + ", " + VLC->townh->factions[town->typeID].name; + hoverName = name + ", " + town->faction->name; if (subID == ETownType::DUNGEON) creatures.resize(GameConstants::CREATURES_PER_TOWN+1);//extra dwelling for Dungeon @@ -2355,7 +2355,7 @@ void CGTownInstance::removeCapitols (PlayerColor owner) const int CGTownInstance::getBoatType() const { - switch (VLC->townh->factions[town->typeID].alignment) + switch (town->faction->alignment) { case EAlignment::EVIL : return 0; case EAlignment::GOOD : return 1; @@ -2431,7 +2431,7 @@ std::vector CGTownInstance::availableItemsIds(EMarketMode::EMarketMode mode std::string CGTownInstance::nodeName() const { - return "Town (" + (town ? VLC->townh->factions[town->typeID].name : "unknown") + ") of " + name; + return "Town (" + (town ? town->faction->name : "unknown") + ") of " + name; } void CGTownInstance::deserializationFix() @@ -2448,6 +2448,8 @@ void CGTownInstance::deserializationFix() void CGTownInstance::recreateBuildingsBonuses() { + static TPropagatorPtr playerProp(new CPropagatorNodeType(PLAYER)); + BonusList bl; getExportedBonusList().getBonuses(bl, Selector::sourceType(Bonus::TOWN_STRUCTURE)); BOOST_FOREACH(Bonus *b, bl) @@ -2459,13 +2461,13 @@ void CGTownInstance::recreateBuildingsBonuses() if(subID == ETownType::CASTLE) //castle { - addBonusIfBuilt(BuildingID::LIGHTHOUSE, Bonus::SEA_MOVEMENT, +500, make_shared(PLAYER)); - addBonusIfBuilt(BuildingID::GRAIL, Bonus::MORALE, +2, make_shared(PLAYER)); //colossus + addBonusIfBuilt(BuildingID::LIGHTHOUSE, Bonus::SEA_MOVEMENT, +500, playerProp); + addBonusIfBuilt(BuildingID::GRAIL, Bonus::MORALE, +2, playerProp); //colossus } else if(subID == ETownType::RAMPART) //rampart { addBonusIfBuilt(BuildingID::FOUNTAIN_OF_FORTUNE, Bonus::LUCK, +2); //fountain of fortune - addBonusIfBuilt(BuildingID::GRAIL, Bonus::LUCK, +2, make_shared(PLAYER)); //guardian spirit + addBonusIfBuilt(BuildingID::GRAIL, Bonus::LUCK, +2, playerProp); //guardian spirit } else if(subID == ETownType::TOWER) //tower { @@ -2478,8 +2480,8 @@ void CGTownInstance::recreateBuildingsBonuses() else if(subID == ETownType::NECROPOLIS) //necropolis { addBonusIfBuilt(BuildingID::COVER_OF_DARKNESS, Bonus::DARKNESS, +20); - addBonusIfBuilt(BuildingID::NECROMANCY_AMPLIFIER, Bonus::SECONDARY_SKILL_PREMY, +10, make_shared(PLAYER), SecondarySkill::NECROMANCY); //necromancy amplifier - addBonusIfBuilt(BuildingID::GRAIL, Bonus::SECONDARY_SKILL_PREMY, +20, make_shared(PLAYER), SecondarySkill::NECROMANCY); //Soul prison + addBonusIfBuilt(BuildingID::NECROMANCY_AMPLIFIER, Bonus::SECONDARY_SKILL_PREMY, +10, playerProp, SecondarySkill::NECROMANCY); //necromancy amplifier + addBonusIfBuilt(BuildingID::GRAIL, Bonus::SECONDARY_SKILL_PREMY, +20, playerProp, SecondarySkill::NECROMANCY); //Soul prison } else if(subID == ETownType::DUNGEON) //Dungeon { @@ -2504,10 +2506,11 @@ void CGTownInstance::recreateBuildingsBonuses() bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype /*= -1*/) { - return addBonusIfBuilt(building, type, val, TPropagatorPtr(), subtype); + static auto emptyPropagator = TPropagatorPtr(); + return addBonusIfBuilt(building, type, val, emptyPropagator, subtype); } -bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr prop, int subtype /*= -1*/) +bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr & prop, int subtype /*= -1*/) { if(hasBuilt(building)) { @@ -2595,7 +2598,7 @@ const CArmedInstance * CGTownInstance::getUpperArmy() const bool CGTownInstance::hasBuilt(BuildingID buildingID, int townID) const { - if (townID == town->typeID || townID == ETownType::ANY) + if (townID == town->faction->index || townID == ETownType::ANY) return hasBuilt(buildingID); return false; } @@ -2675,7 +2678,7 @@ void CGVisitableOPH::initObj() case 2: treePrice[Res::GEMS] = 10; break; - default: + default: break; } } @@ -2968,8 +2971,8 @@ void CGVisitableOPH::blockingDialogAnswered(const CGHeroInstance *hero, ui32 ans case Obj::SCHOOL_OF_WAR: schoolSelected(id, answer); - default: - assert(0); + default: + assert(0); break; } } @@ -3100,9 +3103,11 @@ const std::string & CGCreature::getHoverText() const { if(stacks.empty()) { + static const std::string errorValue("!!!INVALID_STACK!!!"); + //should not happen... logGlobal->errorStream() << "Invalid stack at tile " << pos << ": subID=" << subID << "; id=" << id; - return "!!!INVALID_STACK!!!"; + return errorValue; // references to temporary are illegal - use pre-constructed string } MetaString ms; @@ -6980,7 +6985,7 @@ void CArmedInstance::randomizeArmy(int type) { int level = (randID-VLC->creh->creatures.size()) / 2 -1; bool upgrade = !(randID % 2); - j->second->setType(VLC->townh->towns[type].creatures[level][upgrade]); + j->second->setType(VLC->townh->factions[type]->town->creatures[level][upgrade]); randID = -1; } @@ -7035,7 +7040,7 @@ void CArmedInstance::updateMoraleBonusFromArmy() BOOST_FOREACH(TFaction f, factions) { - if (VLC->townh->factions[f].alignment != EAlignment::EVIL) + if (VLC->townh->factions[f]->alignment != EAlignment::EVIL) mixableFactions++; } if (mixableFactions > 0) @@ -7397,7 +7402,7 @@ GrowthInfo::Entry::Entry(const std::string &format, int _count) GrowthInfo::Entry::Entry(int subID, BuildingID building, int _count) : count(_count) { - description = boost::str(boost::format("%s %+d") % VLC->townh->towns[subID].buildings[building]->Name() % count); + description = boost::str(boost::format("%s %+d") % VLC->townh->factions[subID]->town->buildings[building]->Name() % count); } CTownAndVisitingHero::CTownAndVisitingHero() diff --git a/lib/CObjectHandler.h b/lib/CObjectHandler.h index f7bc4feb0..85570c215 100644 --- a/lib/CObjectHandler.h +++ b/lib/CObjectHandler.h @@ -622,7 +622,7 @@ public: std::string nodeName() const override; void deserializationFix(); void recreateBuildingsBonuses(); - bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr prop, int subtype = -1); //returns true if building is built and bonus has been added + bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr &prop, int subtype = -1); //returns true if building is built and bonus has been added bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype = -1); //convienence version of above void setVisitingHero(CGHeroInstance *h); void setGarrisonedHero(CGHeroInstance *h); @@ -1403,7 +1403,8 @@ public: std::map creBanksNames; //[crebank index] -> name of this creature bank std::vector resVals; //default values of resources in gold - void load(); + CObjectHandler(); + int bankObjToIndex (const CGObjectInstance * obj); template void serialize(Handler &h, const int version) diff --git a/lib/CSpellHandler.cpp b/lib/CSpellHandler.cpp index 76862a17b..0be2dee39 100644 --- a/lib/CSpellHandler.cpp +++ b/lib/CSpellHandler.cpp @@ -246,10 +246,10 @@ void CSpell::getEffects(std::vector& lst, const int level) const } lst.reserve(lst.size() + effects[level].size()); - BOOST_FOREACH (Bonus b, effects[level]) + BOOST_FOREACH (Bonus *b, effects[level]) { //TODO: value, add value - lst.push_back(b); + lst.push_back(Bonus(*b)); } } @@ -344,10 +344,6 @@ bool DLL_LINKAGE isInScreenRange(const int3 ¢er, const int3 &pos) return false; } -CSpellHandler::CSpellHandler() -{ -} - CSpell * CSpellHandler::loadSpell(CLegacyConfigParser & parser, const SpellID id) { CSpell * spell = new CSpell; //new currently being read spell @@ -397,7 +393,7 @@ CSpell * CSpellHandler::loadSpell(CLegacyConfigParser & parser, const SpellID id return spell; } -void CSpellHandler::load() +CSpellHandler::CSpellHandler() { CLegacyConfigParser parser("DATA/SPTRAITS.TXT"); @@ -449,7 +445,7 @@ void CSpellHandler::load() s->counteredSpells = spell.second["counters"].convertTo >(); s->identifier = spell.first; - VLC->modh->identifiers.registerObject("spell." + spell.first, spellID); + VLC->modh->identifiers.registerObject("core", "spell", spell.first, spellID); const JsonNode & flags_node = spell.second["flags"]; if (!flags_node.isNull()) @@ -495,7 +491,7 @@ void CSpellHandler::load() if (!a.empty()) b->additionalInfo = a[i]; - s->effects[i].push_back(*b); + s->effects[i].push_back(b); } } @@ -537,7 +533,7 @@ void CSpellHandler::load() } } -std::vector CSpellHandler::getDefaultAllowedSpells() const +std::vector CSpellHandler::getDefaultAllowed() const { std::vector allowedSpells; allowedSpells.resize(GameConstants::SPELLS_QUANTITY, true); diff --git a/lib/CSpellHandler.h b/lib/CSpellHandler.h index 1bc8cd6b2..189cd9e3d 100644 --- a/lib/CSpellHandler.h +++ b/lib/CSpellHandler.h @@ -96,7 +96,7 @@ private: ETargetType targetType; - std::vector effects [4]; + std::vector effects [4]; std::vector immunities; //any of these grants immunity std::vector limiters; //all of them are required to be affected @@ -168,14 +168,12 @@ public: CSpellHandler(); std::vector< ConstTransitivePtr > spells; - void load(); - /** * Gets a list of default allowed spells. OH3 spells are all allowed by default. * * @return a list of allowed spells, the index is the spell id and the value either 0 for not allowed or 1 for allowed */ - std::vector getDefaultAllowedSpells() const; + std::vector getDefaultAllowed() const; template void serialize(Handler &h, const int version) { diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index afaf66cfa..17e299e22 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -37,18 +37,18 @@ BuildingID CBuilding::getBase() const { const CBuilding * build = this; while (build->upgrade >= 0) - build = VLC->townh->towns[build->tid].buildings[build->upgrade]; + build = build->town->buildings[build->upgrade]; return build->bid; } si32 CBuilding::getDistance(BuildingID buildID) const { - const CBuilding * build = VLC->townh->towns[tid].buildings[buildID]; + const CBuilding * build = town->buildings[buildID]; int distance = 0; while (build->upgrade >= 0 && build != this) { - build = VLC->townh->towns[build->tid].buildings[build->upgrade]; + build = build->town->buildings[build->upgrade]; distance++; } if (build == this) @@ -76,28 +76,31 @@ JsonNode readBuilding(CLegacyConfigParser & parser) return ret; } -void CTownHandler::loadLegacyData(JsonNode & dest) +std::vector CTownHandler::loadLegacyData(size_t dataSize) { + std::vector dest(dataSize); + factions.resize(dataSize); + + auto getBuild = [&](size_t town, size_t building) -> JsonNode & + { + return dest[town]["town"]["buildings"][EBuildingType::names[building]]; + }; + CLegacyConfigParser parser("DATA/BUILDING.TXT"); - dest.Vector().resize(GameConstants::F_NUMBER); parser.endLine(); // header parser.endLine(); //Unique buildings - for (size_t town=0; townmode = static_cast(boost::find(modes, source["mode"].String()) - modes); - ret->tid = town.typeID; + ret->town = &town; ret->bid = BuildingID(source["id"].Float()); ret->name = source["name"].String(); ret->description = source["description"].String(); @@ -265,9 +260,21 @@ void CTownHandler::loadBuilding(CTown &town, const JsonNode & source) void CTownHandler::loadBuildings(CTown &town, const JsonNode & source) { - BOOST_FOREACH(const JsonNode &node, source.Vector()) + if (source.getType() == JsonNode::DATA_VECTOR) { - loadBuilding(town, node); + BOOST_FOREACH(auto &node, source.Vector()) + { + if (!node.isNull()) + loadBuilding(town, node); + } + } + else + { + BOOST_FOREACH(auto &node, source.Struct()) + { + if (!node.second.isNull()) + loadBuilding(town, node.second); + } } } @@ -304,9 +311,21 @@ void CTownHandler::loadStructure(CTown &town, const JsonNode & source) void CTownHandler::loadStructures(CTown &town, const JsonNode & source) { - BOOST_FOREACH(const JsonNode &node, source.Vector()) + if (source.getType() == JsonNode::DATA_VECTOR) { - loadStructure(town, node); + BOOST_FOREACH(auto &node, source.Vector()) + { + if (!node.isNull()) + loadStructure(town, node); + } + } + else + { + BOOST_FOREACH(auto &node, source.Struct()) + { + if (!node.second.isNull()) + loadStructure(town, node.second); + } } } @@ -415,7 +434,7 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source) { auto resIter = boost::find(GameConstants::RESOURCE_NAMES, source["primaryResource"].String()); if (resIter == boost::end(GameConstants::RESOURCE_NAMES)) - town.primaryRes = 127; //Wood + Ore + town.primaryRes = Res::WOOD_AND_ORE; //Wood + Ore else town.primaryRes = resIter - boost::begin(GameConstants::RESOURCE_NAMES); @@ -462,7 +481,7 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source) VLC->modh->identifiers.requestIdentifier("heroClass." + node.first, [=, &town](si32 classID) { - VLC->heroh->classes.heroClasses[classID]->selectionProbability[town.typeID] = chance; + VLC->heroh->classes.heroClasses[classID]->selectionProbability[town.faction->index] = chance; }); } @@ -472,7 +491,7 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source) VLC->modh->identifiers.requestIdentifier("spell." + node.first, [=, &town](si32 spellID) { - SpellID(spellID).toSpell()->probabilities[town.typeID] = chance; + SpellID(spellID).toSpell()->probabilities[town.faction->index] = chance; }); } @@ -506,101 +525,68 @@ void CTownHandler::loadPuzzle(CFaction &faction, const JsonNode &source) assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES); } -void CTownHandler::load(std::string townID, const JsonNode &source) +CFaction * CTownHandler::loadFromJson(const JsonNode &source) { - int id; + CFaction * faction = new CFaction(); - if (source["index"].isNull()) - id = factions.rbegin()->first + 1; - else - id = source["index"].Float(); - - CFaction & faction = factions[id]; - - faction.factionID = id; - faction.name = source["name"].String(); + faction->name = source["name"].String(); VLC->modh->identifiers.requestIdentifier ("creature." + source["commander"].String(), [=](si32 commanderID) { - factions[id].commander = CreatureID(commanderID); + faction->commander = CreatureID(commanderID); }); - faction.creatureBg120 = source["creatureBackground"]["120px"].String(); - faction.creatureBg130 = source["creatureBackground"]["130px"].String(); + faction->creatureBg120 = source["creatureBackground"]["120px"].String(); + faction->creatureBg130 = source["creatureBackground"]["130px"].String(); - faction.nativeTerrain = ETerrainType(vstd::find_pos(GameConstants::TERRAIN_NAMES, + faction->nativeTerrain = ETerrainType(vstd::find_pos(GameConstants::TERRAIN_NAMES, source["nativeTerrain"].String())); int alignment = vstd::find_pos(EAlignment::names, source["alignment"].String()); if (alignment == -1) - faction.alignment = EAlignment::NEUTRAL; + faction->alignment = EAlignment::NEUTRAL; else - faction.alignment = static_cast(alignment); + faction->alignment = static_cast(alignment); if (!source["town"].isNull()) { - towns[id].typeID = id; - loadTown(towns[id], source["town"]); + faction->town = new CTown; + faction->town->faction = faction; + loadTown(*faction->town, source["town"]); } if (!source["puzzleMap"].isNull()) - loadPuzzle(faction, source["puzzleMap"]); + loadPuzzle(*faction, source["puzzleMap"]); - logGlobal->traceStream() << "Added faction: " << townID; - VLC->modh->identifiers.registerObject(std::string("faction.") + townID, faction.factionID); + return faction; } -void CTownHandler::load() +void CTownHandler::loadObject(std::string scope, std::string name, const JsonNode & data) { - JsonNode gameConf(ResourceID("config/gameConfig.json")); - JsonNode buildingsConf = JsonUtils::assembleFromFiles(gameConf["factions"].convertTo >()); + auto object = loadFromJson(data); + object->index = factions.size(); - JsonNode legacyConfig; - loadLegacyData(legacyConfig); + factions.push_back(object); - // semi-manually merge legacy config with towns json - - for (size_t i=0; i< legacyConfig.Vector().size(); i++) - { - JsonNode & legacyFaction = legacyConfig.Vector()[i]; - JsonNode & outputFaction = buildingsConf[ETownType::names[i]]; - - if (outputFaction["name"].isNull()) - outputFaction["name"] = legacyFaction["name"]; - - if (!outputFaction["town"].isNull()) - { - if (outputFaction["town"]["names"].isNull()) - outputFaction["town"]["names"] = legacyFaction["names"]; - - JsonNode & outputBuildings = outputFaction["town"]["buildings"]; - JsonVector & legacyBuildings = legacyFaction["buildings"].Vector(); - BOOST_FOREACH(JsonNode & building, outputBuildings.Vector()) - { - if (vstd::contains(building.Struct(), "id") && - legacyBuildings.size() > building["id"].Float() ) - { - //find same buildings in legacy and json configs - JsonNode & legacyBuilding = legacyBuildings[building["id"].Float()]; - - if (!legacyBuilding.isNull()) //merge if h3 config was found for this building - JsonUtils::merge(building, legacyBuilding); - } - } - } - } - BOOST_FOREACH(auto & entry, buildingsConf.Struct()) - { - //JsonUtils::validate(entry.second, "vcmi:faction", entry.first); - load(entry.first, entry.second); - } + VLC->modh->identifiers.registerObject(scope, "faction", name, object->index); } -std::set CTownHandler::getDefaultAllowedFactions() const +void CTownHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) { - std::set allowedFactions; - BOOST_FOREACH(auto town, towns) + auto object = loadFromJson(data); + object->index = index; + + assert(factions[index] == nullptr); // ensure that this id was not loaded before + factions[index] = object; + + VLC->modh->identifiers.registerObject(scope, "faction", name, object->index); +} + +std::vector CTownHandler::getDefaultAllowed() const +{ + std::vector allowedFactions; + BOOST_FOREACH(auto town, factions) { - allowedFactions.insert(town.first); + allowedFactions.push_back(town->town != nullptr); } return allowedFactions; } diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index 81f953e48..3a366eec1 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -4,6 +4,7 @@ #include "ResourceSet.h" #include "int3.h" #include "GameConstants.h" +#include "IHandlerBase.h" /* * CTownHandler.h, part of VCMI engine @@ -17,6 +18,7 @@ class CLegacyConfigParser; class JsonNode; +class CTown; /// a typical building encountered in every castle ;] /// this is structure available to both client and server @@ -28,7 +30,7 @@ class DLL_LINKAGE CBuilding std::string description; public: - TFaction tid; //town ID + CTown * town; // town this building belongs to BuildingID bid; //structure ID TResources resources; @@ -54,7 +56,7 @@ public: template void serialize(Handler &h, const int version) { - h & tid & bid & resources & name & description & requirements & upgrade & mode; + h & town & bid & resources & name & description & requirements & upgrade & mode; } friend class CTownHandler; @@ -79,10 +81,48 @@ struct DLL_LINKAGE CStructure } }; +struct DLL_LINKAGE SPuzzleInfo +{ + ui16 number; //type of puzzle + si16 x, y; //position + ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered) + std::string filename; //file with graphic of this puzzle + + template void serialize(Handler &h, const int version) + { + h & number & x & y & whenUncovered & filename; + } +}; + +class CFaction +{ +public: + std::string name; //town name, by default - from TownName.txt + + TFaction index; + + ETerrainType nativeTerrain; + EAlignment::EAlignment alignment; + + CreatureID commander; + + CTown * town; //NOTE: can be null + + std::string creatureBg120; + std::string creatureBg130; + + std::vector puzzleMap; + + template void serialize(Handler &h, const int version) + { + h & name & index & nativeTerrain & creatureBg120 & creatureBg130 & puzzleMap; + } +}; + class DLL_LINKAGE CTown { public: - TFaction typeID;//same as CFaction::factionID + CFaction * faction; std::vector names; //names of the town instances @@ -148,48 +188,12 @@ public: template void serialize(Handler &h, const int version) { - h & names & typeID & creatures & dwellings & dwellingNames & buildings & hordeLvl & mageLevel + h & names & faction & creatures & dwellings & dwellingNames & buildings & hordeLvl & mageLevel & primaryRes & warMachine & clientInfo & moatDamage; } }; -struct DLL_LINKAGE SPuzzleInfo -{ - ui16 number; //type of puzzle - si16 x, y; //position - ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered) - std::string filename; //file with graphic of this puzzle - - template void serialize(Handler &h, const int version) - { - h & number & x & y & whenUncovered & filename; - } -}; - -class CFaction -{ -public: - std::string name; //town name, by default - from TownName.txt - - TFaction factionID; - - ETerrainType nativeTerrain; - EAlignment::EAlignment alignment; - - CreatureID commander; - - std::string creatureBg120; - std::string creatureBg130; - - std::vector puzzleMap; - - template void serialize(Handler &h, const int version) - { - h & name & factionID & nativeTerrain & creatureBg120 & creatureBg130 & puzzleMap; - } -}; - -class DLL_LINKAGE CTownHandler +class DLL_LINKAGE CTownHandler : public IHandlerBase { /// loads CBuilding's into town void loadBuilding(CTown &town, const JsonNode & source); @@ -209,38 +213,22 @@ class DLL_LINKAGE CTownHandler void loadPuzzle(CFaction & faction, const JsonNode & source); - /// load all available data from h3 txt(s) into json structure using format similar to vcmi configs - /// returns 2d array [townID] [buildID] of buildings - void loadLegacyData(JsonNode & dest); + CFaction * loadFromJson(const JsonNode & data); public: - std::map towns; - std::map factions; + std::vector > factions; CTownHandler(); //c-tor, set pointer in VLC to this - /// main loading function for mods, accepts merged JSON source and add all entries from it into game - /// all entries in JSON should be checked for validness before using this function - void load(std::string townID, const JsonNode & source); + std::vector loadLegacyData(size_t dataSize) override; - /// "entry point" for loading of OH3 town. - /// reads legacy txt's from H3 + vcmi json, merges them - /// and loads resulting structure to game using loadTowns method - void load(); + 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; - /** - * Gets a list of default allowed factions. OH3 factions are in the range of 0 to 8. - * - * TODO Proposal for town modding: Replace faction id with a unique machine readable town name - * and create a JSON config file or merge it with other configs which describes which - * towns can be used for random map generation / map editor(default map settings). - * - * @return a list of allowed factions, the index which is unique is the faction id - */ - std::set getDefaultAllowedFactions() const; + std::vector getDefaultAllowed() const override; template void serialize(Handler &h, const int version) { - h & towns & factions; + h & factions; } }; diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 3bb9f6c69..79899b8d5 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -209,10 +209,14 @@ class PlayerColor : public BaseForID { INSTID_LIKE_CLASS_COMMON(PlayerColor, ui8) + enum EPlayerColor + { + PLAYER_LIMIT_I = 8 + }; + DLL_LINKAGE static const PlayerColor CANNOT_DETERMINE; //253 DLL_LINKAGE static const PlayerColor UNFLAGGABLE; //254 - neutral objects (pandora, banks) DLL_LINKAGE static const PlayerColor NEUTRAL; //255 - DLL_LINKAGE static const int PLAYER_LIMIT_I = 8; //player limit per map DLL_LINKAGE static const PlayerColor PLAYER_LIMIT; //player limit per map DLL_LINKAGE bool isValidPlayer() const; //valid means < PLAYER_LIMIT (especially non-neutral) diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index bae9e8c22..442f3a4fb 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -1158,7 +1158,7 @@ Bonus::Bonus() valType = ADDITIVE_VALUE; effectRange = NO_LIMIT; val = 0; - source = OTHER; + source = OTHER; } Bonus::~Bonus() diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 6023c403d..c976253a1 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -256,7 +256,7 @@ template DLL_LINKAGE void CPrivilagedInfoCallback::loadCommonState(CLoadFile&); template DLL_LINKAGE void CPrivilagedInfoCallback::saveCommonState(CSaveFile&) const; -inline TerrainTile * CNonConstInfoCallback::getTile( int3 pos ) +TerrainTile * CNonConstInfoCallback::getTile( int3 pos ) { if(!gs->map->isInTheMap(pos)) return NULL; @@ -274,7 +274,7 @@ const CTown * CGameInfoCallback::getNativeTown(PlayerColor color) const { const PlayerSettings *ps = getPlayerSettings(color); ERROR_RET_VAL_IF(!ps, "There is no such player!", NULL); - return &VLC->townh->towns[ps->castle]; + return VLC->townh->factions[ps->castle]->town; } const CGObjectInstance * CGameInfoCallback::getObjByQuestIdentifier(int identifier) const @@ -900,7 +900,6 @@ CGHeroInstance *CNonConstInfoCallback::getHero(ObjectInstanceID objid) CGTownInstance *CNonConstInfoCallback::getTown(ObjectInstanceID objid) { - return const_cast(CGameInfoCallback::getTown(objid)); } diff --git a/lib/IHandlerBase.h b/lib/IHandlerBase.h new file mode 100644 index 000000000..e6137d697 --- /dev/null +++ b/lib/IHandlerBase.h @@ -0,0 +1,40 @@ +#pragma once + +/* + * IHandlerBase.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 + * + */ + +class JsonNode; + +/// base class for all handlers that can be accessed from mod system +class DLL_LINKAGE IHandlerBase +{ + // there also should be private member with such signature: + // Object * loadFromJson(const JsonNode & json); + // where Object is type of data loaded by handler + // primary used in loadObject methods + +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 loadLegacyData(size_t dataSize) = 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; + virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) = 0; + + /** + * Gets a list of objects that are allowed by default on maps + * + * @return a list of allowed objects, the index is the object id + */ + virtual std::vector getDefaultAllowed() const = 0; + + virtual ~IHandlerBase(){} +}; \ No newline at end of file diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index 3a09eeefe..7557a8b2f 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -1125,8 +1125,8 @@ bool JsonValidator::validate(const JsonNode &root, std::string schemaName, std:: if (!errors.empty()) { - logGlobal->warnStream() << "Data in " << name << " is invalid!"; - logGlobal->warnStream() << errors; + logGlobal->warnStream() << "Data in " << name << " is invalid!"; + logGlobal->warnStream() << errors; } return errors.empty(); @@ -1162,7 +1162,7 @@ Bonus * JsonUtils::parseBonus (const JsonVector &ability_vec) //TODO: merge with template const T & parseByMap(const std::map & map, const JsonNode * val, std::string err) { - static T defaultValue; + static T defaultValue = T(); if (!val->isNull()) { std::string type = val->String(); @@ -1179,7 +1179,7 @@ const T & parseByMap(const std::map & map, const JsonNode * val, } else return defaultValue; -}; +} void JsonUtils::resolveIdentifier (si32 &var, const JsonNode &node, std::string name) { diff --git a/lib/ResourceSet.h b/lib/ResourceSet.h index f81c38f29..556fccecd 100644 --- a/lib/ResourceSet.h +++ b/lib/ResourceSet.h @@ -22,7 +22,9 @@ namespace Res enum ERes { - WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL + WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL, + + WOOD_AND_ORE = 127 // special case for town bonus resource }; //class to be representing a vector of resource diff --git a/lib/StringConstants.h b/lib/StringConstants.h index 107a5b501..c8ace79c1 100644 --- a/lib/StringConstants.h +++ b/lib/StringConstants.h @@ -59,6 +59,22 @@ namespace NSecondarySkill }; } +namespace EBuildingType +{ + const std::string names [44] = + { + "mageGuild1", "mageGuild2", "mageGuild3", "mageGuild4", "mageGuild5", + "tavern", "shipyard", "fort", "citadel", "castle", + "villageHall", "townHall", "cityHall", "capitol", "marketplace", + "resourceSilo", "blacksmith", "special1", "horde1", "horde1Upgr", + "ship", "special2", "special3", "special4", "horde2", + "horde2Upgr", "grail", "extraTownHall", "extraCityHall", "extraCapitol", + "dwellingLvl1", "dwellingLvl2", "dwellingLvl3", "dwellingLvl4", "dwellingLvl5", + "dwellingLvl6", "dwellingLvl7", "dwellingUpLvl1", "dwellingUpLvl2", "dwellingUpLvl3", + "dwellingUpLvl4", "dwellingUpLvl5", "dwellingUpLvl6", "dwellingUpLvl7" + }; +} + namespace ETownType { const std::string names [GameConstants::F_NUMBER] = diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index ff8cd20c6..142f9a015 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -78,19 +78,18 @@ void LibClasses::loadFilesystem() static void logHandlerLoaded(const std::string& name, CStopWatch &timer) { - logGlobal->infoStream()<<"\t" << name << " handler: "<infoStream()<<"\t\t" << name << " handler: "< void createHandler(Handler *&handler, const std::string &name, CStopWatch &timer) { handler = new Handler(); - handler->load(); logHandlerLoaded(name, timer); } void LibClasses::init() { - CStopWatch pomtime; + CStopWatch pomtime, totalTime; createHandler(bth, "Bonus type", pomtime); @@ -110,7 +109,9 @@ void LibClasses::init() createHandler(spellh, "Spell", pomtime); - modh->loadActiveMods(); + logGlobal->infoStream()<<"\tInitializing handers: "<< totalTime.getDiff(); + + modh->loadGameContent(); modh->reload(); //FIXME: make sure that everything is ok after game restart //TODO: This should be done every time mod config changes @@ -155,9 +156,10 @@ LibClasses::LibClasses() void LibClasses::callWhenDeserializing() { - generaltexth = new CGeneralTextHandler; - generaltexth->load(); - arth->load(true); + // FIXME: check if any of these are needed + //generaltexth = new CGeneralTextHandler; + //generaltexth->load(); + //arth->load(true); //modh->recreateHandlers(); //modh->loadConfigFromFile ("defaultMods"); //TODO: remember last saved config } diff --git a/lib/VCMI_Lib.h b/lib/VCMI_Lib.h index 30c58e7f9..ce4779288 100644 --- a/lib/VCMI_Lib.h +++ b/lib/VCMI_Lib.h @@ -27,14 +27,14 @@ class CBonusTypeHandler; class DLL_LINKAGE LibClasses { CBonusTypeHandler * bth; - + void callWhenDeserializing(); //should be called only by serialize !!! void makeNull(); //sets all handler pointers to null public: bool IS_AI_ENABLED; //VLC is the only object visible from both CMT and GeniusAI const IBonusTypeHandler * getBth() const; - + CArtHandler * arth; CHeroHandler * heroh; CCreatureHandler * creh; diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index 881bdfa4a..f9dde43fb 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -18,7 +18,10 @@ PlayerInfo::PlayerInfo(): canHumanPlay(false), canComputerPlay(false), aiTactic(EAiTactic::RANDOM), isFactionRandom(false), mainHeroPortrait(-1), hasMainTown(false), generateHeroAtMainTown(false), team(255), generateHero(false), p7(0), hasHero(false), customHeroID(-1), powerPlaceholders(-1) { - allowedFactions = VLC->townh->getDefaultAllowedFactions(); + auto allowed = VLC->townh->getDefaultAllowed(); + for (size_t i=0; iheroh->getDefaultAllowedHeroes(); + allowedHeroes = VLC->heroh->getDefaultAllowed(); players.resize(PlayerColor::PLAYER_LIMIT_I); } @@ -148,8 +151,8 @@ CMapHeader::~CMapHeader() CMap::CMap() : checksum(0), grailRadious(0), terrain(nullptr) { allowedAbilities = VLC->heroh->getDefaultAllowedAbilities(); - allowedArtifact = VLC->arth->getDefaultAllowedArtifacts(); - allowedSpell = VLC->spellh->getDefaultAllowedSpells(); + allowedArtifact = VLC->arth->getDefaultAllowed(); + allowedSpell = VLC->spellh->getDefaultAllowed(); } CMap::~CMap() diff --git a/lib/mapping/CMapEditManager.h b/lib/mapping/CMapEditManager.h index fd05b29c9..640beb36c 100644 --- a/lib/mapping/CMapEditManager.h +++ b/lib/mapping/CMapEditManager.h @@ -16,7 +16,7 @@ class CGObjectInstance; class CTerrainViewPatternConfig; -class TerrainViewPattern; +struct TerrainViewPattern; namespace ETerrainGroup { diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 0815d3462..0762a16a4 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -160,7 +160,7 @@ void CMapGenOptions::setMonsterStrength(EMonsterStrength::EMonsterStrength value void CMapGenOptions::resetPlayersMap() { players.clear(); - int realPlayersCnt = playersCnt == RANDOM_SIZE ? PlayerColor::PLAYER_LIMIT_I : playersCnt; + int realPlayersCnt = playersCnt == RANDOM_SIZE ? static_cast(PlayerColor::PLAYER_LIMIT_I) : playersCnt; int realCompOnlyPlayersCnt = compOnlyPlayersCnt == RANDOM_SIZE ? (PlayerColor::PLAYER_LIMIT_I - realPlayersCnt) : compOnlyPlayersCnt; for(int color = 0; color < (realPlayersCnt + realCompOnlyPlayersCnt); ++color) { @@ -337,7 +337,7 @@ si32 CMapGenOptions::CPlayerSettings::getStartingTown() const void CMapGenOptions::CPlayerSettings::setStartingTown(si32 value) { - if(value >= -1 && value < static_cast(VLC->townh->towns.size())) + if(value >= -1 && value < static_cast(VLC->townh->factions.size())) { startingTown = value; } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 75eb08269..506d4e3bd 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1271,7 +1271,7 @@ void CGameHandler::newTurn() { if(t->hasBuilt(BuildingID::RESOURCE_SILO)) //there is resource silo { - if(t->town->primaryRes == 127) //we'll give wood and ore + if(t->town->primaryRes == Res::WOOD_AND_ORE) //we'll give wood and ore { n.res[player][Res::WOOD] ++; n.res[player][Res::ORE] ++; @@ -4739,11 +4739,12 @@ bool CGameHandler::complain( const std::string &problem ) void CGameHandler::showGarrisonDialog( ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function &cb ) { - PlayerColor player = getOwner(hid); + //PlayerColor player = getOwner(hid); auto upperArmy = dynamic_cast(getObj(upobj)); auto lowerArmy = dynamic_cast(getObj(hid)); - assert(upperArmy, lowerArmy); + assert(lowerArmy); + assert(upperArmy); auto garrisonQuery = make_shared(upperArmy, lowerArmy); queries.addQuery(garrisonQuery); @@ -4789,6 +4790,16 @@ bool CGameHandler::isAllowedExchange( ObjectInstanceID id1, ObjectInstanceID id2 return true; } + if (o1->ID == Obj::HERO && o2->ID == Obj::HERO) + { + const CGHeroInstance *h1 = static_cast(o1); + const CGHeroInstance *h2 = static_cast(o2); + + // two heroes in same town (garrisoned and visiting) + if (h1->visitedTown != nullptr && h2->visitedTown != nullptr && h1->visitedTown == h2->visitedTown) + return true; + } + //Ongoing garrison exchange if(auto dialog = std::dynamic_pointer_cast(queries.topQuery(o1->tempOwner))) { diff --git a/server/CQuery.cpp b/server/CQuery.cpp index ee82a64da..ffcf38b39 100644 --- a/server/CQuery.cpp +++ b/server/CQuery.cpp @@ -1,7 +1,7 @@ #include "StdInc.h" #include "CQuery.h" #include "CGameHandler.h" -#include "..\lib\BattleState.h" +#include "../lib/BattleState.h" boost::mutex Queries::mx; diff --git a/server/CQuery.h b/server/CQuery.h index ef3197624..a32122617 100644 --- a/server/CQuery.h +++ b/server/CQuery.h @@ -1,7 +1,7 @@ #pragma once -#include "..\lib\GameConstants.h" -#include "..\lib\int3.h" -#include "..\lib\NetPacks.h" +#include "../lib/GameConstants.h" +#include "../lib/int3.h" +#include "../lib/NetPacks.h" class CGObjectInstance; class CGHeroInstance; @@ -174,4 +174,4 @@ public: std::vector> allQueries(); //void removeQuery -}; \ No newline at end of file +};