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.
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
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
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
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
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
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
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.
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.
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.
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.
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.
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.
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.
#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.
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.
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.
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.
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.
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.
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.
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/D1462Fixes: #5119
Comments by: elexis, bb, temple, Stan, Freagarach
This was SVN commit r23450.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.