Commit Graph

57 Commits

Author SHA1 Message Date
RoosterDragon
b8a71215eb Fix Locomotor IsMoving checks.
The Locomotor IsMoving check was allowing us to consider another actor that moving as not a blocker. However for some reason it also considered the actor trying to path being mobile as sufficient for this check to pass which did not make sense. We remove that extra check and inline the method.

This was a regression from 4a609bbee8 which changed the method from IsMovingInMyDirection (which required the lookup of the mobile trait) to just IsMoving. It should have removed the lookup as not required.

This fixes a crash in HPF which was considered the location as blocked when Locomotor considered it unblocked because the logic was not aligned. Removing this check aligns the logic and resolves the crash.
2022-11-15 15:42:02 +02:00
RoosterDragon
a85ac26367 Pathing considers reachability of source cells consistently.
Using the local pathfinder, you could not find a path to an unreachable destination cell, but it was possible to find a path from an unreachable source cell if there was a reachable cells adjacent to it.

The hierarchical pathfinder did not have this behaviour and considering an unreachable source cell to block attempts to find a path.

Now, we unify the pathfinders to use a consistent behaviour, allowing paths from unreachable source cells to be found.
2022-11-13 19:59:36 +01:00
Gustas
858d782af1 Simplify 'default' expression (IDE0034) 2022-10-11 17:40:05 +02:00
RoosterDragon
2d45e67bca Teach HierarchicalPathFinder about Immovable actors.
By tracking updates on the ActorMap the HierarchicalPathFinder can be aware of actors moving around the map. We track a subset of immovable actors that always block. These actors can be treated as impassable obstacles just like terrain. When a path needs to be found the abstract path will guide the search around this subset of immovable actors just like it can guide the search around impassable terrain. For path searches that were previously imperformant because some immovable actors created a bottleneck that needed to be routed around, these will now be performant instead. Path searches with bottlenecks created by items such as trees, walls and buildings should see a performance improvement. Bottlenecks created by other units will not benefit.

We now maintain two sets of HPFs. One is aware of immovable actors and will be used for path searches that request BlockedByActor.Immovable, BlockedByActor.Stationary and BlockedByActor.All to guide that around the immovable obstacles. The other is aware of terrain only and will be used for searches that request BlockedByActor.None, or if an ignoreActor is provided. A new UI dropdown when using the `/hpf` command will allow switching between the visuals of the two sets.
2022-08-31 23:12:42 +02:00
RoosterDragon
7e7d94ca89 Fix Locomotor CellCache to not consider transit only cells as crushable.
When the UpdateCellBlocking encountered a transit-only cell (the bibs around a building) it would bail from the loop. This would leave the cellCrushablePlayers set to all players. It would update the cell cache and mark that cell as a crushable location.

When CanMoveFreelyInto would later evaluate a cell, it would consider it passable because the crushable check would pass (cellCache.Crushable.Overlaps(actor.Owner.PlayerMask)) rather than because the transit check (otherActor.OccupiesSpace is Building building && building.TransitOnlyCells().Contains(cell)) would pass.

Although this meant the cell was treated as passable in either scenario, it means the cache contained incorrect data. The cell does not contain any crushable actors but the cache would indicate it did. Correcting this means we can rely on the crushability information stored in the cache to be accurate.
2022-08-31 23:12:42 +02:00
RoosterDragon
714b38c97c Add CellCostChanged event to Locomotor.
This event allows subscribers to be made aware when the terrain costs for a cell change.
2022-04-30 15:56:04 +02:00
RoosterDragon
7df39f3522 On Locomotor initialization, update blocked cells.
Prior to ef44c31a72eab61a597cf539ee4b138e94b254fe, Locomotor would be earlier in the trait initialization sequence than SpawnMapActors. Locomotor would assume no actors on the map, and register to update blocked cells when new ones were added. When SpawnMapActors created actors, Locomotor was made aware and kept up-to-date.

After this commit, the initialization sequence was perturbed and SpawnMapActors would initialize first. Locomotor would assume no actors on the map and thus be unaware of these starting units, meaning those starting units would not cause blocking, allowing units to pass through them.

