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:
parent
4287b2b7bb
commit
92246a2c17
@ -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();
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user