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/ISpellMechanics.h"
|
||||
#include "../../lib/battle/BattleStateInfoForRetreat.h"
|
||||
#include "../../lib/battle/CObstacleInstance.h"
|
||||
#include "../../lib/CStack.h" // TODO: remove
|
||||
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
||||
// 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))
|
||||
{
|
||||
std::set<BattleHex> moatHexes;
|
||||
std::set<BattleHex> obstacleHexes;
|
||||
|
||||
if(hb.battleGetSiegeLevel() >= BuildingID::CITADEL)
|
||||
{
|
||||
auto townMoat = hb.getDefendedTown()->town->moatHexes;
|
||||
auto insertAffected = [](const CObstacleInstance* spellObst, std::set<BattleHex> obstacleHexes) {
|
||||
auto affectedHexes = spellObst->getAffectedTiles();
|
||||
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.
|
||||
// We just check all available hexes and pick the one closest to the target.
|
||||
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
|
||||
|
||||
auto distance = BattleHex::getDistance(bestNeighbor, hex);
|
||||
|
||||
if(vstd::contains(moatHexes, hex))
|
||||
distance += MOAT_PENALTY;
|
||||
if(vstd::contains(obstacleHexes, hex))
|
||||
distance += NEGATIVE_OBSTACLE_PENALTY;
|
||||
|
||||
return scoreEvaluator.checkPositionBlocksOurStacks(hb, stack, hex) ? BLOCKED_STACK_PENALTY + distance : distance;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user