Skip to content

Commit

Permalink
accuracy extender tweaks
Browse files Browse the repository at this point in the history
Fixed an issue that caused the AI to incorrectly determine their range with UFOExtender:Accuracy due to using the TU-cost-percentage-value as an absolute TU-value in the calculations. Some units would think they had no range at all and others would only consider their snap-shot instead of their aimed-shot.

Instead of hiding as long as they can't get into good attack-range, enemy units now only hide if none of their teammates can get into good attack-range. As soon as one of their teammates wants to attack, they all will come out and try to get into attacking-position.
  • Loading branch information
Xilmi committed Jan 30, 2023
1 parent e825608 commit 9fe33c9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
30 changes: 25 additions & 5 deletions src/Battlescape/AIModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3089,8 +3089,12 @@ void AIModule::brutalThink(BattleAction* action)
if (brutalValidTarget(target, true))
{
Position furthestAttackPositon = furthestToGoTowards(targetPosition, BattleActionCost(_unit), _allPathFindingNodes, true);
if (Position::distance(furthestAttackPositon, targetPosition) < maxExtenderRangeWith(_unit, getMaxTU(_unit) - tuCostToReachPosition(furthestAttackPositon, _allPathFindingNodes, NULL)))
if (Position::distance(furthestAttackPositon, targetPosition) < maxExtenderRangeWith(_unit, getMaxTU(_unit) - tuCostToReachPosition(furthestAttackPositon, _allPathFindingNodes, NULL)) || inRangeOfAnyFriend(targetPosition))
{
sweepMode = true;
if (_traceAI)
Log(LOG_INFO) << "Target " << target->getPosition() << " is close enough for me or any of my friends to be attacked. Switching to sweep-mode";
}
weKnowRealPosition = true;
}
Position posUnitCouldReach = closestPositionEnemyCouldReach(target);
Expand Down Expand Up @@ -3300,6 +3304,8 @@ void AIModule::brutalThink(BattleAction* action)
else if (!canReachTargetTileWithAttack && !sweepMode && hideAfterPeaking)
needToFlee = true;
bool shouldSkip = false;
if (_traceAI)
Log(LOG_INFO) << "Peak-Mode: " << peakMode << " amInAnyonesFOW: " << amInAnyonesFOW << " iHaveLof: " << iHaveLof << " sweep-mode: "<<sweepMode;
if (!peakMode && !amInAnyonesFOW && !iHaveLof && !sweepMode)
shouldSkip = true;
if ((unitToWalkTo != NULL || (randomScouting && encircleTile)) && !shouldSkip)
Expand Down Expand Up @@ -4997,13 +5003,13 @@ int AIModule::maxExtenderRangeWith(BattleUnit *unit, int tus)
if (!Options::battleUFOExtenderAccuracy)
return weapon->getRules()->getMaxRange();
int highestRangeAvailableWithTUs = 0;
if (weapon->getRules()->getCostAimed().Time > 0 && weapon->getRules()->getCostAimed().Time <= tus)
if (weapon->getRules()->getCostAimed().Time > 0 && unit->getActionTUs(BA_AIMEDSHOT, weapon).Time < tus)
highestRangeAvailableWithTUs = weapon->getRules()->getAimRange();
if (weapon->getRules()->getCostSnap().Time > 0 && weapon->getRules()->getCostSnap().Time <= tus)
if (weapon->getRules()->getCostSnap().Time > 0 && unit->getActionTUs(BA_SNAPSHOT, weapon).Time < tus)
highestRangeAvailableWithTUs = std::max(highestRangeAvailableWithTUs, weapon->getRules()->getSnapRange());
if (weapon->getRules()->getCostAuto().Time > 0 && weapon->getRules()->getCostAuto().Time <= tus)
if (weapon->getRules()->getCostAuto().Time > 0 && unit->getActionTUs(BA_AUTOSHOT, weapon).Time < tus)
highestRangeAvailableWithTUs = std::max(highestRangeAvailableWithTUs, weapon->getRules()->getAutoRange());
if (weapon->getRules()->getCostMelee().Time > 0 && weapon->getRules()->getCostMelee().Time <= tus)
if (weapon->getRules()->getCostMelee().Time > 0 && unit->getActionTUs(BA_HIT, weapon).Time < tus)
highestRangeAvailableWithTUs = std::max(highestRangeAvailableWithTUs, 1);
highestRangeAvailableWithTUs = std::min(highestRangeAvailableWithTUs, weapon->getRules()->getMaxRange());
return highestRangeAvailableWithTUs;
Expand Down Expand Up @@ -5150,4 +5156,18 @@ bool AIModule::projectileMayHarmFriends(Position startPos, Position targetPos)
return false;
}

bool AIModule::inRangeOfAnyFriend(Position pos)
{
for (BattleUnit* ally : *(_save->getUnits()))
{
if (ally->isOut())
continue;
if (ally->getFaction() != _unit->getFaction())
continue;
if(maxExtenderRangeWith(ally, getMaxTU(ally)) > Position::distance(ally->getPosition(), pos))
return true;
}
return false;
}

}
2 changes: 2 additions & 0 deletions src/Battlescape/AIModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ class AIModule
bool isAlly(BattleUnit *unit) const;
/// Checks whether the trajectory of a projectile visits tiles occupied by our allies
bool projectileMayHarmFriends(Position startPos, Position targetPos);
/// Checks whether at least one of our allies is in range for a good attack
bool inRangeOfAnyFriend(Position pos);
};

}

0 comments on commit 9fe33c9

Please sign in to comment.