mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Merge remote-tracking branch 'wrycu/develop' into develop_khopa
# Conflicts: # ui/overviewcanvas.py
This commit is contained in:
commit
c884fb7262
29
game/db.py
29
game/db.py
@ -104,9 +104,14 @@ PRICES = {
|
|||||||
AirDefence.AAA_Vulcan_M163: 5,
|
AirDefence.AAA_Vulcan_M163: 5,
|
||||||
AirDefence.SAM_Linebacker_M6: 10,
|
AirDefence.SAM_Linebacker_M6: 10,
|
||||||
|
|
||||||
AirDefence.SPAAA_ZSU_23_4_Shilka: 8,
|
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: 13,
|
||||||
AirDefence.SAM_SA_8_Osa_9A33: 18,
|
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,
|
||||||
|
|
||||||
# ship
|
# ship
|
||||||
CV_1143_5_Admiral_Kuznetsov: 100,
|
CV_1143_5_Admiral_Kuznetsov: 100,
|
||||||
@ -206,11 +211,13 @@ UNIT_BY_TASK = {
|
|||||||
AirDefence.SAM_Linebacker_M6,
|
AirDefence.SAM_Linebacker_M6,
|
||||||
|
|
||||||
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
||||||
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
AirDefence.AAA_ZU_23_Closed,
|
||||||
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
|
||||||
AirDefence.SAM_SA_9_Strela_1_9P31,
|
|
||||||
AirDefence.SAM_SA_9_Strela_1_9P31,
|
AirDefence.SAM_SA_9_Strela_1_9P31,
|
||||||
AirDefence.SAM_SA_8_Osa_9A33,
|
AirDefence.SAM_SA_8_Osa_9A33,
|
||||||
|
AirDefence.SAM_SA_19_Tunguska_2S6,
|
||||||
|
AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||||
|
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],
|
Reconnaissance: [Unarmed.Transport_M818, Unarmed.Transport_Ural_375, Unarmed.Transport_UAZ_469],
|
||||||
@ -229,6 +236,11 @@ SAM_BAN = [
|
|||||||
|
|
||||||
AirDefence.SAM_SA_9_Strela_1_9P31,
|
AirDefence.SAM_SA_9_Strela_1_9P31,
|
||||||
AirDefence.SAM_SA_8_Osa_9A33,
|
AirDefence.SAM_SA_8_Osa_9A33,
|
||||||
|
AirDefence.SAM_SA_19_Tunguska_2S6,
|
||||||
|
AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||||
|
AirDefence.SAM_SA_8_Osa_9A33,
|
||||||
|
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||||
|
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
|
||||||
]
|
]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -248,7 +260,7 @@ CARRIER_TAKEOFF_BAN = [
|
|||||||
AirDefense units that will be spawned at control points not related to the current operation
|
AirDefense units that will be spawned at control points not related to the current operation
|
||||||
"""
|
"""
|
||||||
EXTRA_AA = {
|
EXTRA_AA = {
|
||||||
"Russia": AirDefence.SAM_SA_19_Tunguska_2S6,
|
"Russia": AirDefence.SAM_SA_8_Osa_9A33,
|
||||||
"USA": AirDefence.SAM_Linebacker_M6,
|
"USA": AirDefence.SAM_Linebacker_M6,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +301,11 @@ UNIT_BY_COUNTRY = {
|
|||||||
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
||||||
AirDefence.SAM_SA_9_Strela_1_9P31,
|
AirDefence.SAM_SA_9_Strela_1_9P31,
|
||||||
AirDefence.SAM_SA_8_Osa_9A33,
|
AirDefence.SAM_SA_8_Osa_9A33,
|
||||||
|
AirDefence.AAA_ZU_23_Closed,
|
||||||
|
AirDefence.SAM_SA_19_Tunguska_2S6,
|
||||||
|
AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||||
|
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||||
|
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
|
||||||
|
|
||||||
Armor.APC_BTR_80,
|
Armor.APC_BTR_80,
|
||||||
Armor.MBT_T_90,
|
Armor.MBT_T_90,
|
||||||
|
|||||||
@ -84,8 +84,8 @@ class BaseAttackEvent(Event):
|
|||||||
departure_cp=self.departure_cp,
|
departure_cp=self.departure_cp,
|
||||||
to_cp=self.to_cp)
|
to_cp=self.to_cp)
|
||||||
|
|
||||||
defenders = self.to_cp.base.scramble_sweep(self.game.settings.multiplier)
|
defenders = self.to_cp.base.scramble_last_defense()
|
||||||
defenders.update(self.to_cp.base.scramble_cas(self.game.settings.multiplier))
|
#defenders.update(self.to_cp.base.scramble_cas(self.game.settings.multiplier))
|
||||||
|
|
||||||
op.setup(cas=flights[CAS],
|
op.setup(cas=flights[CAS],
|
||||||
escort=flights[CAP],
|
escort=flights[CAP],
|
||||||
|
|||||||
15
game/game.py
15
game/game.py
@ -20,7 +20,7 @@ COMMISION_LIMITS_FACTORS = {
|
|||||||
PinpointStrike: 10,
|
PinpointStrike: 10,
|
||||||
CAS: 5,
|
CAS: 5,
|
||||||
CAP: 8,
|
CAP: 8,
|
||||||
AirDefence: 1,
|
AirDefence: 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMISION_AMOUNTS_SCALE = 1.5
|
COMMISION_AMOUNTS_SCALE = 1.5
|
||||||
@ -28,7 +28,7 @@ COMMISION_AMOUNTS_FACTORS = {
|
|||||||
PinpointStrike: 3,
|
PinpointStrike: 3,
|
||||||
CAS: 1,
|
CAS: 1,
|
||||||
CAP: 2,
|
CAP: 2,
|
||||||
AirDefence: 0.3,
|
AirDefence: 0.8,
|
||||||
}
|
}
|
||||||
|
|
||||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 30
|
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 30
|
||||||
@ -187,7 +187,7 @@ class Game:
|
|||||||
if event_class is BaseAttackEvent:
|
if event_class is BaseAttackEvent:
|
||||||
base_attack_generated_for.add(enemy_cp)
|
base_attack_generated_for.add(enemy_cp)
|
||||||
|
|
||||||
if enemy_probability == 100 or enemy_probability > 0 and self._roll(enemy_probability, enemy_cp.base.strength):
|
if enemy_probability == 100 or enemy_probability > 0 and self._roll(enemy_probability, enemy_cp.base.strength):
|
||||||
self._generate_enemy_event(event_class, player_cp, enemy_cp)
|
self._generate_enemy_event(event_class, player_cp, enemy_cp)
|
||||||
|
|
||||||
def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]:
|
def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]:
|
||||||
@ -273,12 +273,11 @@ class Game:
|
|||||||
else:
|
else:
|
||||||
event.skip()
|
event.skip()
|
||||||
|
|
||||||
|
for cp in self.theater.enemy_points():
|
||||||
|
self._commision_units(cp)
|
||||||
|
self._budget_player()
|
||||||
|
|
||||||
if not no_action:
|
if not no_action:
|
||||||
self._budget_player()
|
|
||||||
|
|
||||||
for cp in self.theater.enemy_points():
|
|
||||||
self._commision_units(cp)
|
|
||||||
|
|
||||||
for cp in self.theater.player_points():
|
for cp in self.theater.player_points():
|
||||||
cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY)
|
cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY)
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,7 @@ class Operation:
|
|||||||
with open("resources/default_options.lua", "r") as f:
|
with open("resources/default_options.lua", "r") as f:
|
||||||
options_dict = loads(f.read())["options"]
|
options_dict = loads(f.read())["options"]
|
||||||
|
|
||||||
|
dcs.Mission.aaa_vehicle_group = aaa.aaa_vehicle_group
|
||||||
self.current_mission = dcs.Mission(terrain)
|
self.current_mission = dcs.Mission(terrain)
|
||||||
if is_quick:
|
if is_quick:
|
||||||
self.quick_mission = self.current_mission
|
self.quick_mission = self.current_mission
|
||||||
|
|||||||
268
gen/aaa.py
268
gen/aaa.py
@ -1,3 +1,5 @@
|
|||||||
|
import random
|
||||||
|
import math
|
||||||
from .conflictgen import *
|
from .conflictgen import *
|
||||||
from .naming import *
|
from .naming import *
|
||||||
|
|
||||||
@ -9,6 +11,266 @@ EXTRA_AA_MAX_DISTANCE = 150000
|
|||||||
EXTRA_AA_POSITION_FROM_CP = 550
|
EXTRA_AA_POSITION_FROM_CP = 550
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
:param position:
|
||||||
|
position of the center unit
|
||||||
|
:param heading:
|
||||||
|
the direction the units should be arranged toward if coverage is not 360
|
||||||
|
:param num_units:
|
||||||
|
number of units to play on the circle
|
||||||
|
:param launcher_distance:
|
||||||
|
distance the units should be from the center unit
|
||||||
|
:param coverage:
|
||||||
|
0-360
|
||||||
|
:return:
|
||||||
|
list of tuples representing each unit location
|
||||||
|
[(pos_x, pos_y, heading), ...]
|
||||||
|
"""
|
||||||
|
if coverage == 360:
|
||||||
|
# one of the positions is shared :'(
|
||||||
|
outer_offset = coverage / num_units
|
||||||
|
else:
|
||||||
|
outer_offset = coverage / (num_units - 1)
|
||||||
|
|
||||||
|
positions = []
|
||||||
|
|
||||||
|
if num_units % 2 == 0:
|
||||||
|
current_offset = heading - ((coverage / (num_units - 1)) / 2)
|
||||||
|
else:
|
||||||
|
current_offset = heading
|
||||||
|
current_offset -= outer_offset * (math.ceil(num_units / 2) - 1)
|
||||||
|
for x in range(1, num_units + 1):
|
||||||
|
positions.append((
|
||||||
|
position.x + launcher_distance * math.cos(math.radians(current_offset)),
|
||||||
|
position.y + launcher_distance * math.sin(math.radians(current_offset)),
|
||||||
|
current_offset,
|
||||||
|
))
|
||||||
|
current_offset += outer_offset
|
||||||
|
return positions
|
||||||
|
|
||||||
|
|
||||||
|
def aaa_vehicle_group(self, country, name, _type: unittype.VehicleType, position: mapping.Point,
|
||||||
|
heading=0, group_size=1,
|
||||||
|
formation=unitgroup.VehicleGroup.Formation.Line,
|
||||||
|
move_formation: PointAction=PointAction.OffRoad):
|
||||||
|
"""
|
||||||
|
Override the default vehicle group so that our group can contain a mix of units (which is required for advanced
|
||||||
|
SAM sites)
|
||||||
|
For further docstrings, see the built-in function
|
||||||
|
"""
|
||||||
|
vg = unitgroup.VehicleGroup(self.next_group_id(), self.string(name))
|
||||||
|
|
||||||
|
for i in range(1, group_size + 1):
|
||||||
|
heading = randint(0, 359)
|
||||||
|
if _type == AirDefence.SAM_SA_3_S_125_LN_5P73:
|
||||||
|
# 4 launchers (180 degrees all facing the same direction), 1 SR, 1 TR
|
||||||
|
num_launchers = 4
|
||||||
|
# search radar
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SR_P_19,
|
||||||
|
)
|
||||||
|
v.position.x = position.x
|
||||||
|
v.position.y = position.y + (i - 1) * 20
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
# track radar
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_3_S_125_TR_SNR,
|
||||||
|
)
|
||||||
|
|
||||||
|
center_x = position.x + randint(20, 40)
|
||||||
|
center_y = position.y + (i - 1) * 20
|
||||||
|
|
||||||
|
v.position.x = center_x
|
||||||
|
v.position.y = center_y
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
plop_positions = determine_positions(
|
||||||
|
position,
|
||||||
|
heading,
|
||||||
|
num_launchers,
|
||||||
|
launcher_distance=100,
|
||||||
|
coverage=180,
|
||||||
|
)
|
||||||
|
for x in range(0, num_launchers):
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||||
|
)
|
||||||
|
|
||||||
|
v.position.x = plop_positions[x][0]
|
||||||
|
v.position.y = plop_positions[x][1]
|
||||||
|
v.heading = plop_positions[x][2]
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
elif _type == AirDefence.SAM_SA_6_Kub_LN_2P25:
|
||||||
|
# 6 launchers (360 degree coverage)
|
||||||
|
# 1 S/TR
|
||||||
|
# search/track radar
|
||||||
|
num_launchers = 6
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_6_Kub_STR_9S91,
|
||||||
|
)
|
||||||
|
v.position.x = position.x
|
||||||
|
v.position.y = position.y + (i - 1) * 20
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
plop_positions = determine_positions(
|
||||||
|
position,
|
||||||
|
heading,
|
||||||
|
num_launchers,
|
||||||
|
launcher_distance=100,
|
||||||
|
coverage=360,
|
||||||
|
)
|
||||||
|
for x in range(0, num_launchers):
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_6_Kub_LN_2P25,
|
||||||
|
)
|
||||||
|
|
||||||
|
v.position.x = plop_positions[x][0]
|
||||||
|
v.position.y = plop_positions[x][1]
|
||||||
|
v.heading = plop_positions[x][2]
|
||||||
|
vg.add_unit(v)
|
||||||
|
elif _type == AirDefence.SAM_SA_10_S_300PS_LN_5P85C:
|
||||||
|
# 8 launchers - 4 directions, two in each direction
|
||||||
|
# 1 SR (offset)
|
||||||
|
# 1 TR (center)
|
||||||
|
# search radar
|
||||||
|
num_launchers = 8
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_SR_5N66M,
|
||||||
|
)
|
||||||
|
v.position.x = position.x
|
||||||
|
v.position.y = position.y + (i - 1) * 20
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
# track radar
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_TR_30N6,
|
||||||
|
)
|
||||||
|
|
||||||
|
center_x = position.x + randint(20, 40)
|
||||||
|
center_y = position.y + (i - 1) * 20
|
||||||
|
|
||||||
|
v.position.x = center_x
|
||||||
|
v.position.y = center_y
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
# command center
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_CP_54K6,
|
||||||
|
)
|
||||||
|
|
||||||
|
center_x = position.x + randint(40, 60)
|
||||||
|
center_y = position.y + (i - 1) * 20
|
||||||
|
|
||||||
|
v.position.x = center_x
|
||||||
|
v.position.y = center_y
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
plop_positions = determine_positions(
|
||||||
|
position,
|
||||||
|
heading,
|
||||||
|
num_launchers,
|
||||||
|
launcher_distance=150,
|
||||||
|
coverage=360,
|
||||||
|
)
|
||||||
|
for x in range(0, num_launchers):
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||||
|
)
|
||||||
|
|
||||||
|
v.position.x = plop_positions[x][0]
|
||||||
|
v.position.y = plop_positions[x][1]
|
||||||
|
v.heading = plop_positions[x][2]
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
elif _type == AirDefence.SAM_SA_10_S_300PS_CP_54K6:
|
||||||
|
# 8 launchers - 4 directions, two in each direction
|
||||||
|
# 1 SR (offset)
|
||||||
|
# 1 TR (center)
|
||||||
|
# search radar
|
||||||
|
num_launchers = 8
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_SR_64H6E,
|
||||||
|
)
|
||||||
|
v.position.x = position.x
|
||||||
|
v.position.y = position.y + (i - 1) * 20
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
# track radar
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_TR_30N6,
|
||||||
|
)
|
||||||
|
|
||||||
|
center_x = position.x + randint(20, 40)
|
||||||
|
center_y = position.y + (i - 1) * 20
|
||||||
|
|
||||||
|
v.position.x = center_x
|
||||||
|
v.position.y = center_y
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
# command center
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_CP_54K6,
|
||||||
|
)
|
||||||
|
|
||||||
|
center_x = position.x + randint(40, 60)
|
||||||
|
center_y = position.y + (i - 1) * 20
|
||||||
|
|
||||||
|
v.position.x = center_x
|
||||||
|
v.position.y = center_y
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
plop_positions = determine_positions(
|
||||||
|
position,
|
||||||
|
heading,
|
||||||
|
num_units=num_launchers,
|
||||||
|
launcher_distance=150,
|
||||||
|
coverage=360,
|
||||||
|
)
|
||||||
|
for x in range(0, num_launchers):
|
||||||
|
v = self.vehicle(
|
||||||
|
name + " Unit #{nr}".format(nr=i),
|
||||||
|
AirDefence.SAM_SA_10_S_300PS_LN_5P85D,
|
||||||
|
)
|
||||||
|
|
||||||
|
v.position.x = plop_positions[x][0]
|
||||||
|
v.position.y = plop_positions[x][1]
|
||||||
|
v.heading = plop_positions[x][2]
|
||||||
|
vg.add_unit(v)
|
||||||
|
else:
|
||||||
|
v = self.vehicle(name + " Unit #{nr}".format(nr=i), _type)
|
||||||
|
v.position.x = position.x
|
||||||
|
v.position.y = position.y + (i - 1) * 20
|
||||||
|
v.heading = heading
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
wp = vg.add_waypoint(vg.units[0].position, move_formation, 0)
|
||||||
|
wp.ETA_locked = True
|
||||||
|
if _type.eplrs:
|
||||||
|
wp.tasks.append(task.EPLRS(self.next_eplrs("vehicle")))
|
||||||
|
|
||||||
|
country.add_vehicle_group(vg)
|
||||||
|
return vg
|
||||||
|
|
||||||
|
|
||||||
class AAConflictGenerator:
|
class AAConflictGenerator:
|
||||||
def __init__(self, mission: Mission, conflict: Conflict):
|
def __init__(self, mission: Mission, conflict: Conflict):
|
||||||
self.m = mission
|
self.m = mission
|
||||||
@ -27,10 +289,10 @@ class AAConflictGenerator:
|
|||||||
def generate(self, units: db.AirDefenseDict):
|
def generate(self, units: db.AirDefenseDict):
|
||||||
for type, count in units.items():
|
for type, count in units.items():
|
||||||
for _, radial in zip(range(count), self.conflict.radials):
|
for _, radial in zip(range(count), self.conflict.radials):
|
||||||
distance = randint(self.conflict.size * DISTANCE_FACTOR[0], self.conflict.size * DISTANCE_FACTOR[1])
|
distance = randint(self.conflict.size * DISTANCE_FACTOR[0] + 9000, self.conflict.size * DISTANCE_FACTOR[1] + 14000)
|
||||||
p = self.conflict.position.point_from_heading(radial, distance)
|
p = self.conflict.position.point_from_heading(random.choice(self.conflict.radials), distance)
|
||||||
|
|
||||||
self.m.vehicle_group(
|
self.m.aaa_vehicle_group(
|
||||||
country=self.conflict.defenders_side,
|
country=self.conflict.defenders_side,
|
||||||
name=namegen.next_unit_name(self.conflict.defenders_side, type),
|
name=namegen.next_unit_name(self.conflict.defenders_side, type),
|
||||||
_type=type,
|
_type=type,
|
||||||
|
|||||||
@ -50,10 +50,10 @@ class GroundObjectsGenerator:
|
|||||||
else:
|
else:
|
||||||
cp = self.conflict.from_cp
|
cp = self.conflict.from_cp
|
||||||
|
|
||||||
|
consumed_farps = set()
|
||||||
|
|
||||||
for ground_object in cp.ground_objects:
|
for ground_object in cp.ground_objects:
|
||||||
if ground_object.dcs_identifier == "AA":
|
if ground_object.dcs_identifier == "AA":
|
||||||
if ground_object.position.distance_to_point(self.conflict.from_cp.position) < AA_CP_MIN_DISTANCE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if ground_object.is_dead:
|
if ground_object.is_dead:
|
||||||
continue
|
continue
|
||||||
@ -61,7 +61,7 @@ class GroundObjectsGenerator:
|
|||||||
unit_type = random.choice(self.game.commision_unit_types(cp, AirDefence))
|
unit_type = random.choice(self.game.commision_unit_types(cp, AirDefence))
|
||||||
assert unit_type is not None, "Cannot find unit type for GroundObject defense ({})!".format(cp)
|
assert unit_type is not None, "Cannot find unit type for GroundObject defense ({})!".format(cp)
|
||||||
|
|
||||||
group = self.m.vehicle_group(
|
group = self.m.aaa_vehicle_group(
|
||||||
country=side,
|
country=side,
|
||||||
name=ground_object.string_identifier,
|
name=ground_object.string_identifier,
|
||||||
_type=unit_type,
|
_type=unit_type,
|
||||||
@ -80,6 +80,16 @@ class GroundObjectsGenerator:
|
|||||||
print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier))
|
print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if ground_object.group_id not in consumed_farps:
|
||||||
|
consumed_farps.add(ground_object.group_id)
|
||||||
|
if random.randint(0, 100) > 50:
|
||||||
|
farp_aa(
|
||||||
|
self.m,
|
||||||
|
side,
|
||||||
|
ground_object.string_identifier,
|
||||||
|
ground_object.position,
|
||||||
|
)
|
||||||
|
|
||||||
group = self.m.static_group(
|
group = self.m.static_group(
|
||||||
country=side,
|
country=side,
|
||||||
name=ground_object.string_identifier,
|
name=ground_object.string_identifier,
|
||||||
@ -90,3 +100,39 @@ class GroundObjectsGenerator:
|
|||||||
)
|
)
|
||||||
|
|
||||||
logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id))
|
logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id))
|
||||||
|
|
||||||
|
|
||||||
|
def farp_aa(mission_obj, country, name, position: mapping.Point):
|
||||||
|
"""
|
||||||
|
Add AAA to a FARP :)
|
||||||
|
:param mission_obj:
|
||||||
|
:param country:
|
||||||
|
:param name:
|
||||||
|
:param position:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
vg = unitgroup.VehicleGroup(mission_obj.next_group_id(), mission_obj.string(name))
|
||||||
|
|
||||||
|
units = [
|
||||||
|
AirDefence.SPAAA_ZSU_23_4_Shilka,
|
||||||
|
AirDefence.AAA_ZU_23_Closed,
|
||||||
|
AirDefence.AAA_ZU_23_Emplacement,
|
||||||
|
AirDefence.AAA_ZU_23_on_Ural_375,
|
||||||
|
AirDefence.AAA_ZU_23_Insurgent_Closed,
|
||||||
|
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
|
||||||
|
Armor.MBT_T_55,
|
||||||
|
Armor.IFV_BMP_3,
|
||||||
|
]
|
||||||
|
|
||||||
|
v = mission_obj.vehicle(name + "_AAA", random.choice(units))
|
||||||
|
v.position.x = position.x - random.randint(5, 30)
|
||||||
|
v.position.y = position.y - random.randint(5, 30)
|
||||||
|
v.heading = random.randint(0, 359)
|
||||||
|
vg.add_unit(v)
|
||||||
|
|
||||||
|
wp = vg.add_waypoint(vg.units[0].position, PointAction.OffRoad, 0)
|
||||||
|
wp.ETA_locked = True
|
||||||
|
|
||||||
|
country.add_vehicle_group(vg)
|
||||||
|
return vg
|
||||||
|
|
||||||
|
|||||||
@ -42,29 +42,34 @@ class TriggersGenerator:
|
|||||||
self.game = game
|
self.game = game
|
||||||
|
|
||||||
def _gen_activation_trigger(self, radius: int, player_cp: ControlPoint, player_coalition: str, enemy_coalition: str):
|
def _gen_activation_trigger(self, radius: int, player_cp: ControlPoint, player_coalition: str, enemy_coalition: str):
|
||||||
|
conflict_distance = player_cp.position.distance_to_point(self.conflict.position)
|
||||||
|
minimum_radius = max(conflict_distance - TRIGGER_MIN_DISTANCE_FROM_START, TRIGGER_RADIUS_MINIMUM)
|
||||||
|
if minimum_radius < 0:
|
||||||
|
minimum_radius = 0
|
||||||
|
radius = min(minimum_radius, radius)
|
||||||
|
activation_trigger_zone = self.mission.triggers.add_triggerzone(
|
||||||
|
self.conflict.position,
|
||||||
|
radius,
|
||||||
|
name="Activation zone",
|
||||||
|
)
|
||||||
|
activation_trigger = TriggerOnce(Event.NoEvent, "Activation trigger")
|
||||||
|
activation_trigger.add_condition(PartOfCoalitionInZone(player_coalition, activation_trigger_zone.id))
|
||||||
|
activation_trigger.add_condition(FlagIsTrue())
|
||||||
activate_by_trigger = []
|
activate_by_trigger = []
|
||||||
|
flag_id = 2
|
||||||
for coalition_name, coalition in self.mission.coalition.items():
|
for coalition_name, coalition in self.mission.coalition.items():
|
||||||
for country in coalition.countries.values():
|
for country in coalition.countries.values():
|
||||||
if coalition_name == enemy_coalition:
|
if coalition_name == enemy_coalition:
|
||||||
for plane_group in country.plane_group + country.helicopter_group:
|
for plane_group in country.plane_group + country.helicopter_group:
|
||||||
plane_group.late_activation = True
|
plane_group.late_activation = True
|
||||||
activate_by_trigger.append(plane_group)
|
#activate_by_trigger.append(plane_group)
|
||||||
|
self.delayed_trigger(plane_group, flag_id)
|
||||||
|
flag_id += 1
|
||||||
|
|
||||||
for vehicle_group in country.vehicle_group:
|
for vehicle_group in country.vehicle_group:
|
||||||
vehicle_group.late_activation = True
|
vehicle_group.late_activation = True
|
||||||
activate_by_trigger.append(vehicle_group)
|
activate_by_trigger.append(vehicle_group)
|
||||||
|
|
||||||
conflict_distance = player_cp.position.distance_to_point(self.conflict.position)
|
|
||||||
minimum_radius = max(conflict_distance - TRIGGER_MIN_DISTANCE_FROM_START, TRIGGER_RADIUS_MINIMUM)
|
|
||||||
if minimum_radius < 0:
|
|
||||||
minimum_radius = 0
|
|
||||||
|
|
||||||
radius = min(minimum_radius, radius)
|
|
||||||
|
|
||||||
activation_trigger_zone = self.mission.triggers.add_triggerzone(self.conflict.position, radius, name="Activation zone")
|
|
||||||
activation_trigger = TriggerOnce(Event.NoEvent, "Activation trigger")
|
|
||||||
activation_trigger.add_condition(PartOfCoalitionInZone(player_coalition, activation_trigger_zone.id))
|
|
||||||
activation_trigger.add_condition(FlagIsTrue())
|
|
||||||
for group in activate_by_trigger:
|
for group in activate_by_trigger:
|
||||||
activation_trigger.add_action(ActivateGroup(group.id))
|
activation_trigger.add_action(ActivateGroup(group.id))
|
||||||
|
|
||||||
@ -143,6 +148,22 @@ class TriggersGenerator:
|
|||||||
for vehicle_group in country.vehicle_group:
|
for vehicle_group in country.vehicle_group:
|
||||||
vehicle_group.set_skill(Skill(skill_level[1]))
|
vehicle_group.set_skill(Skill(skill_level[1]))
|
||||||
|
|
||||||
|
def delayed_trigger(self, group, flag_id):
|
||||||
|
trigger_one = TriggerOnce(Event.NoEvent, "Activation trigger")
|
||||||
|
trigger_one.add_action(SetFlagValue(flag_id, random.randint(0, 1200)))
|
||||||
|
|
||||||
|
trigger_two = TriggerCondition()
|
||||||
|
trigger_two.add_condition(TimeSinceFlag(flag_id, seconds=1))
|
||||||
|
trigger_two.add_action(DecreaseFlag(flag_id, 1))
|
||||||
|
|
||||||
|
trigger_three = TriggerOnce()
|
||||||
|
trigger_three.add_condition(FlagEquals(flag_id, 1))
|
||||||
|
trigger_three.add_action(ActivateGroup(group.id))
|
||||||
|
|
||||||
|
self.mission.triggerrules.triggers.append(trigger_one)
|
||||||
|
self.mission.triggerrules.triggers.append(trigger_two)
|
||||||
|
self.mission.triggerrules.triggers.append(trigger_three)
|
||||||
|
|
||||||
def generate(self, player_cp: ControlPoint, is_quick: bool, activation_trigger_radius: int, awacs_enabled: bool):
|
def generate(self, player_cp: ControlPoint, is_quick: bool, activation_trigger_radius: int, awacs_enabled: bool):
|
||||||
player_coalition = self.game.player == "USA" and "blue" or "red"
|
player_coalition = self.game.player == "USA" and "blue" or "red"
|
||||||
enemy_coalition = player_coalition == "blue" and "red" or "blue"
|
enemy_coalition = player_coalition == "blue" and "red" or "blue"
|
||||||
|
|||||||
@ -158,14 +158,17 @@ class Base:
|
|||||||
return int(self.total_armor * 0.5)
|
return int(self.total_armor * 0.5)
|
||||||
|
|
||||||
def assemble_aa_count(self) -> int:
|
def assemble_aa_count(self) -> int:
|
||||||
if self.strength > STRENGTH_AA_ASSEMBLE_MIN:
|
# previous logic removed because we always want the full air defense capabilities.
|
||||||
return self.total_aa
|
return self.total_aa
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||||
return self._find_best_planes(CAP, self.scramble_count(multiplier, CAP))
|
return self._find_best_planes(CAP, self.scramble_count(multiplier, CAP))
|
||||||
|
|
||||||
|
def scramble_last_defense(self):
|
||||||
|
# return as many CAP-capable aircraft as we can since this is the last defense of the base
|
||||||
|
# (but not more than 20 - that's just nuts)
|
||||||
|
return self._find_best_planes(CAP, min(self.total_planes, 20))
|
||||||
|
|
||||||
def scramble_cas(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
def scramble_cas(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||||
return self._find_best_planes(CAS, self.scramble_count(multiplier, CAS))
|
return self._find_best_planes(CAS, self.scramble_count(multiplier, CAS))
|
||||||
|
|
||||||
|
|||||||
@ -320,7 +320,7 @@ class OverviewCanvas:
|
|||||||
for cp in self.game.theater.controlpoints:
|
for cp in self.game.theater.controlpoints:
|
||||||
coords = self._transform_point(cp.position)
|
coords = self._transform_point(cp.position)
|
||||||
radius = 12 * math.pow(cp.importance, 1)
|
radius = 12 * math.pow(cp.importance, 1)
|
||||||
radius_m = max(radius * cp.base.strength - 2, 0)
|
radius_m = radius * max(cp.base.strength - 2, 0)
|
||||||
|
|
||||||
if cp.captured:
|
if cp.captured:
|
||||||
color = self._player_color()
|
color = self._player_color()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user