The OrderBy overload that takes an int generating key selector is faster than the one that requires a custom comparer. We extract a function from the ScreenZPosition function that determines the Z position of a WPos with an offset, but does not account for the tileset height. For the ordering function this is fine as only the relative magnitude of the comparison keys matter, so we don't need to spend time adjusting for the tileset height, as that won't affect the sort.
Automatically formatted all files via VS. This generally corrects indentation, removes trailing whitespace and corrects misplaced tabs or spaces. Manually tweaked a few files where required.
The TraitsImplementing<T> performs a dictionary lookup to match up its generic type parameter with the right trait collection. Since actors are rendered so much, it is useful to cache this result to avoid looking it up repeatedly.
...which caused the headers to still be visible when the options bin was open.
Also moves the "Map Options" title to the same place the headers occupy,
to above the options bin.
Avoid allocating memory and resources for graphical elements that will never be drawn when starting a dedicated server. This reduces the server memory footprint by approx 17 MiB.
The bin partitioning in ActorMap worked by dividing the map up into a few chunks of cells, each of which would contain some actors. Unfortunately, the bins were accessed directly in world coordinates which are on a scale 1024x greater than cell coordinates. This lead to all actors being placed into the bottom right bin. When checking for actors in a box, only this bottom right bin would be iterated for actors. Thanks to the fact this bin indeed contained all the actors, some clamps on the input ranges and filtering required per bin anyway, this actually returned correct results. Effectively, it was as if there was no spatial partitioning at all.
Not surprisingly however, this is fairly inefficient. By correcting the spatial partitioning to actually partition we see a 7x speedup in ActorsInBox on the RA shellmap.
The region covered by map.Cells may not cover the whole map size, but we need the whole cache initialized so it can be used correctly when a different map is used, because that map may have the same size but a different offset which means a different region is covered.