mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
BattleAI: check negative obstacles instead of moat.
This will work for fire walls too (and if someone will summon elementals after placing land mines). But will not work for Tower's landmines.
This commit is contained in:
parent
1100bc7a5b
commit
6c5f5dba75
@ -19,6 +19,7 @@
|
|||||||
#include "../../lib/spells/CSpellHandler.h"
|
#include "../../lib/spells/CSpellHandler.h"
|
||||||
#include "../../lib/spells/ISpellMechanics.h"
|
#include "../../lib/spells/ISpellMechanics.h"
|
||||||
#include "../../lib/battle/BattleStateInfoForRetreat.h"
|
#include "../../lib/battle/BattleStateInfoForRetreat.h"
|
||||||
|
#include "../../lib/battle/CObstacleInstance.h"
|
||||||
#include "../../lib/CStack.h" // TODO: remove
|
#include "../../lib/CStack.h" // TODO: remove
|
||||||
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
||||||
// CUnitState should be private and CStack should be removed completely
|
// CUnitState should be private and CStack should be removed completely
|
||||||
@ -309,25 +310,38 @@ BattleAction CBattleAI::goTowardsNearest(const CStack * stack, std::vector<Battl
|
|||||||
|
|
||||||
if(stack->hasBonusOfType(Bonus::FLYING))
|
if(stack->hasBonusOfType(Bonus::FLYING))
|
||||||
{
|
{
|
||||||
std::set<BattleHex> moatHexes;
|
std::set<BattleHex> obstacleHexes;
|
||||||
|
|
||||||
if(hb.battleGetSiegeLevel() >= BuildingID::CITADEL)
|
auto insertAffected = [](const CObstacleInstance* spellObst, std::set<BattleHex> obstacleHexes) {
|
||||||
{
|
auto affectedHexes = spellObst->getAffectedTiles();
|
||||||
auto townMoat = hb.getDefendedTown()->town->moatHexes;
|
obstacleHexes.insert(affectedHexes.cbegin(), affectedHexes.cend());
|
||||||
|
};
|
||||||
|
|
||||||
moatHexes = std::set<BattleHex>(townMoat.begin(), townMoat.end());
|
const auto & obstacles = hb.battleGetAllObstacles();
|
||||||
|
|
||||||
|
for (const auto & obst: obstacles) {
|
||||||
|
const auto * spellObst = dynamic_cast<const SpellCreatedObstacle*>(obst.get());
|
||||||
|
|
||||||
|
if(spellObst && spellObst->trigger)
|
||||||
|
{
|
||||||
|
auto triggerAbility = VLC->spells()->getById(SpellID(spellObst->ID));
|
||||||
|
auto triggerIsNegative = triggerAbility->isNegative() || triggerAbility->isDamage();
|
||||||
|
|
||||||
|
if(triggerIsNegative)
|
||||||
|
insertAffected(spellObst, obstacleHexes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Flying stack doesn't go hex by hex, so we can't backtrack using predecessors.
|
// Flying stack doesn't go hex by hex, so we can't backtrack using predecessors.
|
||||||
// We just check all available hexes and pick the one closest to the target.
|
// We just check all available hexes and pick the one closest to the target.
|
||||||
auto nearestAvailableHex = vstd::minElementByFun(avHexes, [&](BattleHex hex) -> int
|
auto nearestAvailableHex = vstd::minElementByFun(avHexes, [&](BattleHex hex) -> int
|
||||||
{
|
{
|
||||||
const int MOAT_PENALTY = 100; // avoid landing on moat
|
const int NEGATIVE_OBSTACLE_PENALTY = 100; // avoid landing on negative obstacle (moat, fire wall, etc)
|
||||||
const int BLOCKED_STACK_PENALTY = 100; // avoid landing on moat
|
const int BLOCKED_STACK_PENALTY = 100; // avoid landing on moat
|
||||||
|
|
||||||
auto distance = BattleHex::getDistance(bestNeighbor, hex);
|
auto distance = BattleHex::getDistance(bestNeighbor, hex);
|
||||||
|
|
||||||
if(vstd::contains(moatHexes, hex))
|
if(vstd::contains(obstacleHexes, hex))
|
||||||
distance += MOAT_PENALTY;
|
distance += NEGATIVE_OBSTACLE_PENALTY;
|
||||||
|
|
||||||
return scoreEvaluator.checkPositionBlocksOurStacks(hb, stack, hex) ? BLOCKED_STACK_PENALTY + distance : distance;
|
return scoreEvaluator.checkPositionBlocksOurStacks(hb, stack, hex) ? BLOCKED_STACK_PENALTY + distance : distance;
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user