If the user's DCS directory is not configured correctly this will
degrade by not showing an icon. Otherwise (and typically) we get nicer
looking icons for each theater, and we don't have to make these for each
new map.
This appears to be incompatible with pyinstaller. I get the following
when trying to run the executable generated with pyside6:
```
Traceback (most recent call last):
File "qt_ui\main.py", line 29, in <module>
File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
File "qt_ui\windows\QLiberationWindow.py", line 28, in <module>
File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
File "qt_ui\widgets\map\QLiberationMap.py", line 11, in <module>
ImportError: could not import module 'PySide6.QtPrintSupport'
```
- will not be used for binary read/writes (rb,wb)!
- prevents a bug where units with special characters in the unit name can not be tracked anymore as there will be a name mismatch due to wrong encoding
Many of the schema version increases are just to add new features that
don't render old campaigns obsolete. Convert the version number to a
major/minor format so we can detect the difference between changes that
render old campaigns obsolete (major versions) and new features that
will not work on older builds of Liberation (minor versions).
This is used to provide a UI hint to guide players towards campaigns
that have been updated to work with the current version of the game.
All the campaigns we currently have were made for an unknown version of
the game, so they're all flagged as incompatible.
The version field is not the DCS Liberation version number because the
campaign format may change multiple times during development. Instead
the version number is a monotonically increasing integer that we
increment whenever a game change requires campaign updates.
Defining a campaign using a miz file instead of as JSON has a number of
advantages:
* Much easier for players to mod their campaigns.
* Easier to see the big picture of how objective locations will be laid
out, since every control point can be seen at once.
* No need to associate objective locations to control points explicitly;
the campaign generator can claim objectives for control points based
on distance.
* Easier to create an IADS that performs well.
* Non-random campaigns are easier to make.
The downside is duplication across campaigns, and a less structured data
format for complex objects. The former is annoying if we have to fix a
bug that appears in a dozen campaigns. It's less an annoyance for
needing to start from scratch since the easiest way to create a campaign
will be to copy the "full" campaign for the given theater and prune it.
So far I've implemented control points, base defenses, and front lines.
Still need to add support for non-base defense TGOs.
This currently doesn't do anything for the `radials` property of the
`ControlPoint` because I'm not sure what those are.
Logging before we've made it to the logging setup was causing the root
logger to be permanently configured to the default (warning) log
level, so we weren't getting any info or debug logs any more.
Defer the campaign data load until it is needed rather than doing it
at import time. I've also cleaned up a bit so we only load each
campaign once, rather than re-loading the campaign to create the
theater again after the wizard is finished.