Since 38b33b0484, the range check happened in CanAttack, however the
check there is too permissive.
This meant it was possible for towers to attack certain targets outside
their actual range, depending on the query results and unit AI focus
fire.
Following 38b33b0484, units on aggressive stance no longer chase beyond
their own vision, including on player-forced orders. This fixes that
regression.
(Note that approaching and chasing are a bit inconsistent).
38b33b0484 partly rewrote GetQueryRange but ended up with two
bugs/regressions:
- in standGround, melee units used an effective max-range of 0 instead
of their melee attack max range
- units that have a min-range did not see units within their min-range
(even though they can move).
This fixes these issues and rewrite the function in a simpler fashion
for readability.
38b33b0484 added a visibility filter to TestEntityQuery, active whenever
a query sets preferMirages - which UnitAI's attack range query does.
However, those filters do not work for Gaia, and so the query never
returned anything.
It was only a wrapper around `std::string::substr`. The interface
matches the usecase more. In some places it's better to use
`std::string::ends_with`.
In most places `fmt::format` is used because it's locale indidendant.
For the user reporter the locale dependant form of `fmt::format` is used
because it's shown to the user.
When temporarly leaving a multiplayer game the "I will return" button
didn't work. This was because there was no valid `closeSession`.
Since it requires accessing `this` the function can't be an arrow
function anymore.
Introduced in 2520c45220Fixes: #9086
GATHER.FINDINGNEWTARGET inserts a ReturnResource order ahead of the
next queued order when the unit is still carrying resources, but
skips doing so if the next order already returns those resources.
Unfortunately, the check was incorrectly written, missing a `.type`.
This meant we always added a fresh order.
Units could then sometimes return resources to the closest dropsites,
then move to the actually queued dropsite, which could lead to
unexpected pathing.
Introduced in 0dda3b579c where the feature was added.
The cache invalidation was incorrectly using forEach, which failed to invalidate the cache.
This never actually caused a bug because the game currently does not silently swap active player entities.
In `CCmpObstruction::ResolveFoundationCollisions`, the nested loop
intended to assign a persistent control group to colliding normal
entities was incorrectly iterating over `normalEnts` instead of
`persistentEnts`.
This caused the function to attempt to clobber default control groups
with other non-persistent groups, completely bypassing the intended
`ControlPersist` logic.
This patch fixes the inner loop to correctly iterate over
`persistentEnts`, ensuring foundations properly inherit persistent
control groups.
Fixes: 9ae084519f
Adds baseRange parameter to parabolic queries for combined
2D + parabolic detection. StandGround and Chase stances now
use attack range (parabolic) with vision as baseRange, allowing
units to attack enemies visible through friendly vision.
Buildings benefit as well via BuildingAI.
Introduce CanEverReachTarget in the Attack component to check whether
a target is geometrically reachable at all, accounting for height
offsets and turreted units inside buildings.
For non-parabolic attacks (e.g. melee), a simple 3D distance check
from the closest approach point is used.
For parabolic attacks (e.g. ranged), the parabolic range formula
is used to determine if the height difference is surmountable
from the closest horizontal distance to the target.
Add GetClosestApproachDistanceToTurretPoint to TurretHolder
to estimate the minimum horizontal distance to a turret point,
using its local offset and the holder's obstruction size.
Passable buildings are not considered obstacles.
Fixes units on the ground trying to attack unreachable units on walls
or towers when the projectile's arc cannot reach the required height.
Wraps RangeManager.GetEffectiveParabolicRange for unified range
resolution. Maintains symmetry with GetRange(), improves readability,
and consistently translates NEVER_IN_RANGE.
Simplifies callers in UnitAI and Attack.
StandGround units now use parabolic range queries to detect enemies,
accounting for terrain elevation and height offsets. This ensures
units on hills or when 'turreted', can detect enemies
that are in parabolic range but outside flat range.
Previously, StandGround detection used flat circular queries,
causing units to miss enemies in their elevation-buffed range.
Other stances are unaffected since they chase targets anyway.
The parabolic range formula in GetEffectiveParabolicRange was only
computating height differences from manual HeightOffset values,
completely ignoring actual terrain elevation.
This meant units on hills received no tactical advantage
despite the UI stat tooltip correctly showing extended ranges.
Fixes#8889
It was removed in dee2b73c7d since it wasn't noticed that it referred to
the number in the top panel. Adding the number should make this more
clear. The color is only applied to the number instead of the whole line
so that it's harder to mistake it with just some fancy formatting.
Fixes: #7851
Split mouse wheel scroll handling into horizontal and vertical. Keep
vertical scroll for zooming and use horizontal to rotate around the y
axis replicating the behaviour of the main game.
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
As the latest version of pre-commit is broken right now
(https://github.com/pre-commit/pre-commit/issues/3737) and the official
pre-commit Github action doesn't allow specifying an older pre-commit
version to use, this inlines the logic of the pre-commit action into our
action.