mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
fix(SAMs): correctly track when a SAM site is destroyed
This commit is contained in:
parent
55de28105e
commit
b1576e8f15
41
game/db.py
41
game/db.py
@ -106,12 +106,12 @@ PRICES = {
|
||||
|
||||
AirDefence.AAA_ZU_23_Closed: 2,
|
||||
AirDefence.SPAAA_ZSU_23_4_Shilka: 4,
|
||||
AirDefence.SAM_SA_9_Strela_1_9P31: 13,
|
||||
AirDefence.SAM_SA_9_Strela_1_9P31: 8,
|
||||
AirDefence.SAM_SA_19_Tunguska_2S6: 15,
|
||||
AirDefence.SAM_SA_6_Kub_LN_2P25: 12,
|
||||
AirDefence.SAM_SA_8_Osa_9A33: 6,
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73: 10,
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 20,
|
||||
AirDefence.SAM_SA_6_Kub_LN_2P25: 22,
|
||||
AirDefence.SAM_SA_8_Osa_9A33: 12,
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73: 35,
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 25,
|
||||
|
||||
# ship
|
||||
CV_1143_5_Admiral_Kuznetsov: 100,
|
||||
@ -167,7 +167,6 @@ UNIT_BY_TASK = {
|
||||
Ka_50,
|
||||
SA342M,
|
||||
],
|
||||
|
||||
Transport: [
|
||||
IL_76MD,
|
||||
An_26B,
|
||||
@ -176,15 +175,12 @@ UNIT_BY_TASK = {
|
||||
|
||||
C_130,
|
||||
],
|
||||
|
||||
Refueling: [
|
||||
IL_78M,
|
||||
KC_135,
|
||||
S_3B_Tanker,
|
||||
],
|
||||
|
||||
AWACS: [E_3A, A_50, ],
|
||||
|
||||
PinpointStrike: [
|
||||
Armor.APC_BTR_80,
|
||||
Armor.APC_BTR_80,
|
||||
@ -219,11 +215,9 @@ UNIT_BY_TASK = {
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
|
||||
],
|
||||
|
||||
Reconnaissance: [Unarmed.Transport_M818, Unarmed.Transport_Ural_375, Unarmed.Transport_UAZ_469],
|
||||
Nothing: [Infantry.Infantry_M4, Infantry.Soldier_AK, ],
|
||||
Embarking: [UH_1H, Mi_8MT, ],
|
||||
|
||||
Carriage: [CVN_74_John_C__Stennis, LHA_1_Tarawa, CV_1143_5_Admiral_Kuznetsov, ],
|
||||
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev, Tanker_Elnya_160, Armed_speedboat, ],
|
||||
}
|
||||
@ -243,6 +237,28 @@ SAM_BAN = [
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
|
||||
]
|
||||
|
||||
"""
|
||||
Used to convert SAM site parts to the corresponding site
|
||||
"""
|
||||
SAM_CONVERT = {
|
||||
AirDefence.SAM_SR_P_19: AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
AirDefence.SAM_SA_3_S_125_TR_SNR: AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73: AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
AirDefence.SAM_SA_6_Kub_LN_2P25: AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||
AirDefence.SAM_SA_6_Kub_STR_9S91: AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||
AirDefence.SAM_SA_10_S_300PS_SR_5N66M: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||
AirDefence.SAM_SA_10_S_300PS_TR_30N6: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||
AirDefence.SAM_SA_10_S_300PS_CP_54K6: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||
AirDefence.SAM_SA_10_S_300PS_SR_64H6E: AirDefence.SAM_SA_10_S_300PS_CP_54K6,
|
||||
'except': {
|
||||
# this radar is shared between the two S300's. if we attempt to find a SAM site at a base and can't find one
|
||||
# model, we can safely assume the other was deployed
|
||||
# well, perhaps not safely, but we'll make the assumption anyway :p
|
||||
AirDefence.SAM_SA_10_S_300PS_TR_30N6: AirDefence.SAM_SA_10_S_300PS_CP_54K6,
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
Units that will always be spawned in the air
|
||||
"""
|
||||
@ -471,7 +487,8 @@ def unit_task(unit: UnitType) -> Task:
|
||||
for task, units in UNIT_BY_TASK.items():
|
||||
if unit in units:
|
||||
return task
|
||||
|
||||
elif unit in SAM_CONVERT:
|
||||
return SAM_CONVERT[unit]
|
||||
assert False
|
||||
|
||||
|
||||
|
||||
55
gen/aaa.py
55
gen/aaa.py
@ -11,6 +11,33 @@ EXTRA_AA_MAX_DISTANCE = 150000
|
||||
EXTRA_AA_POSITION_FROM_CP = 550
|
||||
|
||||
|
||||
def num_sam_dead(sam_type, destroyed_count):
|
||||
"""
|
||||
Given a type and count of SAM units, determine if enough units were destroyed to warrant the
|
||||
loss of a site
|
||||
:param sam_type:
|
||||
inidivudal unit name in SAM site which was destroyed
|
||||
:param destroyed_count:
|
||||
count of that unit type which was destroyed *in the sortie*
|
||||
:return:
|
||||
INT: number of sites lost
|
||||
"""
|
||||
sam_threshold = {
|
||||
AirDefence.SAM_SR_P_19: 1,
|
||||
AirDefence.SAM_SA_3_S_125_TR_SNR: 1,
|
||||
AirDefence.SAM_SA_6_Kub_STR_9S91: 1,
|
||||
AirDefence.SAM_SA_10_S_300PS_SR_5N66M: 1,
|
||||
AirDefence.SAM_SA_10_S_300PS_TR_30N6: 1,
|
||||
AirDefence.SAM_SA_10_S_300PS_CP_54K6: 1,
|
||||
AirDefence.SAM_SA_10_S_300PS_SR_64H6E: 1,
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73: 4,
|
||||
AirDefence.SAM_SA_6_Kub_LN_2P25: 6,
|
||||
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: 8,
|
||||
}
|
||||
|
||||
return int(destroyed_count / sam_threshold[sam_type])
|
||||
|
||||
|
||||
def determine_positions(position, heading, num_units, launcher_distance, coverage=90):
|
||||
"""
|
||||
Given a position on the map, array a group of units in a circle a uniform distance from the unit
|
||||
@ -69,7 +96,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
num_launchers = 4
|
||||
# search radar
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-sr".format(nr=i),
|
||||
AirDefence.SAM_SR_P_19,
|
||||
)
|
||||
v.position.x = position.x
|
||||
@ -78,7 +105,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
vg.add_unit(v)
|
||||
# track radar
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-tr".format(nr=i),
|
||||
AirDefence.SAM_SA_3_S_125_TR_SNR,
|
||||
)
|
||||
|
||||
@ -98,7 +125,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
)
|
||||
for x in range(0, num_launchers):
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-{x}".format(nr=i, x=x),
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
)
|
||||
|
||||
@ -113,7 +140,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
# search/track radar
|
||||
num_launchers = 6
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-str".format(nr=i),
|
||||
AirDefence.SAM_SA_6_Kub_STR_9S91,
|
||||
)
|
||||
v.position.x = position.x
|
||||
@ -130,7 +157,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
)
|
||||
for x in range(0, num_launchers):
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-{x}".format(nr=i, x=x),
|
||||
AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||
)
|
||||
|
||||
@ -145,7 +172,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
# search radar
|
||||
num_launchers = 8
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-sr".format(nr=i),
|
||||
AirDefence.SAM_SA_10_S_300PS_SR_5N66M,
|
||||
)
|
||||
v.position.x = position.x
|
||||
@ -154,7 +181,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
vg.add_unit(v)
|
||||
# track radar
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-tr".format(nr=i),
|
||||
AirDefence.SAM_SA_10_S_300PS_TR_30N6,
|
||||
)
|
||||
|
||||
@ -167,7 +194,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
vg.add_unit(v)
|
||||
# command center
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-c".format(nr=i),
|
||||
AirDefence.SAM_SA_10_S_300PS_CP_54K6,
|
||||
)
|
||||
|
||||
@ -188,7 +215,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
)
|
||||
for x in range(0, num_launchers):
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-{x}".format(nr=i, x=x),
|
||||
AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||
)
|
||||
|
||||
@ -204,7 +231,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
# search radar
|
||||
num_launchers = 8
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-sr".format(nr=i),
|
||||
AirDefence.SAM_SA_10_S_300PS_SR_64H6E,
|
||||
)
|
||||
v.position.x = position.x
|
||||
@ -213,7 +240,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
vg.add_unit(v)
|
||||
# track radar
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-tr".format(nr=i),
|
||||
AirDefence.SAM_SA_10_S_300PS_TR_30N6,
|
||||
)
|
||||
|
||||
@ -226,7 +253,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
vg.add_unit(v)
|
||||
# command center
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-c".format(nr=i),
|
||||
AirDefence.SAM_SA_10_S_300PS_CP_54K6,
|
||||
)
|
||||
|
||||
@ -247,7 +274,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
)
|
||||
for x in range(0, num_launchers):
|
||||
v = self.vehicle(
|
||||
name + " Unit #{nr}".format(nr=i),
|
||||
name + " Unit #{nr}-{x}".format(nr=i, x=x),
|
||||
AirDefence.SAM_SA_10_S_300PS_LN_5P85D,
|
||||
)
|
||||
|
||||
@ -256,7 +283,7 @@ def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position
|
||||
v.heading = plop_positions[x][2]
|
||||
vg.add_unit(v)
|
||||
else:
|
||||
v = self.vehicle(name + " Unit #{nr}".format(nr=i), _type)
|
||||
v = self.vehicle(name + " Unit #{nr}-sam".format(nr=i), _type)
|
||||
v.position.x = position.x
|
||||
v.position.y = position.y + (i - 1) * 20
|
||||
v.heading = heading
|
||||
|
||||
@ -8,6 +8,7 @@ from dcs.vehicles import *
|
||||
from dcs.task import *
|
||||
|
||||
from game import db
|
||||
from gen import aaa
|
||||
|
||||
STRENGTH_AA_ASSEMBLE_MIN = 0.2
|
||||
PLANES_SCRAMBLE_MIN_BASE = 2
|
||||
@ -119,12 +120,33 @@ 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:
|
||||
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))
|
||||
@ -138,6 +160,21 @@ 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']
|
||||
|
||||
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