130 Commits

Author SHA1 Message Date
Atrik 73f7884b4a Fix oversight from 832501fc9b and b93634fb28
When merging twin formations, the calls to AddMembers()
and RemoveMembers() got inverted. RemoveMembers()
calls UnsetFormationController() on each member, which overwrites
the formation controller reference just set by AddMembers() to
INVALID_ENTITY.
2026-03-23 14:50:12 +01:00
Atrik 6f645fa48f Fix formation ordering oversight
Fixes #8827
2026-03-13 22:59:59 +01:00
Atrik 99e3799883 Fix formation reshuffling after entity rename
When entities in formations were renamed (e.g., during promotion),
the formation would immediately recalculate all member positions,
and queue movement orders causing visible shuffling.

Changes:
1. Transfer existing offsets movement to the renamed entity
   to maintain current formation structure
2. Schedule offset recalculation for the next tick to allow proper
   reordering after all systems have updated

This preserves formation integrity during renames while allowing
eventual optimal position recalculation.

Fixes #8656
2026-02-04 11:05:07 +01:00
Atrik 065ecdbdf8 Implement level class sorting for formations
Add support for multi-level priority sorting of entity classes
in formations.

fixes #7547

Change formation template's default sorting order
using multi-level sorting.

fixes #6873
2026-01-23 17:20:11 +01:00
Vantha b93634fb28 Clean some rebase oversights of 832501fc9b 2026-01-21 19:05:58 +01:00
Dunedan 93ce94655d Use @stylistic/brace-style for eslint
Up to now `eslint-plugin-brace-rules` was used to enforce a common brace
style for JavaScript code. This plugin was however updated the last time
over 9 years ago and will be incompatible with ESLint v10, as that
[removes `context.getSourceCode()`][1], the plugin relies on.

To keep the eslint config working with ESLint v10, this replaces
`eslint-plugin-brace-rules` with the [`@stylistic/brace-style`][2] rule
from `@stylistic/eslint-plugin`, a package we already use.

While `@stylistic/brace-style` doesn't offer an option to format braces
in exactly the same way as before, the "allman" style seems to be the
one closest to the existing code.

[1]: https://eslint.org/blog/2025/11/eslint-v10.0.0-alpha.0-released/#removed-deprecated-rule-context-members
[2]: https://eslint.style/rules/brace-style
2026-01-12 21:33:52 +01:00
Vantha 832501fc9b Remove columnar walking behavior of formations
This behavior is a remnant of the very first implementaion of
formations, when there weren't different types of yet, only
box for fighting and column for walking.
Now that we have different types of selectable formations, however, this
behavior is no longer desired, it also caused a lot of ugly reordering
when giving walk commands. See the issue for more details.

Fixes #8580
2025-12-26 10:54:00 +01:00
Atrik 06c40946eb Simplify calls for moving units into formation
Co-authored-by: @Vantha

Centralize all calls to move units into formation in UnitAI
Allowing additional checks to be done
before calling members to reform formation

Fixes : #8545

Revised Formation methods and when they do call
on reforming formation

Fixes : #7328

Don't order formation members to go to a point
if the controller is stuck
Instead make the controller jump to the member
who is closest to the destination

Fixes : #8543

Correct 'filter(member)' instead of 'filter(ent)'
in GetClosestMemberToPosition (ex GetClosestMember)

Fixes :	#5120
2025-12-18 10:22:27 +01:00
Vantha 7032293207 Add context and comment attributes where useful
Add context and comment attributes to all translated XML elements in the
simulation that can specify any string -- unlike "Rank", which has to be
"Basic", "Advanced", or "Elite".
Most of them aren't used right now, but they can be in the
future and by mods, without touching the schemas again.

Fixes #8540
2025-11-18 11:34:10 +01:00
Ralph Sennhauser 97d76b1495 Fix eslint rule 'prefer-const'
Manual fixes needed for:
eslint --no-config-lookup --rule '"prefer-const": 1'

