Updated the F4.py pydcs extension to match the updated F-4B/C mod and
reworked the standard payloads to add "clean" to new F-4B pylons 11 and
12.
This includes a workaround to allow Liberation to use the new VSN F-4B
weapons with combined 2x Aim-9js on pylons 3 and 9 underslung with bombs
on ters on new pylons 11 and 12. In mission editor the combined weapons
are selected in pylons 3 and 9 and their under-slung counterparts are
forced onto 11 and 12 using "required" arguments in the mod's lua. All
other pylon 3 and 9 weapons use "required clean" arguments. Liberation
doesn't have a way to force these linkages onto pylons 11 and 12 and
without them, even without clean, no weapons will load on 3 and 9 or 11
and 12.
The workaround for normal weapons on the F-4B is to set the standard
load-outs to "clean" on pylons 11 and 12. This allows all normal weapons
to work on pylons 3 and 9 so long as pylons 11 and 12 are left as Clean.
It also allows Clean into the Liberation dropdown so it can be selected
later if necessary.
The workaround for the 4 new weapons that combines pylons 3 with 11 and
9 with 12 is that the user has to use the matching pair on each set of
pylons. For example - if F4B_LAU105_AIM9J_2_BRU42A_MK82_3 is selected
for pylon 3, BRU 42A MK823 LAU105 AIM9J2 must be selected for pylon 11.
Failure to do this correctly doesn't crash liberation or DCS, the result
will just be either no weapons at all on either pylon or the underslung
weapons on 11 and 12 floating without a pylon attaching it to the plane.
When updating f4.py in the future, note that running the pydcs database
export doesn't pull any data for Pylons 11 and 12. Those matching
weapons / classes have to be manually defined in those pylons for the
F-4B. This is noted in f4.py.
If the transport were able to move exactly the quantity of units of the
given type remaining in the transfer without moving the whole order, the
transfer order would be left with instructions to transfer zero of that
unit. That's an invariant violation, and was resulting in _later_
transfers attempting to create a convoy with zero units, which pydcs
rightly rejects.
For example: if 2 Abrams and 2 Paladins are ordered to transfer from a
disconnected FOB to a distant location that is connected by road, and
only two cargo slots are available, that transfer could be split into:
```
{
Abrams: 2
}
```
and
```
{
Abrams: 0,
Paladin: 2
}
```
Depending on the route, those airlifted units might end up still needing
road transit (we prefer short airlifts rather than direct routes because
it gives the player more opportunities to intercept enemy convoys). The
current turn would airlift the Abrams-only group and the Paladin group
would wait. On the next turn the Abrams would travel by road and the
Paladins would be airlifted. On the _third_ turn, the Paladins (and zero
Abrams) would generate an invalid convoy.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2761.
Need to reset the persisted save paths on load, since the file that was
loaded may have been moved since it was saved and the original location
may no longer be accessible.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2756.
The manual for the legacy warthog usually calls these VHF 1/2 and UHF,
or VHF AM/FM and UHF. The AM/FM nomenclature is what I usually hear
people call them and it's clearer, so go with that.
For the A-10C II, that manual hasn't been updated for the AN/ARC-210
yet, so I'm not really sure what that ought to be called. The UFC calls
it COM 1 though, so I went with that. The alternative would be something
like VHF/UHF for the 210 and UHF for the 164, but I don't know if that's
actually better. Could be completely explicit and call them by their
full names, but that's probably less clear to people that aren't
fiddling with the radio implementation constantly (and even I confuse
the 164 and the 186 all the damn time).
When a new flight is added to a package, if the TOT is early enough the
new flight might have a startup time in the past. Clamp the TOT when
adding new flights to the package to avoid this.
https://github.com/dcs-liberation/dcs_liberation/issues/1680
This makes the start time in WaitingForStart dynamic, which is more
expensive but probably still cheap enough.
It also checks that the new TOT will not result in a start time in the
past when the player changes the TOT.
https://github.com/dcs-liberation/dcs_liberation/issues/1680
All three refueling missions share a common task type and differentiate
their behavior based on the type and allegiance of the package target.
This means that if the theater commander identifies a carrier as the
best location for a theater refueling task, a recovery tanker will be
planned by mistake.
If this happens on a sunken carrier, mission generation will fail
because a recovery tanker cannot be generated for a sunken carrier.
Fix the crash and the misplanned theater tanker by preventing the
commander from choosing fleet control points as refueling targets.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2693.
This is the first step toward bundling all assets related to a save game
into a single item. That makes it easier to avoid clobbering "temporary"
assets from other games like the state.json, but also makes it easier
for players to file bug reports, since there's only a single asset to
upload.
This is only the first step because so far it only includes the various
save files: start of turn, end of last turn before results processing,
and "latest" (the game saved explicitly by the player).
This is by no means complete. The bugs that this solves were already in
6.x, but we'd hidden the speed controls for the sim in that release, and
have always said that anything done after pressing "go" the first time
is undefined behavior. This is the first step on making those mid-sim
actions behave correctly.
UI actions such as creating a new package need to be executed between
ticks of the sim. We can either do this synchronously by blocking the UI
until the tick is done executing, acquiring a lock on the sim, executing
the action, then releasing the lock; or asynchronously by queueing
events and letting the sim execute them when it completes the current
tick (or instantly if the sim is paused).
Anything that comes from the new UI (currently just the map) must be
asynchronous because it goes through the REST API, but for the old UI
it's simpler (and because the lock will only be acquired as quickly as
the user can act, shouldn't slow anything down) to do this
synchronously, since it's difficult to use coroutines in Qt.
https://github.com/dcs-liberation/dcs_liberation/issues/1680
It sounds like PySide2 will not be moving to Python 3.11, so we're stuck
on 3.10 without this. Upgrading to a newer Qt also fixes some high DPI
bugs (the file browser dialog for save/load is no longer tiny on 4k).
https://github.com/pyinstaller/pyinstaller/issues/5414 previously
blocked this, but the bug appears to be fixed now.
mypy struggles to prove this cast correct when there are two or'd
isinstance checks where both types coincidentally have properties of the
same name (but no defined protocol making that explicit). I'm not really
sure why mypy is happy with this in its current state, but it isn't
after a change I'm making.
All our isinstance use is a bit of an anti-pattern anyway, so extract a
method that exposes the data we care about.
The start/end times for tankers aren't actually used, so this could be
simplified even more, but that data _should_ be used.
All groups (friendly and enemy) that are part of the front line are set
to `Hidden On MFD`. This is a group level filter, and can not be applied
on a per unit basis.
We often get save games uploaded with bug reports that are already in a
broken state with nothing we can do about it. This saves that turn to
`last_turn.liberation` so users are less likely to have clobbered the
useful data before filing the report.
There doesn't appear to be any reason for us to be poking at
implementation details here aside from changing the name from "unit" to
"building" for that case. Just iterate over the known strike targets.
Making this change uncovered some latent type errors.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2564.
With the latest change we added capture zones and corresponding trigger rules for all Airfields as well so we do not need to rely on the dcs capture event S_EVENT_BASE_CAPTURED anymore.
This will create capture zones and the trigger rules to check for a base capture. Will fix an issue where the dcs capture event is not fired and therefore the capture not recognized by liberation
Fixed an error which would occur when dead units which are non static would be added as secondary node during the skynet lua data generation. This should in general not be possible as connection nodes and power sources are currently most of the time static.
Troops must be dropped inside this zone or they won't attack the target.
The zone needs to be drawn in the map so players don't break the flight
plan by accidentally moving the drop waypoint outside the DZ.
I've move the API for doing this out of `PatrollingFlightPlan` in favor
of a mixin so this is no longer presented as `engagement_distance` by
the flight plan. I don't love that it's still the `commit-boundary`
endpoint, but it's fine for now.
I don't know why mypy wasn't able to catch this. pycharm is also
struggling to understand this class.
The timing for these doesn't work. Sweep RTBs at the same time the
package reaches its TOT. The tanker won't be on station until 1m30s
before the package reaches the refueling point.