1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
vcmi/AI/Nullkiller/Behaviors/BuyArmyBehavior.cpp
Xilmi fac18d953e Fixed and improved disband-logic
The score for buying army now scales with the cost of that army.
The cost of the units that need to be disbanded in order to hire the new units is subtracted from the army-hiring-score so the AI will prefer hiring armies where the amount of troops to disband is low or non-existent.
Fixed a bug that also disbanded troops when there still were free slots available.
2024-12-13 00:09:10 +01:00

77 lines
1.7 KiB
C++

/*
* BuyArmyBehavior.cpp, 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
*
*/
#include "StdInc.h"
#include "BuyArmyBehavior.h"
#include "../AIGateway.h"
#include "../AIUtility.h"
#include "../Goals/BuyArmy.h"
#include "../Engine/Nullkiller.h"
namespace NKAI
{
using namespace Goals;
std::string BuyArmyBehavior::toString() const
{
return "Buy army";
}
Goals::TGoalVec BuyArmyBehavior::decompose(const Nullkiller * ai) const
{
Goals::TGoalVec tasks;
auto heroes = cb->getHeroesInfo();
if(heroes.empty())
{
return tasks;
}
ai->dangerHitMap->updateHitMap();
for(auto town : cb->getTownsInfo())
{
uint8_t closestThreat = ai->dangerHitMap->getTileThreat(town->visitablePos()).fastestDanger.turn;
if (closestThreat >=2 && ai->buildAnalyzer->isGoldPressureHigh() && !town->hasBuilt(BuildingID::CITY_HALL) && cb->canBuildStructure(town, BuildingID::CITY_HALL) != EBuildingState::FORBIDDEN)
{
return tasks;
}
auto townArmyAvailableToBuy = ai->armyManager->getArmyAvailableToBuyAsCCreatureSet(
town,
ai->getFreeResources());
for(const CGHeroInstance * targetHero : heroes)
{
if(ai->heroManager->getHeroRole(targetHero) == HeroRole::MAIN)
{
auto reinforcement = ai->armyManager->howManyReinforcementsCanGet(
targetHero,
targetHero,
&*townArmyAvailableToBuy);
if(reinforcement)
vstd::amin(reinforcement, ai->armyManager->howManyReinforcementsCanBuy(town->getUpperArmy(), town));
if(reinforcement)
{
tasks.push_back(Goals::sptr(Goals::BuyArmy(town, reinforcement).setpriority(reinforcement)));
}
}
}
}
return tasks;
}
}