When the Land activity is run, the aircraft adds influence to the cell so it cannot be used by other actors. When the TakeOff activity runs, it removes the influence so the cell can be used by other actors.
However, when a Carryall picks up a unit, it is told to Land with a vertical offset - it never reaches ground level. When the TakeOff activity runs, it saw the aircraft was above ground level and bailed out. The means the influence is never removed. The cell is now unusable despite the fact the Carryall has left.
To fix this, TakeOff now checks if influence was applied instead of checking if the aircraft is above ground level. If so, we know the Land activity had decided that influence was required, even if the aircraft has not made it to ground level. When TakeOff runs, it will treat it as a proper take off event even though the aircraft is already above ground level. This means influence will be removed and the cell will become accessible as intended.
In ActorMap, we also fix a design flaw where disposed actors where excluded from queries. This caused cache inconsistencies with clients using ActorMap.CellUpdated event to rely on updates. This event will not get called when the actor was disposed, so the downsteam client may have cached the actors at that location, only for them to "change" when the actor is later disposed. This could cause the Locomotor and HierarchicalPathFInder to have inconsistent views of the actors on the map, causing crashes if the inconsistent state broken some internal invariants. The only reason to exclude disposed actors would be to cover up for the actors not being removed properly from the map, which is fixed now aircraft are handled correctly. If ever an actor isn't removed from the actor map, then the caller needs fixing rather than having the actor map exclude it.
If a path search is attempted from a location outside the map, then PathSearch will filter these out to prevent any crashes. The path search will result in no path. However if the location is within the map but on a custom movement layer that the locomotor cannot use, this currently crashes. To fix this we apply a similar filtering logic to ignore any source locations that cannot be used, and so the path search will result in no path for these as well.
Disallow join button without IP address Input
Closes#20234
Trying to join a server with an empty address crashes the game. This fix disallows pressing join button without ip address field input. Updated to reuse search for joinButton vs 2 separate calls to search.
When using the internal AbstractCellForLocalCell method to check if a local cell is reachable, this should return null when the cell is unreachable. If multiple abstract cells were required for that grid, this worked as intended. Only reachable cells are stored in the localCellToAbstractCell mapping. For a grid that required only a single abstract cell, which is the common case, we optimize this to store only the single abstract cell rather than the whole mapping for potentially 100 cells in that grid. However this makes no distinction between the reachable and unreachable cells, so when we check later we get incorrect results. If a cell is unreachable but belongs to the same grid as a single group of reachable cells then we incorrectly report it as reachable. The easiest way to see this incorrect behaviour is when the PathExists is called and can sometimes indicate a path exists when it does not.
To fix this, we now ensure we perform a check to see if the cell is reachable in this single layer case, this allows us to retain the optimization where we don't need to store the whole mapping, but allows us to correctly indicate when cells are unreachable.
Switched the Utility's ExtractTraitDocsCommand output to JSON.
Updated documentation generation to use that and the new Python script to generate the Markdown file, same as the Weapon documentation.
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.
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.
Since bbf5970bc1 we update frozen actors only when required.
In 8339c6843e a regression was fixed where actors created in line of sight would be invisible.
Here, we fix a related regression where cloaked units that are revealed, and then frozen when you move out of line of sight would lack tooltips.
The fix centers around the setting of the Hidden flag. In the old code this used CanBeViewedByPlayer which checks for visibility modifiers and then uses the default visibility. The bug with this code is that when a visibility modifier was not hiding the actor, then we would report the default visibility state instead. However the frozen visibility state applies here which means if the frozen actor is visible, then we consider the actor to be hidden and therefore tooltips will not appear. In the fixed version we only consider the modifiers. This means a visibility modifier such as Cloak can hide the frozen actor tooltips. But otherwise we do not consider the frozen actor to be hidden. This prevents a frozen actor from hiding its own tooltips in some unintended circular logic. Hidden now becomes just a flag to indicate if the visibility modifiers are overriding things, as intended.