mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-08 00:39:47 +02:00
AI can now disband units that block slots for buying better units
When the AI cannot buy units in a city because all slots are blocked and the units in the slot are cheaper than the units it wants to buy, the AI will now get rid of the units that block that slot in order to be able to buy the better units.
This commit is contained in:
parent
6536c9a18e
commit
2ad9038709
@ -309,6 +309,10 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
|
||||
? dynamic_cast<const CGTownInstance *>(dwelling)
|
||||
: nullptr;
|
||||
|
||||
// Keep track of the least valuable slot in the hero's army
|
||||
SlotID leastValuableSlot;
|
||||
int leastValuableStackMarketValue = std::numeric_limits<int>::max();
|
||||
|
||||
for(int i = dwelling->creatures.size() - 1; i >= 0; i--)
|
||||
{
|
||||
auto ci = infoFromDC(dwelling->creatures[i]);
|
||||
@ -322,13 +326,40 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
|
||||
|
||||
if(!ci.count) continue;
|
||||
|
||||
// Calculate the market value of the new stack
|
||||
int newStackMarketValue = ci.creID.toCreature()->getFullRecruitCost().marketValue() * ci.count;
|
||||
|
||||
SlotID dst = hero->getSlotFor(ci.creID);
|
||||
if(!hero->hasStackAtSlot(dst)) //need another new slot for this stack
|
||||
{
|
||||
if(!freeHeroSlots) //no more place for stacks
|
||||
continue;
|
||||
if(!freeHeroSlots) // No free slots; consider replacing
|
||||
{
|
||||
// Check for the least valuable existing stack
|
||||
for (auto& slot : hero->Slots())
|
||||
{
|
||||
if(slot.second->getCreatureID() != CreatureID::NONE)
|
||||
{
|
||||
int currentStackMarketValue =
|
||||
slot.second->getCreatureID().toCreature()->getFullRecruitCost().marketValue() * slot.second->getCount();
|
||||
|
||||
if(currentStackMarketValue < leastValuableStackMarketValue)
|
||||
{
|
||||
leastValuableStackMarketValue = currentStackMarketValue;
|
||||
leastValuableSlot = slot.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decide whether to replace the least valuable stack
|
||||
if(newStackMarketValue <= leastValuableStackMarketValue)
|
||||
{
|
||||
continue; // Skip if the new stack isn't worth replacing
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freeHeroSlots--; //new slot will be occupied
|
||||
}
|
||||
}
|
||||
|
||||
vstd::amin(ci.count, availableRes / ci.creID.toCreature()->getFullRecruitCost()); //max count we can afford
|
||||
|
@ -58,6 +58,29 @@ void BuyArmy::accept(AIGateway * ai)
|
||||
|
||||
if(ci.count)
|
||||
{
|
||||
if (!town->getUpperArmy()->hasStackAtSlot(town->getUpperArmy()->getSlotFor(ci.creID)))
|
||||
{
|
||||
SlotID lowestValueSlot;
|
||||
int lowestValue = std::numeric_limits<int>::max();
|
||||
for (auto slot : town->getUpperArmy()->Slots())
|
||||
{
|
||||
if (slot.second->getCreatureID() != CreatureID::NONE)
|
||||
{
|
||||
int currentStackMarketValue =
|
||||
slot.second->getCreatureID().toCreature()->getFullRecruitCost().marketValue() * slot.second->getCount();
|
||||
|
||||
if (currentStackMarketValue < lowestValue)
|
||||
{
|
||||
lowestValue = currentStackMarketValue;
|
||||
lowestValueSlot = slot.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lowestValueSlot.validSlot())
|
||||
{
|
||||
cb->dismissCreature(town->getUpperArmy(), lowestValueSlot);
|
||||
}
|
||||
}
|
||||
cb->recruitCreatures(town, town->getUpperArmy(), ci.creID, ci.count, ci.level);
|
||||
valueBought += ci.count * ci.creID.toCreature()->getAIValue();
|
||||
}
|
||||
|
@ -374,10 +374,12 @@ HeroExchangeArmy * HeroExchangeMap::tryUpgrade(
|
||||
for(auto & creatureToBuy : buyArmy)
|
||||
{
|
||||
auto targetSlot = target->getSlotFor(creatureToBuy.creID.toCreature());
|
||||
|
||||
target->addToSlot(targetSlot, creatureToBuy.creID, creatureToBuy.count);
|
||||
target->armyCost += creatureToBuy.creID.toCreature()->getFullRecruitCost() * creatureToBuy.count;
|
||||
target->requireBuyArmy = true;
|
||||
if (targetSlot.validSlot())
|
||||
{
|
||||
target->addToSlot(targetSlot, creatureToBuy.creID, creatureToBuy.count);
|
||||
target->armyCost += creatureToBuy.creID.toCreature()->getFullRecruitCost() * creatureToBuy.count;
|
||||
target->requireBuyArmy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user