Compare commits

...

10 Commits
2.4.1 ... 2.4.2

Author SHA1 Message Date
Dan Albert
e40b916b07 Merge pull request #884 from Khopa/develop_2_4_x
Release 2.4.2.
2021-02-12 19:05:44 -08:00
Dan Albert
1bc994c102 Fix version number of the release. 2021-02-12 16:18:01 -08:00
Dan Albert
21be4d38e1 Mention new start dates in the changelog.
(cherry picked from commit f7889b785d)
2021-02-12 16:16:36 -08:00
Mustang-25
3b58c571b3 Add a mid-90s campaign date option
1995 is a good date to pick if you want to date restrict all GPS weapons but still have all the laser guided options.

(cherry picked from commit 27829a024a)
2021-02-12 16:16:35 -08:00
Mustang-25
e0430cf607 Adjust HARM Weapon Restriction Date
Official Navy docs have the 88A's IOC date in 1983. Also left a note on the B and C IOC dates if DCS ever adds the older models.

(cherry picked from commit a0fda2552f)
2021-02-12 16:16:31 -08:00
Dan Albert
fb425d3524 Fix rounding of budget in recruitment menu.
Fixes https://github.com/Khopa/dcs_liberation/issues/861.

(cherry picked from commit 5792eb354c)
2021-02-12 14:01:34 -08:00
Dan Albert
45300b64c5 Mention weapon data in changelog.
(cherry picked from commit dce7d91511)
2021-02-12 13:54:51 -08:00
Brandon Danyluk
4b7ef46f82 Add weapon era restrictions for USA/Russia/UK/France (#860)
(cherry picked from commit 61f1e11a48)
2021-02-12 13:49:40 -08:00
Dan Albert
b67e6d20f1 Move 2.4.2 fix to the correct section.
(cherry picked from commit 3d1afa74d4)
2021-02-12 13:48:02 -08:00
Dan Albert
0ae6575087 Transfer pending purchases forward along capture.
Fixes https://github.com/Khopa/dcs_liberation/issues/828.

(cherry picked from commit d8c94f5ece)
2021-02-12 13:46:08 -08:00
8 changed files with 958 additions and 209 deletions

View File

@@ -1,3 +1,15 @@
# 2.4.2
## Features/Improvements
* **[Factions]** Introduction dates and fallback weapons added for US, Russian, UK, and French weapons. Huge thanks to @TheCandianVendingMachine for the massive amount of data entry!
* **[Campaigns]** Added 1995 start dates.
## Fixes
* **[Economy]** Pending ground unit purchases will also be transferred when a connected base is captured.
* **[UI]** Fixed rounding of budget in recruitment menu.
# 2.4.1 # 2.4.1
## Fixes ## Fixes

File diff suppressed because it is too large Load Diff

View File

@@ -1300,6 +1300,10 @@ TIME_PERIODS = {
"Gulf War - Winter [1990]": datetime(1990, 1, 1), "Gulf War - Winter [1990]": datetime(1990, 1, 1),
"Gulf War - Spring [1990]": datetime(1990, 4, 1), "Gulf War - Spring [1990]": datetime(1990, 4, 1),
"Gulf War - Summer [1990]": datetime(1990, 6, 1), "Gulf War - Summer [1990]": datetime(1990, 6, 1),
"Mid-90s - Winter [1995]": datetime(1995, 1, 1),
"Mid-90s - Spring [1995]": datetime(1995, 4, 1),
"Mid-90s - Summer [1995]": datetime(1995, 6, 1),
"Mid-90s - Fall [1995]": datetime(1995, 10, 1),
"Gulf War - Fall [1990]": datetime(1990, 10, 1), "Gulf War - Fall [1990]": datetime(1990, 10, 1),
"Modern - Winter [2010]": datetime(2010, 1, 1), "Modern - Winter [2010]": datetime(2010, 1, 1),
"Modern - Spring [2010]": datetime(2010, 4, 1), "Modern - Spring [2010]": datetime(2010, 4, 1),
@@ -1309,7 +1313,7 @@ TIME_PERIODS = {
"Syrian War [2011]": datetime(2011, 3, 15), "Syrian War [2011]": datetime(2011, 3, 15),
"6 days war [1967]": datetime(1967, 6, 5), "6 days war [1967]": datetime(1967, 6, 5),
"Yom Kippour War [1973]": datetime(1973, 10, 6), "Yom Kippour War [1973]": datetime(1973, 10, 6),
"Lebanon War [1982]": datetime(1982, 6, 6), "First Lebanon War [1982]": datetime(1982, 6, 6),
"Arab-Israeli War [1948]": datetime(1948, 5, 15), "Arab-Israeli War [1948]": datetime(1948, 5, 15),
} }

View File

@@ -6,7 +6,7 @@ from typing import Dict, Iterator, List, TYPE_CHECKING, Tuple, Type
from dcs.mapping import Point from dcs.mapping import Point
from dcs.task import Task from dcs.task import Task
from dcs.unittype import UnitType from dcs.unittype import UnitType, VehicleType
from game import persistency from game import persistency
from game.debriefing import AirLosses, Debriefing from game.debriefing import AirLosses, Debriefing
@@ -296,45 +296,69 @@ class Event:
self.game.turn) self.game.turn)
self.game.informations.append(info) self.game.informations.append(info)
def redeploy_units(self, cp): def redeploy_units(self, cp: ControlPoint) -> None:
"""" """"
Auto redeploy units to newly captured base Auto redeploy units to newly captured base
""" """
ally_connected_cps = [ocp for ocp in cp.connected_points if cp.captured == ocp.captured] ally_connected_cps = [ocp for ocp in cp.connected_points if
enemy_connected_cps = [ocp for ocp in cp.connected_points if cp.captured != ocp.captured] cp.captured == ocp.captured]
enemy_connected_cps = [ocp for ocp in cp.connected_points if
cp.captured != ocp.captured]
# If the newly captured cp does not have enemy connected cp, # If the newly captured cp does not have enemy connected cp,
# then it is not necessary to redeploy frontline units there. # then it is not necessary to redeploy frontline units there.
if len(enemy_connected_cps) == 0: if len(enemy_connected_cps) == 0:
return return
# From each ally cp, send reinforcements
for ally_cp in ally_connected_cps:
self.redeploy_between(cp, ally_cp)
def redeploy_between(self, destination: ControlPoint,
source: ControlPoint) -> None:
total_units_redeployed = 0
moved_units = {}
if source.has_active_frontline or not destination.captured:
# If there are still active front lines to defend at the
# transferring CP we should not transfer all units.
#
# Opfor also does not transfer all of their units.
# TODO: Balance the CPs rather than moving half from everywhere.
move_factor = 0.5
else: else:
# From each ally cp, send reinforcements # Otherwise we can move everything.
for ally_cp in ally_connected_cps: move_factor = 1
total_units_redeployed = 0
own_enemy_cp = [ocp for ocp in ally_cp.connected_points if ally_cp.captured != ocp.captured]
moved_units = {} for frontline_unit, count in source.base.armor.items():
moved_units[frontline_unit] = int(count * move_factor)
total_units_redeployed = total_units_redeployed + int(
count * move_factor)
# If the connected base, does not have any more enemy cp connected. destination.base.commision_units(moved_units)
# Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once) source.base.commit_losses(moved_units)
if len(own_enemy_cp) > 0 or not cp.captured:
for frontline_unit, count in ally_cp.base.armor.items():
moved_units[frontline_unit] = int(count/2)
total_units_redeployed = total_units_redeployed + int(count/2)
else: # So if the old base, does not have any more enemy cp connected, or if it is an enemy base
for frontline_unit, count in ally_cp.base.armor.items():
moved_units[frontline_unit] = count
total_units_redeployed = total_units_redeployed + count
cp.base.commision_units(moved_units) # Also transfer pending deliveries.
ally_cp.base.commit_losses(moved_units) for unit_type, count in source.pending_unit_deliveries.units.items():
if not issubclass(unit_type, VehicleType):
continue
if count <= 0:
# Don't transfer *sales*...
continue
move_count = int(count * move_factor)
source.pending_unit_deliveries.sell({unit_type: move_count})
destination.pending_unit_deliveries.order({unit_type: move_count})
total_units_redeployed += move_count
if total_units_redeployed > 0: if total_units_redeployed > 0:
info = Information("Units redeployed", "", self.game.turn) text = (
info.text = str(total_units_redeployed) + " units have been redeployed from " + ally_cp.name + " to " + cp.name f"{total_units_redeployed} units have been redeployed from "
self.game.informations.append(info) f"{source.name} to {destination.name}"
logging.info(info.text) )
info = Information("Units redeployed", text, self.game.turn)
self.game.informations.append(info)
logging.info(text)
class UnitsDeliveryEvent: class UnitsDeliveryEvent:

