1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

* Fixed #1417 — infinite loop of AI trying to visit allied creture generator

* Fixed #1401 — battle AI won't attempt attacks with First Aid Tent
This commit is contained in:
Michał W. Urbańczyk 2013-08-25 13:03:29 +00:00
parent 4287b2b7bb
commit 92246a2c17
5 changed files with 53 additions and 2 deletions

View File

@ -112,6 +112,20 @@ BattleAction CBattleAI::activeStack( const CStack * stack )
print("activeStack called for " + stack->nodeName());
if(stack->type->idNumber == CreatureID::CATAPULT)
return useCatapult(stack);
if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON) && stack->hasBonusOfType(Bonus::HEALER))
{
auto healingTargets = cb->battleGetStacks(CBattleInfoEssentials::ONLY_MINE);
std::map<int, const CStack*> woundHpToStack;
for(auto stack : healingTargets)
if(auto woundHp = stack->MaxHealth() - stack->firstHPleft)
woundHpToStack[woundHp] = stack;
if(woundHpToStack.size())
return BattleAction::makeHeal(stack, woundHpToStack.rbegin()->second); //last element of the woundHpToStack is the most wounded stack
else
return BattleAction::makeDefend(stack);
}
if(cb->battleCanCastSpell())
attemptCastingSpell();

View File

@ -113,6 +113,10 @@ BattleAction CStupidAI::activeStack( const CStack * stack )
return attack;
}
else if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON))
{
return BattleAction::makeDefend(stack);
}
for (const CStack *s : cb->battleGetStacks(CBattleCallback::ONLY_ENEMY))
{

View File

@ -3412,10 +3412,32 @@ TSubgoal CGoal::whatToDoToAchieve()
}
std::vector<const CGObjectInstance *> objs; //here we'll gather all dwellings
ai->retreiveVisitableObjs(objs);
ai->retreiveVisitableObjs(objs, true);
erase_if(objs, [&](const CGObjectInstance *obj)
{
return (obj->ID != Obj::CREATURE_GENERATOR1);
if(obj->ID != Obj::CREATURE_GENERATOR1)
return true;
auto relationToOwner = cb->getPlayerRelations(obj->getOwner(), ai->playerID);
if(relationToOwner == PlayerRelations::ALLIES)
return true;
//Use flagged dwellings only when there are available creatures that we can afford
if(relationToOwner == PlayerRelations::SAME_PLAYER)
{
auto dwelling = dynamic_cast<const CGDwelling*>(obj);
for(auto & creLevel : dwelling->creatures)
{
if(creLevel.first)
{
auto creature = VLC->creh->creatures[creLevel.second.front()];
if(cb->getResourceAmount().canAfford(creature->cost))
return false;
}
}
}
return true;
});
if(objs.empty()) //no possible objects, we did eveyrthing already
return CGoal(EXPLORE).sethero(hero);

View File

@ -24,6 +24,16 @@ BattleAction::BattleAction()
additionalInfo = -1;
}
BattleAction BattleAction::makeHeal(const CStack *healer, const CStack *healed)
{
BattleAction ba;
ba.side = !healer->attackerOwned;
ba.actionType = STACK_HEAL;
ba.stackNumber = healer->ID;
ba.destinationTile = healed->position;
return ba;
}
BattleAction BattleAction::makeDefend(const CStack *stack)
{
BattleAction ba;

View File

@ -32,6 +32,7 @@ struct DLL_LINKAGE BattleAction
BattleAction();
static BattleAction makeHeal(const CStack *healer, const CStack *healed);
static BattleAction makeDefend(const CStack *stack);
static BattleAction makeWait(const CStack *stack);
static BattleAction makeMeleeAttack(const CStack *stack, const CStack * attacked, BattleHex attackFrom = BattleHex::INVALID);