Change terrain type from string based dictionaries to arrays

This replaces the string based dictionary lookups with arrays that are accessed by index. It partially follows the suggestions in #4596. The main difference being that it doesn't create bit fields, mainly because we want more info per terrain type than a boolean pass/can't pass (we store movement cost and speed).

It's difficult to test exactly how this performs but I see a 10+% speedup in movement/pathfinding related activities, on average.

I've tested several replays recorded on the current bleed with this and they don't desync, crash, or anything else strange so it seems this doesn't break anything obvious.

~~It requires #5447 or it will complain about invalid terrain templates and abort.~~ (edit: merged)

Please test & discuss. I plan to look for more cases that can be optimized and build on this PR so I'd like to know if the changes here are in the right direction.
You can avoid storing this for every TileTemplate by passing the TileSet into `LoadTiles()` and `Save()`.