The priority list was guiding the purchase decision which largely meant
that this was working correctly, but there were suboptimal cases where
the list was being taken in FIFO order by purchased type. This fixes the
search to be locally optimal, although this does still mean that a worse
but closer aircraft will be chosen over a better but slightly farther
away aircraft. We'd need to have a quality vs distance rating to do
better.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/755
We were accidentally iterating over the faction list and checking it
against the priority list rather than the other way around, so the
faction's aircraft list was being used for purchase priority rather than
the actual priority list in the game.
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).
Loadout selection no longer has two (disagreeing) implementations. What
the UI shows is now what the miz will have.
We now store the chosen layout in the Flight *always*, not just for
custom loadouts. This means that we do loadout lookups at the start of
each turn, but the data is cached in pydcs.
Era-specific loadout degradation is still done at generation (and
presentation) time. This is so that players can toggle that option and
have it affect the *current* turn, rather than the next one.
Many of the aircraft that we use for DEAD are not actually capable of
the SEAD task in DCS, so they were being loaded as some other task type,
usually one that doesn't support Attack Group, which made them lose
their waypoint actions and do nothing.
This switches them to using CAS which supports a superset of the SEAD
capable aircraft.
I've also audited the SEAD/DEAD lists. The F-117 was removed because it
is not capable of Attack Group *at all*, and all the non-SEAD aircraft
that are capable of ground attack moved from SEAD to DEAD.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1086
This is a pretty janky system until we get add context menu support. For
now the destination is set by dragging the CV marker and cleared by
right clicking the destination marker. Once we have a context menu a
context action will begin setting the destination the way it did in the
old UI, and the destination marker will be draggable.
These are an implementation quirk, and passing them to the UI just means
that we put TGO pins on top of the CP, which makes the base menu
unopenable.
In the old UI we avoided this by not drawing anything that was
`for_airbase`, but now that we can zoom in further we're drawing base
defenses.
This PR allows campaign creators to incorporate map objects (referred to as Scenery in the code) into their Liberation campaign.
Map objects are defined using white trigger zones created by right clicking on scenery and clicking `assign as...`. Objective groups are defined by creating a blue TriggerZone surrounding the centers of the white trigger zones. The type of objective is determined by the campaign creator, assigning the value of the first property of the blue TriggerZone with the objective type.
Map objects maintain their visually dead state by assigning a `Mission Start` `Scenery Object Dead` trigger to the trigger zone. It is important for the Liberation generated TriggerZone to be as small as possible so that no other scenery is marked dead by DCS.
TriggerZones are hidden during gameplay (DCS behavior. I don't know if it's possible to turn that off.) TriggerZones are visible in the mission editor and mission planner however. If a player is using an older plane, it is important for them to remember where the target is.
In the mission planner, the trigger zones' will be blue or red depending on which faction the map objects belong to.
Inherent Resolve campaign has been modified to integrate scenery objects.
### **Limitations:**
- Objective definitions (Any Blue TriggerZones) in campaign definition cannot overlap.
- Map object deaths in `state.json` is tracking integers. You won't know what died until debriefing.
- No images for the various buildings. In theory it can be done, but an unreasonable amount of work.
- Every blue trigger zone must have a unique name. (If you let DCS auto increment the names this is not a concern.
- No output to screen when scenery object is dead. You can see the building drawn as dead in the F10 map though.
### **Pictures:**
An objective:

How the objective looks once in the mission planner/editor. This objective belongs to the enemy faction:

To avoid confusion, use only the aircraft list for the purchasable
aircraft. This fix also caught a faction's Tu-142 that was not actually
purchasable. Invalid aircraft in the faction aircraft list will now
raise an error.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1074
https://bugreports.qt.io/browse/PYSIDE-1426
For whatever reason this only shows up in packaged builds for us, and
also the recommended workaround of using a member property rather than a
decorated method does not work for us.
Until PySide2 5.15.3 (or later) is released, we need to use a named
signal for every property we expose.