Ref: #7812
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-05-28 19:34:46 +02:00
Ralph Sennhauser b80c222b96 Fix eslint rule 'prefer-const' in components/[C-F]*
eslint --no-config-lookup --fix --rule '"prefer-const": 1' \
    binaries/data/mods/public/simulation/components/C* \
    binaries/data/mods/public/simulation/components/D* \
    binaries/data/mods/public/simulation/components/E* \
    binaries/data/mods/public/simulation/components/F*

Ref: #7812
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-05-11 14:27:12 +02:00
Stan c278da73d9 Fix issues with the component documentation.
Reported by: @Langbart
Fixes: #6792

Differential Revision: https://code.wildfiregames.com/D4985
This was SVN commit r27638.
2023-05-10 15:55:51 +00:00
Freagarach 3f243b7b50 Fix d1538f7fbd.
Where I forgot to remove the other members when disbanding a formation.

Reported by: @wowgetoffyourcellphone
This was SVN commit r27000.
2022-07-04 05:06:59 +00:00
Freagarach d1538f7fbd Fix formation merging issues.
The motion parameters were calculated even without members, which caused
us to try set a undefined passclass.
Also were members added to previously merged twin-formations. Once
merged (i.e. disbanded), they are moved out of world now.

Some cleanups/deduplication whilst at it.