There are two possible fixes. SpawnMapActorsInfo can initialize NotBefore<LocomotorInfo>, enforcing that actors are spawned after locomotor is ready. Or we can remove the assumption in Locomotor that the map starts empty, and have it update blocked cells on startup. The latter seems cleaner, so any other traits that may want to spawn actors don't have to be aware sequencing their initialization with the Locomotor trait, instead things would "just work".
2022-04-24 12:48:52 +02:00
RoosterDragon
2583a7af31 After NotBefore<> support to control initialization order.
Requires<T> means that trait of type T will be initialized first, and asserts that at least one exists. The new NotBefore<T> means that trait of type T will be initialized first, but allows no traits.

This allows traits to control initialization order for optional dependencies. They want to be initialized second so they can rely on the dependencies having been initialized. But if the dependencies are optional then to not throw if none are present.

We apply this to Locomotor which was previously using AddFrameEndTask to work around trait order initialization. This improves the user experience as the initialization is applied whilst the loading screen is still visible, rather than the game starting and creating jank by performing initialization on the first tick.
2022-04-18 10:31:47 +01:00
RoosterDragon
6dc189b7d1 Rearrange various API surfaces related to pathfinding.
The existing APIs surfaces for pathfinding are in a wonky shape. We rearrange various responsibilities to better locations and simplify some abstractions that aren't providing value.

