mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge pull request #529 from nullkiller/AI-fix-freeze-on-buyarmy
AI: fix freeze on BuyArmy
This commit is contained in:
commit
0a461829fb
@ -524,7 +524,8 @@ creInfo infoFromDC(const dwellingContent & dc)
|
||||
return ci;
|
||||
}
|
||||
|
||||
ui64 howManyReinforcementsCanBuy(HeroPtr h, const CGDwelling * t)
|
||||
|
||||
ui64 howManyReinforcementsCanBuy(const CArmedInstance * h, const CGDwelling * t)
|
||||
{
|
||||
ui64 aivalue = 0;
|
||||
|
||||
@ -552,7 +553,7 @@ ui64 howManyReinforcementsCanBuy(HeroPtr h, const CGDwelling * t)
|
||||
return aivalue;
|
||||
}
|
||||
|
||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance * t)
|
||||
ui64 howManyReinforcementsCanGet(const CArmedInstance * h, const CGTownInstance * t)
|
||||
{
|
||||
ui64 ret = 0;
|
||||
int freeHeroSlots = GameConstants::ARMY_SIZE - h->stacksCount();
|
||||
|
@ -179,8 +179,8 @@ bool compareMovement(HeroPtr lhs, HeroPtr rhs);
|
||||
bool compareHeroStrength(HeroPtr h1, HeroPtr h2);
|
||||
bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2);
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2);
|
||||
ui64 howManyReinforcementsCanBuy(HeroPtr h, const CGDwelling * t);
|
||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance * t);
|
||||
ui64 howManyReinforcementsCanBuy(const CArmedInstance * h, const CGDwelling * t);
|
||||
ui64 howManyReinforcementsCanGet(const CArmedInstance * h, const CGTownInstance * t);
|
||||
int3 whereToExplore(HeroPtr h);
|
||||
uint32_t distanceToTile(const CGHeroInstance * hero, int3 pos);
|
||||
|
||||
|
@ -64,7 +64,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
|
||||
if(ai->isAccessibleForHero(pos, hero))
|
||||
{
|
||||
//grab army from town
|
||||
if(!t->visitingHero && howManyReinforcementsCanGet(hero, t))
|
||||
if(!t->visitingHero && howManyReinforcementsCanGet(hero.get(), t))
|
||||
{
|
||||
if(!vstd::contains(ai->townVisitsThisWeek[hero], t))
|
||||
ret.push_back(sptr(VisitTile(pos).sethero(hero)));
|
||||
@ -72,10 +72,23 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
|
||||
//buy army in town
|
||||
if (!t->visitingHero || t->visitingHero == hero.get(true))
|
||||
{
|
||||
ui32 val = std::min<ui32>(value, howManyReinforcementsCanBuy(hero, t));
|
||||
std::vector<int> values = {
|
||||
value,
|
||||
(int)howManyReinforcementsCanBuy(t->getUpperArmy(), t),
|
||||
(int)howManyReinforcementsCanBuy(hero.get(), t) };
|
||||
|
||||
int val = *std::min_element(values.begin(), values.end());
|
||||
|
||||
logAi->trace(
|
||||
"Army value need %i, to hero %i, to town %i",
|
||||
value,
|
||||
(int)howManyReinforcementsCanBuy(hero.get(), t),
|
||||
(int)howManyReinforcementsCanBuy(t->getUpperArmy(), t));
|
||||
|
||||
if (val)
|
||||
{
|
||||
auto goal = sptr(BuyArmy(t, val).sethero(hero));
|
||||
|
||||
if(!ai->ah->containsObjective(goal)) //avoid loops caused by reserving same objective twice
|
||||
ret.push_back(goal);
|
||||
else
|
||||
@ -137,7 +150,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
|
||||
{
|
||||
auto dwelling = dynamic_cast<const CGDwelling *>(obj);
|
||||
|
||||
ui32 val = std::min<ui32>(value, howManyReinforcementsCanBuy(hero, dwelling));
|
||||
ui32 val = std::min<ui32>(value, howManyReinforcementsCanBuy(hero.get(), dwelling));
|
||||
|
||||
if(val)
|
||||
{
|
||||
|
@ -1456,12 +1456,13 @@ void VCAI::wander(HeroPtr h)
|
||||
|
||||
auto compareReinforcements = [h](const CGTownInstance * lhs, const CGTownInstance * rhs) -> bool
|
||||
{
|
||||
auto r1 = howManyReinforcementsCanGet(h, lhs),
|
||||
r2 = howManyReinforcementsCanGet(h, rhs);
|
||||
const CGHeroInstance * hptr = h.get();
|
||||
auto r1 = howManyReinforcementsCanGet(hptr, lhs),
|
||||
r2 = howManyReinforcementsCanGet(hptr, rhs);
|
||||
if (r1 != r2)
|
||||
return r1 < r2;
|
||||
else
|
||||
return howManyReinforcementsCanBuy(h, lhs) < howManyReinforcementsCanBuy(h, rhs);
|
||||
return howManyReinforcementsCanBuy(hptr, lhs) < howManyReinforcementsCanBuy(hptr, rhs);
|
||||
};
|
||||
|
||||
std::vector<const CGTownInstance *> townsReachable;
|
||||
@ -2200,6 +2201,8 @@ void VCAI::tryRealize(Goals::BuyArmy & g)
|
||||
ui64 valueBought = 0;
|
||||
//buy the stacks with largest AI value
|
||||
|
||||
makePossibleUpgrades(t);
|
||||
|
||||
while (valueBought < g.value)
|
||||
{
|
||||
auto res = ah->allResources();
|
||||
@ -2209,7 +2212,15 @@ void VCAI::tryRealize(Goals::BuyArmy & g)
|
||||
{
|
||||
auto ci = infoFromDC(t->creatures[i]);
|
||||
|
||||
if(!ci.count || ci.creID == -1 || (g.objid != -1 && ci.creID != g.objid))
|
||||
if(!ci.count
|
||||
|| ci.creID == -1
|
||||
|| (g.objid != -1 && ci.creID != g.objid)
|
||||
|| t->getUpperArmy()->getSlotFor(ci.creID) == SlotID())
|
||||
continue;
|
||||
|
||||
vstd::amin(ci.count, res / ci.cre->cost); //max count we can afford
|
||||
|
||||
if(!ci.count)
|
||||
continue;
|
||||
|
||||
ci.level = i; //this is important for Dungeon Summoning Portal
|
||||
@ -2223,21 +2234,17 @@ void VCAI::tryRealize(Goals::BuyArmy & g)
|
||||
*boost::max_element(creaturesInDwellings, [&res](const creInfo & lhs, const creInfo & rhs)
|
||||
{
|
||||
//max value of creatures we can buy with our res
|
||||
int value1 = lhs.cre->AIValue * (std::min(lhs.count, res / lhs.cre->cost)),
|
||||
value2 = rhs.cre->AIValue * (std::min(rhs.count, res / rhs.cre->cost));
|
||||
int value1 = lhs.cre->AIValue * lhs.count,
|
||||
value2 = rhs.cre->AIValue * rhs.count;
|
||||
|
||||
return value1 < value2;
|
||||
});
|
||||
|
||||
vstd::amin(ci.count, res / ci.cre->cost); //max count we can afford
|
||||
if (ci.count > 0 && t->getUpperArmy()->getSlotFor(ci.creID) != SlotID())
|
||||
{
|
||||
cb->recruitCreatures(t, t->getUpperArmy(), ci.creID, ci.count, ci.level);
|
||||
valueBought += ci.count * ci.cre->AIValue;
|
||||
}
|
||||
else
|
||||
throw cannotFulfillGoalException("Can't buy any more creatures!");
|
||||
|
||||
cb->recruitCreatures(t, t->getUpperArmy(), ci.creID, ci.count, ci.level);
|
||||
valueBought += ci.count * ci.cre->AIValue;
|
||||
}
|
||||
|
||||
throw goalFulfilledException(sptr(g)); //we bought as many creatures as we wanted
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user