Reported by: @andy5995 at the forums
(https://wildfiregames.com/forum/topic/71578-feedbacks-from-a26-svn-tests/page/8/#comment-505078)
Differential revision: https://code.wildfiregames.com/D4727
Comments by: @Langbart, @marder
Tested by: @Langbart
Fixes #6580

This was SVN commit r26993.
2022-06-30 06:04:05 +00:00
marder efc2d39372 Fix a comment and rename the formation angle function to better reflect what it does
wrong comment noticed by: @Silier
accepted by : @Freagarach

Differential revision: https://code.wildfiregames.com/D4658
This was SVN commit r26893.
2022-05-20 07:02:22 +00:00
marder dec727ce8e Fix missing parentheses in formation turning angle calculation
The function that is calculating the difference between the two angles
is missing some parentheses.

Didn't notice it sooner as it works in 95% of all cases without them,
but sometimes you can see the formation doing a wrong turn.

reviewed by : @Freagarach

Differential revision: https://code.wildfiregames.com/D4626
This was SVN commit r26874.
2022-05-11 15:22:54 +00:00
Freagarach ed4e07e594 Allow setting the passability class depending on formation members.
Improves pathfinding for the general case (no large entities in a
formation).

Differential revision: https://code.wildfiregames.com/D4605
Comments by: @marder, @Stan, @wraitii
This was SVN commit r26873.
2022-05-11 14:47:16 +00:00
bb 1b0891c566 Handle OutOfWorld for formations
Comments By: Silier
Reviewed By: Freagarach
Differential Revision: D4535
fixes #6448
fixes d9d4deb6ce

This was SVN commit r26651.
2022-03-14 19:51:22 +00:00
bb f69e5c01e8 Fix template type in d9d4deb6ce
This was SVN commit r26521.
2022-03-02 15:55:16 +00:00
bb d9d4deb6ce smoother formation manouvres
Implement a threshold between "turning" the formation and "rearranging"
it.

Patch By: marder
Based on Patch By: alre
Comments By: Freagarach, Stan, Silier
Glanced good By: Freagarach
Differential Revision: D4294
Forum Topic:
https://wildfiregames.com/forum/topic/44848-proposals-for-formations/#comment-452917

This was SVN commit r26520.
2022-03-02 12:54:43 +00:00
Freagarach b778caf146 Move FormationName and Icon from cmpFormation to cmpIdentity.
Reduces duplication across components.
Allows to provide specific names and history for formations.

Differential revision: https://code.wildfiregames.com/D4476
Comments by: @bb, @Stan
Fixes #6400

This was SVN commit r26476.
2022-02-24 06:51:07 +00:00
Freagarach d0549d7994 Use (civ-specific) standards to show formations.
Since we can have battalion-style formations (a70a20fd42), it is nice to
show a TW-style banner for them.
Code adapted from @Silier at
https://wildfiregames.com/forum/topic/68008-formation-standards-total-war-style-flags-over-battalions/.

Differential revision: https://code.wildfiregames.com/D4467
Comments by: @asterix, @Silier
Refs. #4545

This was SVN commit r26326.
2022-02-09 06:54:12 +00:00
bb acc780bcbb Add accelerations in unit movement.
This helps preventing arrow dodging.

Differential Revision: D3200
Reviewed By: Freagarach
Comments By: wraitii, vladislav, Palaxin, Stan
refs: #5106

This was SVN commit r25953.
2021-10-09 21:31:11 +00:00
Freagarach 56f5cb9e62 Use transform for changing a formation template.
As noted on the forums by @Ceres
(https://wildfiregames.com/forum/topic/44848-proposals-for-formations/?do=findComment&comment=453840)
formations change orientation when changing their template.
This uses the transform helper to change the template of the formation,
which apparently also fixes the rotation issue.

With the notion that a different design of transform is preferential
(P46).

Differential revision: https://code.wildfiregames.com/D4272
Comments by: @Angen, @bb, @Ceres, @wraitii
Tested by: @Ceres
This was SVN commit r25949.
2021-10-03 06:26:28 +00:00
Freagarach 65cd29696d Don't stop gathering after starting by autocontinue when in a formation.
FinishOrder called SetWaitingOnController, although the order
(constructing) had pushed another order (gather).
This is done now by telling we finished the order only when really idle.

This seems to boil down to the question: If we issued an order to a
formation, and its members have wandered off (imagine attacking an
entity and our members have finished the initial target but attack
nearby ones) do we want the whole formation to continue attacking or
execute the next order.

Also fixes reforming whilst attacking when an attack order was issued by
the player.

Reported by: @Langbart at https://code.wildfiregames.com/D2175#182343
Differential revision: https://code.wildfiregames.com/D4282
Tested by: @Langbart
This was SVN commit r25947.
2021-10-03 05:59:54 +00:00
wraitii e94e1f1fcf Better fix for formation waltzing, revert 5d96346ac5.
5d96346ac5 proved unsufficient to fix formation 'waltzing'. This is a
better fix, which makes sure units actually try to reach their
designated offset in the first place.
Further, it removes code that recalculated offsets un-necessarily, which
led to an issue with "sloppy" formations such as open and closed orders.

Fixes #5997

Differential Revision: https://code.wildfiregames.com/D3543
This was SVN commit r24865.
2021-02-10 09:59:39 +00:00
wraitii c57a4d90a1 Fix segfault from a formation infinite loop.
#5932 reported a segfault. The direct cause is an infinite loop in
Order.Repair in a formation controller.
There are multiple issues at play here, but the core problem is that the
controller has been marked for destruction, but remains alive over the
turn and UnitAI timers can fire. This leads to an unexpected state that
triggers an infinite loop.

To avoid this problem, immediately switch the formation controller to a
clean state when it's being disbanded.

Fixes #5932

Differential Revision: https://code.wildfiregames.com/D3410
This was SVN commit r24688.
2021-01-18 18:29:40 +00:00
wraitii 59d0885d68 Allow picking a default formation for walk (and walk-like) orders.
This allows choosing a "default formation", which is activated
automatically for units given walk orders (and attack-walk etc.).
Conversely, units in formation that are given a gather/build/... order
are taken out of formation and given the order individually.
The default formation can be selected by right-clicking on any formation
icon.

This leverages formations for walking, where they are quite efficient
(in fact, perhaps too efficient), while circumventing issues with
various orders.

Choosing the "null formation" as the default formation de-activates the
behaviour entirely, and plays out exactly like SVN.

This makes it possible to queue a formation-order then a
noformation-order (i.e. walk then repair), though the behaviour isn't
very flexible.

For modders, it should be relatively easy to change the setup for each
order, and/or to force deactivating/activating formations in general.

Tested by: Freagarach, Angen
Refs #3479, #1791.
Makes #3478 mostly invalid.

Differential Revision: https://code.wildfiregames.com/D2764
This was SVN commit r24480.
2020-12-31 10:04:58 +00:00
bb 42c70cd508 Let units take time actual time for turning while moving. This limits the possibility of "dancing" (making short moves to avoid being hit by arrows) beyond only patrolling.
Reviewed By: wraitii
Gameplay Tests By: FeldFeld
Comments By: Freagarach, Angen
Differential Revision: D2837
refs: #5106

This was SVN commit r24415.
2020-12-17 22:54:14 +00:00
bb 7335fc793a sloppyness → sloppiness
Patch By: Nescio
Differential Revision: D3003
This was SVN commit r24040.
2020-09-14 16:55:14 +00:00
Angen 1f5766079d Clean Formation.js
var -> let
comments - capital leters, dots
a:help - dots
spaces

Differential Revision: https://code.wildfiregames.com/D3001
Comments by: Nescio, Jenkins
This was SVN commit r24024.
2020-09-06 14:08:56 +00:00
Angen f074096cf3 Use average rotation of members when giving formation controller into the world
Differential revision: https://code.wildfiregames.com/D2890
Reviewed by: wraitii
Comments by: Freagarach
This was SVN commit r23899.
2020-07-26 18:22:26 +00:00
wraitii a7da40ac2f Fix formations reshaping incorrectly & related issues.
Formation were reshaping in cases where they should not (such as when
the controller is waiting on members).
This made them look very odd for some orders.

This also cleans up held positions for formations somewhat.

Also:
- ed54ad3486 fixed units not facing correctly after a formation-walk.
The fix is correct, but we can actually make it slightly more
self-contained by moving everything in `leave`. Also clarify comments.
- This fixes some very broken code in 4ca448a686 in
FORMATIONMEMBER.WALKING.MovementUpdate. It never errored because
formation controllers weren't moved out of the world before.

Reviewed By: Angen
Fixes #5443

Differential Revision: https://code.wildfiregames.com/D2763
This was SVN commit r23806.
2020-07-07 10:24:58 +00:00
wraitii feda708d5d Fix formations not queueing orders properly.
Formation controllers were not always waiting on their members correctly
because the "finishedOrder" check was being reset in the wrong place.
This happened particularly with queued orders.

This merges the "finishedOrder" and the "InPosition" logic.

Reported by: elexis
Based on a patch by: Freagarach
Tested by: Freagarach
Reviewed By: Angen
Fixes #3274

Differential Revision: https://code.wildfiregames.com/D2702
This was SVN commit r23744.
2020-06-06 16:07:01 +00:00
Angen 9f6d44feb8 Remove some variables from serialisation and update this.animations name to reflect what it actually holds [Formations.js]
Needs ReviewPublic

Differential Revision: https://code.wildfiregames.com/D2707
Comments by: elexis, Stan, wraitii, bb
Remove variables were not needed to be serialised or stored inside
component
Create `variablesToSerialize` to hold list of variables, that need to be
Serialized.
Rename `this.template.Animations` to `this.template.AnimationVariants`
(and anything related) as it does not hold animation names but names of
animation variants what is misleading.
Do not create timer when deserializing as that would cause oos and timer
already exists.
this.Init has to be called from Deserialize because it is not called by
default

This was SVN commit r23694.
2020-05-23 13:03:34 +00:00
Angen 23111ab427 Actually do not use sorting order for forced columnar formation
f19a8d6b41 moved sorting classes to template and according to lines 561
and 574 in that commit, it was intended to not use sorting in case of
forced columnar formation.

Fixing oversight at lines 660 and 662 in that commit by removing this.
word so cavalry will be put to the front always.

Noticed in D2707 after @elexis mentioned behaviour change on unused
variable.

Differential Revision: https://code.wildfiregames.com/D2711
This was SVN commit r23613.
2020-05-01 09:44:14 +00:00
Angen 67a4c18c74 Disband formation instead destroying
Fix missed line change in 9c2e9d7893 when rebasing D1462

This was SVN commit r23454.
2020-01-28 19:31:04 +00:00
Angen 9c2e9d7893 Enforce formation required member count
Disband formation with less memebers than required.
Do not allow one member in formation.
Show only formations entities actually are allowed to form. (do not show
wedge for infantry)

Differential Revision: https://code.wildfiregames.com/D1462
Fixes: #5119
Comments by: elexis, bb, temple, Stan, Freagarach
This was SVN commit r23450.
2020-01-27 17:49:06 +00:00
Angen 163d710952 Update auras when a formation member renames
Reported on forum:
https://wildfiregames.com/forum/index.php?/topic/25196-when-unit-levels-up-he-loses-armor-bonus-from-athens-hero/

Relevant diff: https://code.wildfiregames.com/D997

Differential Revision: https://code.wildfiregames.com/D1727
Patch by: @Freagarach
This was SVN commit r23408.
2020-01-17 09:32:52 +00:00
Angen d12e5a9df0 Do not allow to override formation animation variants chosen when walking and define remaining combat variants
Fixing oversight from e7ab2c9b3f. Switching to columnar formation,
adding or removing formation members does not reset animation variant
passed by last order.

Also adding remaining combat variants for formationwalk.

Differential Revision: https://code.wildfiregames.com/D2556
This was SVN commit r23359.
2020-01-10 10:03:15 +00:00
Angen e7ab2c9b3f Support order defined animation variants for formation
Allows to pass variant name when moving units to formation used by
UnitAi when formation is moving. That variant will be passed as
parameter of order FormationWalk so formationmember can set requested
variant.

This passed variant will be ignored if formation defines own variant
based on position of member.

When none of above is true, that means nor formation nor order defines
variant, member will fallback to default variant in order to show
carried resources if has some what makes it more consistant with
animation variants used in individual state.

Differential Revision: https://code.wildfiregames.com/D2550
This was SVN commit r23352.
2020-01-09 20:53:13 +00:00
Angen ed54ad3486 Do not face point after movement for formation walk
After formation member ends walking, he tries to face target point.
However that eliminates rotation set by SetInPosition from formation
component. Partly fixed in 9d0b4db973 with setting correct rotation in
idle state, but one could still notice that there is glitch when unit
does quick turn to target point and then back. However that solution
would be still required if logic in SetInPosition would not be changed
to always set correct rotation. Another alternative would be to unset
unit at position with every walking order but that would have the same
effect and this is just more performance friendly to not splice member
from position every time.

Notice that information from inPosition is currently not used, so that
change in it is not braking anything.

This was SVN commit r23346.
2020-01-08 21:37:19 +00:00
Angen 425fb6d93a Fix units not reentering FORMATIONMEMBER.IDLE when they are promoted or stopped
When unit is idle in formation and promoted, it enters INDIVIDUAL.IDLE
incorrectly.
When unit is moving as part of formation and formation is ordered to
stop, unit enters INDIVIDUAL.IDLE but should keep FORMATIONMEMBER.IDLE.

Differential Revision: https://code.wildfiregames.com/D2468
This was SVN commit r23236.
2019-12-14 15:47:26 +00:00
Angen a7b7486dea Set correct animation variant for formation member when starts to move
Formation variants for members are not set correctly once they move
because their ranks changes but variants do not get updated.

This was SVN commit r23233.
2019-12-14 10:10:26 +00:00
Angen 3a79451638 ComputeMotionParameters correctly when formation member is added or removed
As noticed by @bb in
https://code.wildfiregames.com/D1727?id=7276#inline-38148 and found
issue in 4ee4f16793#inline-4563 ComputeMotionParameters is not called
correctly.

One problem is when merging twinformations, addMembers does not update
speed, so if one formation contains slowest unit and it is merged to
formation which does not, merged formation will move faster than it
should, the same problem applies if unit is added calling function from
outside of component.

Another problem is when from formation is removed slowest unit and has
rearrange set to false. Having speed computation after rearrange check
means formation is not going to move faster if slowest member is removed
by player or killed (but it will if player recreates formation manually)

Differential Revision: https://code.wildfiregames.com/D2449
This was SVN commit r23223.
2019-12-08 13:59:33 +00:00
wraitii e16c4c4800 Add a system component to handle stat modifiers, make technologies and auras use this common interface.
The ModifiersManager system component provides an interface to add and
remove modifiers, and get modified stats.
The goal is to merge all the different stat-modifying systems 0 A.D. has
implemented over the years.
This commit makes technologies and auras use ModifiersManager. Some
cheats and AI bonuses also have a similar stat-modifying effect that
have not yet been updated.

Further, this system component makes it possible for e.g. triggers to
easily add modifiers, enabling the writing of Castle Blood Automatic,
RPG or Tower Defense maps without the need for mods or hacks.

The 'Modifier' name was preferred over 'Modification' as it is shorter
and more readable, along with the logic that 'modifiers' store
'modifications' and this stores modifiers. Renaming of other functions
and classes has been left for future work for now.

Internally, this uses a JS data structure. If performance issues arise
with it in the future, this data structure or the whole component could
be moved to C++.
The performance has been tested to be about as fast as the current
implementations (and specifically much faster for global auras with no
icons). Testing showed that sending value modification messages was by
far the slowest part.

Comments by: leper, Stan, elexis
Differential Revision: https://code.wildfiregames.com/D274
This was SVN commit r22767.
2019-08-24 07:37:07 +00:00
wraitii c03abd1e92 UnitMotion cleanup - remove dead code, add a common path for MoveTo functions, rename BeginPathing, move functions around for better readability.
BeginPathing renamed to ComputePathToGoal, as that is what this function
does.
IsMoving renamed to IsMoveRequested, as the function returns true when
the unit has a move request going on, not when it is actually moving
across the map, which was misleading.

UpdateMovementState's implementation moved closer to where it is used.

PathIsShort and WAYPOINT_ADVANCE_MAX are currently unused, thus deleted.

Differential Revision: https://code.wildfiregames.com/D2067
This was SVN commit r22568.
2019-07-28 10:51:12 +00:00
wraitii 7cf6244110 Formation animation refactor - use animation variants instead of special move override.
The animation overrides are a little awkward. Instead, use animation
variants, which allow defining different animations (and props and such)
easily for different units in a formation.
This lets us clean up the special C++ code to override the walk
animations.

It continues the work started by 8446b92f1b.

Original Patch By: temple
Differential Revision: https://code.wildfiregames.com/D1337
This was SVN commit r22442.
2019-07-08 18:23:44 +00:00
wraitii 859d96fba5 UnitMotion - improve variable names and reuse a duplicated function (cleanup def47cb7ae)
This:
 - cleans up a code duplication and clarifies the intent.
 - reorders things around for clarity
 - improves variable names.

Commented By: elexis
Differential Revision: https://code.wildfiregames.com/D1840
This was SVN commit r22277.
2019-05-13 16:47:51 +00:00
wraitii def47cb7ae Change Run Speed into a Run multiplier.
This changes running speed into a running multiplier (of walk speed).

The advantage is that it simplifies code since you can setup a default
run multiplier at the template level and it'll work for all subsequent
templates, and technologies cannot forget to change it. It makes
specialised unit templates easier to maintain, too.

Formations have a 100 run multiplier which effectively sets their
maximal walking speed at 100

Reviewed By: bb, O2 JS Simulation
Differential Revision: https://code.wildfiregames.com/D438
This was SVN commit r22197.
2019-04-19 10:04:50 +00:00