Introduce CellLayer and CellRegion abstractions.

The next step towards TS/RA2 tileset support (#5350) is to remove the assumption that map coordinates == cell coordinates (the isometric games have cell axes rotated by 45 degrees to the map).

The existing code required each trait that stored something for each cell to roll its own storage, usually via an inefficient 2D array.  The CellLayer class replaces this duplication with a wrapper around a 1D array, and which can transparently convert between cell and map coordinates (see [pchote:isometric](https://github.com/pchote/OpenRA/commits/isometric) for a sneak-peek at where this is going).

The next problem is enumerating over a set of cells on the screen / in the map / etc.  Looping over the x and y axes won't work, as they are rotated relative to the screen for isometric maps.  The CellRegion class introduces a simpler way of enumerating regions that will work for both perspectives.
This should be `if (s.explored[cell])`