diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index e9388dba2..f50546b0f 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -3233,10 +3233,15 @@ TSubgoal CGoal::whatToDoToAchieve() auto creature = VLC->creh->creatures[objid]; if (t->subID == creature->faction) //TODO: how to force AI to build unupgraded creatures? :O { - auto creatures = t->town->creatures[creature->level]; - int upgradeNumber = std::find(creatures.begin(), creatures.end(), creature->idNumber) - creatures.begin(); + auto creatures = vstd::tryAt(t->town->creatures, creature->level - 1); + if(!creatures) + continue; - BuildingID bid(BuildingID::DWELL_FIRST + creature->level + upgradeNumber * GameConstants::CREATURES_PER_TOWN); + int upgradeNumber = vstd::find_pos(*creatures, creature->idNumber); + if(upgradeNumber < 0) + continue; + + BuildingID bid(BuildingID::DWELL_FIRST + creature->level - 1 + upgradeNumber * GameConstants::CREATURES_PER_TOWN); if (t->hasBuilt(bid)) //this assumes only creatures with dwellings are assigned to faction { dwellings.push_back(t); diff --git a/Global.h b/Global.h index 60ccf7c9e..10190d2c7 100644 --- a/Global.h +++ b/Global.h @@ -601,6 +601,34 @@ namespace vstd return nullptr; } + template + bool isValidIndex(const Container &c, Index i) + { + return i >= 0 && i < c.size(); + } + + template + boost::optional tryAt(const Container &c, Index i) + { + if(isValidIndex(c, i)) + { + auto itr = c.begin(); + std::advance(itr, i); + return *itr; + } + return boost::none; + } + + template + static boost::optional tryFindIf(const Container &r, const Pred &t) + { + auto pos = range::find_if(r, t); + if(pos == boost::end(r)) + return boost::none; + else + return *pos; + } + using boost::math::round; } using vstd::operator-=; diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index b5ae8fbe8..0e9f1e6f1 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -33,7 +33,7 @@ public: CreatureID idNumber; TFaction faction; - ui8 level; // 0 - unknown + ui8 level; // 0 - unknown; 1-7 for "usual" creatures //stats that are not handled by bonus system ui32 fightValue, AIValue, growth, hordeGrowth;