mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Auto redeploy frontline units.
This commit is contained in:
parent
8fd91e6c5c
commit
4bc04ec031
@ -2,7 +2,8 @@
|
||||
|
||||
##Features/Improvements :
|
||||
* **[Units/Factions]** Added P-47D-30 for factions allies_1944
|
||||
* **[Mission Generator]** CAP flights have been slightly reworked
|
||||
* **[Units/Factions]** Replaced S3-B Tanker by KC130 for most factions
|
||||
* **[Mission Generator]** AI Flight generator has been reworked
|
||||
* **[Mission Generator]** Add PP points for JF-17 on STRIKE missions
|
||||
* **[Mission Generator]** Add ST point for F-14B on STRIKE missions
|
||||
* **[Mission Generator]** Flights with client slots will never be delayed
|
||||
@ -18,12 +19,13 @@
|
||||
|
||||
##Fixed issues :
|
||||
* **[Mission Generator]** When playing as RED the activation trigger would not be properly generated
|
||||
* **[Mission Generator]** Changed "strike" payload for Su-24M
|
||||
* **[Mission Generator]** Changed "strike" payload for JF-17
|
||||
* **[Mission Generator]** Changed "strike" payload for Su-24M that was innefective
|
||||
* **[Mission Generator]** Changed "strike" payload for JF-17 to use LS-6 bombs instead of GBU
|
||||
* **[Mission Generator]** FW-190A8 is now properly considered as a flyable
|
||||
* **[Maps/Campaign]** Now using Vasiani airport instead of Soganlung in North Caucasus campaign (More parking slots)
|
||||
* **[Info Panel]** Message displayed on base capture event stated that the ennemy captured an airbase, while it was the player who captured it.
|
||||
* **[Map]** Graphical glitch on map when one building of an objective was destroyed, but not the others
|
||||
* **[Map]** Change power station template. (Buildings could end up superposed).
|
||||
|
||||
#2.0 RC 6
|
||||
|
||||
|
||||
@ -1033,14 +1033,6 @@ def _validate_db():
|
||||
assert unit_type not in total_set, "{} is duplicate for task {}".format(unit_type, t)
|
||||
total_set.add(unit_type)
|
||||
|
||||
# check country allegiance
|
||||
for unit_type in total_set:
|
||||
did_find = False
|
||||
for country_units_list in FACTIONS.values():
|
||||
if unit_type in country_units_list["units"]:
|
||||
did_find = True
|
||||
print("WARN : {} not in country list".format(unit_type))
|
||||
|
||||
# check prices
|
||||
for unit_type in total_set:
|
||||
assert unit_type in PRICES, "{} not in prices".format(unit_type)
|
||||
|
||||
@ -216,28 +216,27 @@ class Event:
|
||||
id = int(captured.split("||")[0])
|
||||
new_owner_coalition = int(captured.split("||")[1])
|
||||
|
||||
captured_cps = []
|
||||
for cp in self.game.theater.controlpoints:
|
||||
if cp.id == id:
|
||||
|
||||
pname = ""
|
||||
if cp.captured and new_owner_coalition != coalition:
|
||||
cp.captured = False
|
||||
info = Information(cp.name + " lost !",
|
||||
"We took control of " + cp.name + "! Great job !",
|
||||
self.game.turn)
|
||||
self.game.informations.append(info)
|
||||
pname = self.game.enemy_name
|
||||
elif not(cp.captured) and new_owner_coalition == coalition:
|
||||
cp.captured = True
|
||||
info = Information(cp.name + " captured !", "The ennemy took control of " + cp.name + "\nShame on us !", self.game.turn)
|
||||
self.game.informations.append(info)
|
||||
pname = self.game.enemy_name
|
||||
captured_cps.append(cp)
|
||||
elif not(cp.captured) and new_owner_coalition == coalition:
|
||||
cp.captured = True
|
||||
info = Information(cp.name + " lost !", "We took control of " + cp.name + "! Great job !", self.game.turn)
|
||||
self.game.informations.append(info)
|
||||
pname = self.game.player_name
|
||||
captured_cps.append(cp)
|
||||
else:
|
||||
continue
|
||||
|
||||
cp.base.aircraft = {}
|
||||
cp.base.armor = {}
|
||||
cp.base.aa = {}
|
||||
|
||||
airbase_def_id = 0
|
||||
for g in cp.ground_objects:
|
||||
@ -246,6 +245,10 @@ class Event:
|
||||
generate_airbase_defense_group(airbase_def_id, g, pname, self.game, cp)
|
||||
airbase_def_id = airbase_def_id + 1
|
||||
|
||||
for cp in captured_cps:
|
||||
logging.info("Will run redeploy for " + cp.name)
|
||||
self.redeploy_units(cp)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
@ -324,6 +327,47 @@ class Event:
|
||||
def skip(self):
|
||||
pass
|
||||
|
||||
def redeploy_units(self, cp):
|
||||
""""
|
||||
Auto redeploy units to newly captured base
|
||||
"""
|
||||
|
||||
ally_connected_cps = [ocp for ocp in cp.connected_points if 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,
|
||||
# then it is not necessary to redeploy frontline units there.
|
||||
if len(enemy_connected_cps) == 0:
|
||||
return
|
||||
else:
|
||||
# From each ally cp, send reinforcements
|
||||
for ally_cp in ally_connected_cps:
|
||||
total_units_redeployed = 0
|
||||
own_enemy_cp = [ocp for ocp in ally_cp.connected_points if ally_cp.captured != ocp.captured]
|
||||
|
||||
moved_units = {}
|
||||
|
||||
# If the connected base, does not have any more enemy cp connected.
|
||||
# Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once)
|
||||
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)
|
||||
ally_cp.base.commit_losses(moved_units)
|
||||
|
||||
if total_units_redeployed > 0:
|
||||
info = Information("Units redeployed", "", self.game.turn)
|
||||
info.text = str(total_units_redeployed) + " have been redeployed from " + ally_cp.name + " to " + cp.name
|
||||
self.game.informations.append(info)
|
||||
logging.info(info.text)
|
||||
|
||||
|
||||
|
||||
class UnitsDeliveryEvent(Event):
|
||||
informational = True
|
||||
|
||||
@ -47,11 +47,9 @@ class GameStats:
|
||||
for cp in game.theater.controlpoints:
|
||||
if cp.captured:
|
||||
turn_data.allied_units.aircraft_count += sum(cp.base.aircraft.values())
|
||||
turn_data.allied_units.sam_count += sum(cp.base.aa.values())
|
||||
turn_data.allied_units.vehicles_count += sum(cp.base.armor.values())
|
||||
else:
|
||||
turn_data.enemy_units.aircraft_count += sum(cp.base.aircraft.values())
|
||||
turn_data.enemy_units.sam_count += sum(cp.base.aa.values())
|
||||
turn_data.enemy_units.vehicles_count += sum(cp.base.armor.values())
|
||||
|
||||
self.data_per_turn.append(turn_data)
|
||||
|
||||
@ -120,34 +120,13 @@ class Base:
|
||||
target_dict[unit_type] = target_dict.get(unit_type, 0) + unit_count
|
||||
|
||||
def commit_losses(self, units_lost: typing.Dict[typing.Any, int]):
|
||||
# advanced SAM sites have multiple units - this code was not at all set up to handle that
|
||||
# to avoid having to restructure a bunch of upstream code, we track total destroyed units and
|
||||
# use that to determine if a site was destroyed
|
||||
# this can be thought of as the enemy re-distributing parts of SAM sites to keep as many
|
||||
# operational as possible (pulling specific units from ...storage... to bring them back online
|
||||
# if non-letal damage was done)
|
||||
# in the future, I may add more depth to this (e.g. a base having a certain number of spares and tracking
|
||||
# the number of pieces of each site), but for now this is what we get
|
||||
sams_destroyed = {}
|
||||
# we count complex SAM sites at the end - don't double count
|
||||
aa_skip = [
|
||||
AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1
|
||||
]
|
||||
|
||||
for unit_type, count in units_lost.items():
|
||||
if unit_type in db.SAM_CONVERT or unit_type in db.SAM_CONVERT['except']:
|
||||
# unit is part of an advanced SAM site, which means it will fail the below check
|
||||
try:
|
||||
sams_destroyed[unit_type] += 1
|
||||
except KeyError:
|
||||
sams_destroyed[unit_type] = 1
|
||||
|
||||
if unit_type in self.aircraft:
|
||||
target_array = self.aircraft
|
||||
elif unit_type in self.armor:
|
||||
target_array = self.armor
|
||||
elif unit_type in self.aa and unit_type not in aa_skip:
|
||||
target_array = self.aa
|
||||
else:
|
||||
print("Base didn't find event type {}".format(unit_type))
|
||||
continue
|
||||
@ -160,22 +139,6 @@ class Base:
|
||||
if target_array[unit_type] == 0:
|
||||
del target_array[unit_type]
|
||||
|
||||
# now that we have a complete picture of the SAM sites destroyed, determine if any were destroyed
|
||||
for sam_site, count in sams_destroyed.items():
|
||||
dead_count = aaa.num_sam_dead(sam_site, count)
|
||||
try:
|
||||
modified_sam_site = db.SAM_CONVERT[sam_site]
|
||||
except KeyError:
|
||||
modified_sam_site = db.SAM_CONVERT[sam_site]['except']
|
||||
|
||||
if modified_sam_site in self.aa:
|
||||
self.aa[modified_sam_site] = max(
|
||||
self.aa[modified_sam_site] - dead_count,
|
||||
0
|
||||
)
|
||||
if self.aa[modified_sam_site] == 0:
|
||||
del self.aa[modified_sam_site]
|
||||
|
||||
def affect_strength(self, amount):
|
||||
self.strength += amount
|
||||
if self.strength > BASE_MAX_STRENGTH:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user