dao::attack
Melee and ranged attacks: reach, the approach to a target, turning to face it.
Declared in dao/Attack.h.
Classes
| Class | |
|---|---|
| Approach | How an attack or an ability would approach its target, given where the two stand now. |
| FacingTurn | The turn an attacker’s command makes to face its target before the blow, computed for now. |
| Ring | One of a creature’s melee rings. |
| RingPlace | One place on a melee ring. |
| Walked | The walk an attacker would make before its attack. |
Enumerations
GiveUp
enum class GiveUp : std::uint8_t
Why an attack’s approach ended without arriving, as the engine decided it.
| Value | |
|---|---|
NoPlace |
the target’s ring had no place for the attacker (COMMAND_FAILED_NO_SPACE_IN_MELEE_RING) |
Timeout |
the command’s own time ran out; only commands given one (the AI’s) have it |
Stuck |
the walker stood still too long, or the path could not be walked |
PathAction |
a door or the like is in the way |
TargetGone |
the target is no more or cannot be attacked, or the attacker was knocked down |
Other |
any other failure the engine answers |
Functions
ApproachOf()
std::optional<Approach> ApproachOf(ObjectId attacker, ObjectId target)
Returns how the attack command would approach a target from where the attacker stands now.
A ring place found now can be taken by other creatures before the attacker gets there, and the attack then fails.
Returns the approach, or nullopt if either object is not a creature
ApproachOf()
std::optional<Approach> ApproachOf(ObjectId user, ObjectId target, std::int32_t ability)
Returns how a creature using an ability on a target would approach it from where it stands now.
The ability’s own Range decides the kind of approach, whatever weapon the user holds. An ability used on its user has no approach, and the answer is in reach. An ability aimed at a point on the ground is not answered. As with an attack, a ring place found now can be gone before the user gets there.
| Parameter | |
|---|---|
ability |
a row of the abilities table (TABLE_ABILITIES_SPELLS) |
Returns the approach, or nullopt if either object is not a creature or ability is not a row of the table
FaceExactly()
bool FaceExactly(ObjectId creature, Vector toward)
Turns a creature to face exactly along a direction on the ground, and sets its movement controller’s facing to match, so the game starts no turn of its own.
Use it to fix FacingTurn::stalls:
if (const auto turn = dao::attack::TurnTo(attacker, target); turn && turn->stalls)
{
dao::attack::FaceExactly(attacker, turn->toward);
}
| Parameter | |
|---|---|
toward |
the direction to face; only x and y are used |
Returns false, changing nothing, if creature is not a creature, toward has no length on the ground, or the creature is walking or turning
IsRanged()
bool IsRanged(ObjectId attacker)
Returns whether a creature’s attack counts as ranged, using the attack command’s own test: true when its main hand holds a staff, a bow or a crossbow.
Returns false also when attacker is not a creature
OnApproachGivesUp()
void OnApproachGivesUp(std::function<void(ObjectId attacker, GiveUp why, std::int32_t status, bool ranged)> observer)
Calls observer when an attack’s approach gives up: the engine’s own verdict, at the update it is reached, before the command ends with it.
It does not fire for an attacker that keeps walking round a ring whose places keep moving: the engine gives no verdict for that. Callbacks run on the game thread.
| Parameter | |
|---|---|
observer |
receives the attacker, why, the engine’s status (the command’s result, such as -5) and whether it was the ranged approach |
RingNeighbours()
std::vector<ObjectId> RingNeighbours(ObjectId target)
Returns the creatures around the target, as the game last recorded them when it refreshed the target’s rings.
Returns their ids, or an empty vector if target is not a creature
Rings()
std::vector<Ring> Rings(ObjectId target)
Returns a target’s melee rings as they are now, without changing them.
The game tries the rings in order of how close the attacker is to each one’s radius. A place is free to an attacker when it is not blocked, is not near-only (unless the attacker stands inside the radius), and no one else holds it.
Returns the rings, or an empty vector if target is not a creature
TurnTo()
std::optional<FacingTurn> TurnTo(ObjectId attacker, ObjectId target)
Computes the turn an attacker’s command would make to face its target now.
When stalls is set, the scripts’ SetFacing commands do not help; FaceExactly does.
Returns the turn, or nullopt if either object is not a creature or the attacker stands on the point it would turn to
Walk()
std::optional<Walked> Walk(ObjectId attacker, ObjectId target)
Computes the walk an attacker would make before attacking, along the game’s path to the approach’s goal.
A melee walk goes to the end of the path; a ranged walk stops where the game would stop it, in range and in sight. A ranged walk that begins in range but out of sight depends on the frame rate in the game. This reckons it at sixty frames a second and the usual combat run, and can be a few metres off.
Returns the walk, or nullopt if either object is not a creature, no path reaches the goal, or the game would give up the attack on the way (no room on the melee ring, or no line of sight in time)
Walk()
std::optional<Walked> Walk(ObjectId user, ObjectId target, std::int32_t ability)
Computes the walk a creature would make before using an ability on a target.
It works like Walk above, with the approach ApproachOf gives for the ability.
| Parameter | |
|---|---|
ability |
a row of the abilities table (TABLE_ABILITIES_SPELLS) |