View File

@@ -606,6 +606,10 @@ class ControlPoint(MissionTarget, ABC):
def income_per_turn(self) -> int: def income_per_turn(self) -> int:
return 0 return 0
@property
def has_active_frontline(self) -> bool:
return any(
not c.is_friendly(self.captured) for c in self.connected_points)
class Airfield(ControlPoint): class Airfield(ControlPoint):

View File

@@ -2,7 +2,7 @@ from pathlib import Path
def _build_version_string() -> str: def _build_version_string() -> str:
components = ["2.4"] components = ["2.4.2"]
build_number_path = Path("resources/buildnumber") build_number_path = Path("resources/buildnumber")
if build_number_path.exists(): if build_number_path.exists():
with build_number_path.open("r") as build_number_file: with build_number_path.open("r") as build_number_file:

View File

@@ -28,7 +28,7 @@ class QRecruitBehaviour:
bought_amount_labels = None bought_amount_labels = None
maximum_units = -1 maximum_units = -1
recruitable_types = [] recruitable_types = []
BUDGET_FORMAT = "Available Budget: <b>${}M</b>" BUDGET_FORMAT = "Available Budget: <b>${:.2f}M</b>"
def __init__(self) -> None: def __init__(self) -> None:
self.bought_amount_labels = {} self.bought_amount_labels = {}