diff --git a/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp b/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp index 9666bb3e4..766dcbfa1 100644 --- a/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp +++ b/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp @@ -33,7 +33,7 @@ void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo) BuildingID prefixes[] = {BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_FIRST}; - for(int level = 0; level < GameConstants::CREATURES_PER_TOWN; level++) + for(int level = 0; level < developmentInfo.town->town->creatures.size(); level++) { logAi->trace("Checking dwelling level %d", level); BuildingInfo nextToBuild = BuildingInfo(); diff --git a/AI/VCAI/Goals/GatherTroops.cpp b/AI/VCAI/Goals/GatherTroops.cpp index ed4e1a6c0..275bef9f5 100644 --- a/AI/VCAI/Goals/GatherTroops.cpp +++ b/AI/VCAI/Goals/GatherTroops.cpp @@ -109,7 +109,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals() if(upgradeNumber < 0) continue; - BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * GameConstants::CREATURES_PER_TOWN); + BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * t->town->creatures.size()); if(t->hasBuilt(bid) && ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) //this assumes only creatures with dwellings are assigned to faction { solutions.push_back(sptr(BuyArmy(t, creature->getAIValue() * this->value).setobjid(objid))); diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 4434e2fdc..8a0e028ad 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -237,7 +237,7 @@ std::string CBuildingRect::getSubtitle()//hover text for building return town->town->buildings.at(getBuilding()->bid)->getNameTranslated(); else//dwellings - recruit %creature% { - auto & availableCreatures = town->creatures[(bid-30)%GameConstants::CREATURES_PER_TOWN].second; + auto & availableCreatures = town->creatures[(bid-30)%town->town->creatures.size()].second; if(availableCreatures.size()) { int creaID = availableCreatures.back();//taking last of available creatures @@ -688,7 +688,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil if (building >= BuildingID::DWELL_FIRST) { - enterDwelling((building-BuildingID::DWELL_FIRST)%GameConstants::CREATURES_PER_TOWN); + enterDwelling((building-BuildingID::DWELL_FIRST)%town->town->creatures.size()); } else { @@ -800,10 +800,10 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil break; case BuildingSubID::PORTAL_OF_SUMMONING: - if (town->creatures[GameConstants::CREATURES_PER_TOWN].second.empty())//No creatures + if (town->creatures[town->town->creatures.size()].second.empty())//No creatures LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30]); else - enterDwelling(GameConstants::CREATURES_PER_TOWN); + enterDwelling(town->town->creatures.size()); break; case BuildingSubID::BALLISTA_YARD: @@ -917,8 +917,8 @@ void CCastleBuildings::enterDwelling(int level) void CCastleBuildings::enterToTheQuickRecruitmentWindow() { const auto beginIt = town->creatures.cbegin(); - const auto afterLastIt = town->creatures.size() > GameConstants::CREATURES_PER_TOWN - ? std::next(beginIt, GameConstants::CREATURES_PER_TOWN) + const auto afterLastIt = town->creatures.size() > town->town->creatures.size() + ? std::next(beginIt, town->town->creatures.size()) : town->creatures.cend(); const auto hasSomeoneToRecruit = std::any_of(beginIt, afterLastIt, [](const auto & creatureInfo) { return creatureInfo.first > 0; }); @@ -1880,7 +1880,7 @@ const CBuilding * CFortScreen::RecruitArea::getMyBuilding() { BuildingID myID = BuildingID(BuildingID::DWELL_FIRST + level); - if (level == GameConstants::CREATURES_PER_TOWN) + if (level == town->town->creatures.size()) return town->town->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING); if (!town->town->buildings.count(myID)) @@ -1891,7 +1891,7 @@ const CBuilding * CFortScreen::RecruitArea::getMyBuilding() { if (town->hasBuilt(myID)) build = town->town->buildings.at(myID); - myID.advance(GameConstants::CREATURES_PER_TOWN); + myID.advance(town->town->creatures.size()); } return build; } diff --git a/client/windows/QuickRecruitmentWindow.cpp b/client/windows/QuickRecruitmentWindow.cpp index ae976282b..4c478593b 100644 --- a/client/windows/QuickRecruitmentWindow.cpp +++ b/client/windows/QuickRecruitmentWindow.cpp @@ -51,7 +51,7 @@ void QuickRecruitmentWindow::setCreaturePurchaseCards() { int availableAmount = getAvailableCreatures(); Point position = Point((pos.w - 100*availableAmount - 8*(availableAmount-1))/2,64); - for (int i = 0; i < GameConstants::CREATURES_PER_TOWN; i++) + for (int i = 0; i < town->town->creatures.size(); i++) { if(!town->town->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first) { @@ -120,7 +120,7 @@ void QuickRecruitmentWindow::purchaseUnits() int QuickRecruitmentWindow::getAvailableCreatures() { int creaturesAmount = 0; - for (int i=0; i< GameConstants::CREATURES_PER_TOWN; i++) + for (int i=0; i< town->town->creatures.size(); i++) if(!town->town->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first) creaturesAmount++; return creaturesAmount; diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 5e23f3e5a..854b03ef3 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -760,7 +760,7 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects) auto addBonusForTier = [&](int tier, std::shared_ptr b) { assert(vstd::iswithin(tier, 1, 7)); //bonuses from level 7 are given to high-level creatures too - auto max = tier == GameConstants::CREATURES_PER_TOWN ? std::numeric_limits::max() : tier + 1; + auto max = tier == 7 ? std::numeric_limits::max() : tier + 1; auto limiter = std::make_shared(tier, max); b->addLimiter(limiter); globalEffects.addNewBonus(b); diff --git a/lib/constants/EntityIdentifiers.h b/lib/constants/EntityIdentifiers.h index c30fdf6f1..5fe8912c0 100644 --- a/lib/constants/EntityIdentifiers.h +++ b/lib/constants/EntityIdentifiers.h @@ -296,16 +296,16 @@ public: RESOURCE_SILO, BLACKSMITH, SPECIAL_1, HORDE_1, HORDE_1_UPGR, SHIP, SPECIAL_2, SPECIAL_3, SPECIAL_4, HORDE_2, HORDE_2_UPGR, GRAIL, EXTRA_TOWN_HALL, EXTRA_CITY_HALL, EXTRA_CAPITOL, - DWELL_FIRST=30, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LVL_7, DWELL_LAST=37, - DWELL_UP_FIRST=38, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, - DWELL_LVL_6_UP, DWELL_LVL_7_UP, DWELL_UP_LAST=45, + DWELL_FIRST=30, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LAST=36, + DWELL_UP_FIRST=37, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, + DWELL_LVL_6_UP, DWELL_UP_LAST=43, DWELL_LVL_8_UP, DWELL_LVL_8, DWELL_LVL_1 = DWELL_FIRST, - DWELL_LVL_8 = DWELL_LAST, + DWELL_LVL_7 = DWELL_LAST, DWELL_LVL_1_UP = DWELL_UP_FIRST, - DWELL_LVL_8_UP = DWELL_UP_LAST, + DWELL_LVL_7_UP = DWELL_UP_LAST, - DWELL_UP2_FIRST = DWELL_LVL_8_UP + 1, + DWELL_UP2_FIRST = DWELL_LVL_7_UP + 1, // //Special buildings for towns. CASTLE_GATE = SPECIAL_3, //Inferno @@ -314,6 +314,9 @@ public: }; + const std::vector dwellings = { DWELL_LVL_1, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LVL_7, DWELL_LVL_8 }; + const std::vector dwellingsUp = { DWELL_LVL_1_UP, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, DWELL_LVL_6_UP, DWELL_LVL_7_UP, DWELL_LVL_8_UP }; + bool IsSpecialOrGrail() const { return num == SPECIAL_1 || num == SPECIAL_2 || num == SPECIAL_3 || num == SPECIAL_4 || num == GRAIL; diff --git a/lib/entities/building/CBuildingHandler.cpp b/lib/entities/building/CBuildingHandler.cpp index dcdd1c2ca..293a4f8fa 100644 --- a/lib/entities/building/CBuildingHandler.cpp +++ b/lib/entities/building/CBuildingHandler.cpp @@ -9,6 +9,9 @@ */ #include "StdInc.h" #include "CBuildingHandler.h" +#include "VCMI_Lib.h" +#include "../faction/CTown.h" +#include "../faction/CTownHandler.h" VCMI_LIB_NAMESPACE_BEGIN @@ -36,7 +39,7 @@ BuildingID CBuildingHandler::campToERMU(int camp, FactionID townType, const std: }; int curPos = static_cast(campToERMU.size()); - for (int i=0; itownh)[townType]->town->creatures.size(); ++i) { if(camp == curPos) //non-upgraded return BuildingID(30 + i); diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index 1ad39fef1..12971d0f4 100644 --- a/lib/gameState/CGameState.cpp +++ b/lib/gameState/CGameState.cpp @@ -864,7 +864,7 @@ void CGameState::initTowns() //town events for(CCastleEvent &ev : vti->events) { - for (int i = 0; igetTown()->creatures.size(); i++) if (vstd::contains(ev.buildings,hordes[i])) //if we have horde for this level { ev.buildings.erase(hordes[i]); diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 01d5bce96..6ec65f759 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -128,7 +128,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const { GrowthInfo ret; - if (level<0 || level >=GameConstants::CREATURES_PER_TOWN) + if (level<0 || level >=town->creatures.size()) return ret; if (creatures[level].second.empty()) return ret; //no dwelling @@ -591,7 +591,7 @@ void CGTownInstance::newTurn(vstd::RNG & rand) const } if ((stacksCount() < GameConstants::ARMY_SIZE && rand.nextInt(99) < 25) || Slots().empty()) //add new stack { - int i = rand.nextInt(std::min(GameConstants::CREATURES_PER_TOWN, cb->getDate(Date::MONTH) << 1) - 1); + int i = rand.nextInt(std::min((int)town->creatures.size(), cb->getDate(Date::MONTH) << 1) - 1); if (!town->creatures[i].empty()) { CreatureID c = town->creatures[i][0]; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index e665af1c8..a4e43183c 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2362,8 +2362,8 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID, { if(buildingID >= BuildingID::DWELL_FIRST) //dwelling { - int level = (buildingID - BuildingID::DWELL_FIRST) % GameConstants::CREATURES_PER_TOWN; - int upgradeNumber = (buildingID - BuildingID::DWELL_FIRST) / GameConstants::CREATURES_PER_TOWN; + int level = (buildingID - BuildingID::DWELL_FIRST) % t->town->creatures.size(); + int upgradeNumber = (buildingID - BuildingID::DWELL_FIRST) / t->town->creatures.size(); if(upgradeNumber >= t->town->creatures.at(level).size()) {