- IPathSearch, BasePathSearch and PathSearch are combined into only PathSearch. Its role is now to run a search space over a graph, maintaining the open queue and evaluating the provided heuristic function. The builder-like methods (WithHeuristic, Reverse, FromPoint, etc) are removed in favour of optional parameters in static creation methods. This removes confusion between the builder-aspect and the search function itself. It also becomes responsible for applying the heuristic weight to the heuristic. This fixes an issue where an externally provided heuristic ignored the weighting adjustment, as previously the weight was baked into the default heuristic only.
- Reduce the IGraph interface to the concepts of nodes and edges. Make it non-generic as it is specifically for pathfinding, and rename to IPathGraph accordingly. This is sufficient for a PathSearch to perform a search over any given IGraph. The various customization options are concrete properties of PathGraph only.
- PathFinder does not need to deal with disposal of the search/graph, that is the caller's responsibility.
- Remove CustomBlock from PathGraph as it was unused.
- Remove FindUnitPathToRange as it was unused.
- Use PathFinder.NoPath as the single helper to represent no/empty paths.
2022-01-30 11:47:52 +01:00
RoosterDragon
f0e24f6d21 Make knowledge of height discontinuities live in Locomotor not PathGraph. 2021-11-21 17:52:12 +01:00
RoosterDragon
dd9d600ef9 Change GetCustomMovementLayers to expose an array, not a dictionary.
As there are few custom movement layers, using an array is good for improving lookup speed. Additionally, we can simplify some code by reserving index 0 of the array for the ground layer. Code that needs to maintain a state for the ground layer and every custom movement layer can now maintain a flat array of state using index 0 for the ground layer, and the the ICustomMovementLayer.Index for the custom movement layer. This removes a lot of ternary statements checking for the ground layer special case.
2021-11-13 12:15:48 +00:00
RoosterDragon
df9398a871 Use named pathfinding constants.
- Rename CostForInvalidCell to PathCostForInvalidPath
- Add MovementCostForUnreachableCell
- Update usages of int.MaxValue and short.Maxvalue to use named constants where relevant.
- Update costs on ICustomMovementLayer to return short, for consistency with costs from Locomotor.
- Rename some methods to distinguish between path/movement cost.
2021-10-10 17:09:38 +02:00
Vapre
9d4d4bb924 Locomotor, PathGraph, trivial optimizations. 2021-10-01 22:21:47 +02:00
Andre Mohren
6810469634 Updated copyright years. 2021-06-29 18:33:21 -05:00
Matthias Mailänder
5a0bcc01a6 Add a lint check for trait placement on hardcoded actor names. 2021-04-11 20:20:00 +02:00
teinarss
d60c05eff3 Change to use pattern matching 2021-03-27 17:29:20 +01:00
teinarss
6b74093c04 Add readonly to structs 2021-03-14 15:17:57 +01:00
teinarss
4a1e4f3e16 Use expression body syntax 2021-03-07 13:00:52 +00:00
teinarss
53b781960c Change FieldLoader.LoadUsing to use nameof 2021-02-28 18:43:51 +01:00
Paul Chote
87790069e9 Add ITerrainInfo interface. 2021-01-11 21:57:55 +01:00
abcdefg30
10f645bf77 Replace usage of the Stances dict by a method call 2020-11-14 11:04:41 +00:00
abcdefg30
eda9966d27 Rename Stance to PlayerRelationship 2020-11-14 11:04:41 +00:00
Paul Chote
5a7dc385a3 Remove obsolete LocomotorInfo caching. 2020-10-18 18:19:56 +02:00
teinarss
27f1a7ab27 Use out var syntax 2020-08-19 18:11:07 +01:00
reaperrr
f58c3aed32 Use OccupiesSpace to save more trait look-ups
This time in Locomotor.IsBlockedBy.
2020-06-02 20:08:34 +02:00
Paul Chote
86f61298e6 Replace ITraitInfo interface with TraitInfo class. 2020-05-21 13:01:04 +02:00
teinarss
b8a5750529 Add map.contains check to CanStayInCell 2020-05-14 20:06:21 +02:00
Paul Chote
9acea56108 Fix pathing across transit-only cells. 2020-03-11 15:40:12 +01:00
Paul Chote
44a7422375 Fix variable naming in Locomotor. 2020-03-11 15:40:12 +01:00
Paul Chote
85a5b6cc17 Fix subcell crusher logic. 2020-02-09 13:18:57 +01:00
abcdefg30
23b3c237b7 Update the year numbers in all license headers to 2020 2020-01-05 17:00:34 +00:00
tovl
434c46058f Disallow units idling on service depot. 2020-01-04 16:04:27 +00:00
abcdefg30
4717e98c48 Add a subCell parameter to IPositionableInfo.CanEnterCell 2019-11-21 14:13:17 +01:00
tovl
d2991247a3 Add separate condition to mobile for disabling nudging only. 2019-10-28 19:35:32 +01:00
tovl
c4d1468f62 Make locomotor cache and nudging logic aware of mobile trait status. 2019-10-28 19:35:32 +01:00
tovl
4a609bbee8 Allow units to give way when path is blocked by oncoming unit. 2019-09-15 17:51:34 +01:00
teinarss
d712bdea85 Locomotor cache should handle custom layers 2019-09-09 21:39:25 +02:00
teinarss
c13fb80257 Fix crushable logic for actors in cell 2019-09-07 13:31:57 +01:00
teinarss
6795fb6967 GetAvailableSubCell should block cells outside the map 2019-09-06 13:32:09 +02:00
teinarss
7544d4b4e6 Cells with Temporary blockers should not exit early in locomotor cache 2019-08-19 19:06:57 +02:00
teinarss
ff1d4ec9ae Fix Out of sync caused by Locomotor cache 2019-08-11 09:53:02 +02:00
teinarss
4193247169 Reset Locomotor cache on world loaded 2019-08-10 17:34:11 +02:00
teinarss
277906c657 Fixes on blocking logic 2019-08-10 17:34:11 +02:00
Tomase
98602cb1cb Change impassable terrain to short.max 2019-08-10 17:34:11 +02:00
Paul Chote
6345655bb1 Add a PerfSample to UpdateCellBlocking. 2019-07-27 17:21:43 +02:00
teinarss
cc84daacea Added cache for cell cost and blocking 2019-07-26 15:54:22 +02:00
teinarss
fb1af81280 Updated TerrainInfo cost to use short 2019-07-26 15:54:22 +02:00
reaperrr
a10af382b4 Add plumbing for notifying traits of movement
More precisely, about start and stop of movement.
2019-03-30 16:24:47 +00:00
abcdefg30
cadbd0d9ab Change the year number in all cs headers from 2018 to 2019 2019-01-26 23:15:21 +01:00
Ectras
93977782a7 Updated Description for TerrainSpeeds
Added check for speed > 0
2018-10-18 18:45:51 +02:00