From 26840373ed735e246b0ab37e4a15d0779568c305 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Thu, 30 May 2019 21:31:50 -0700 Subject: [PATCH 01/10] refactor(turns): modify turn settings * raise air defense limits * enemy gains more units even if no action is taken on a turn * player gains money even if no action was taken on a turn --- game/game.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/game/game.py b/game/game.py index 356e3375..c71cc688 100644 --- a/game/game.py +++ b/game/game.py @@ -20,7 +20,7 @@ COMMISION_LIMITS_FACTORS = { PinpointStrike: 10, CAS: 5, CAP: 8, - AirDefence: 1, + AirDefence: 8, } COMMISION_AMOUNTS_SCALE = 1.5 @@ -28,7 +28,7 @@ COMMISION_AMOUNTS_FACTORS = { PinpointStrike: 3, CAS: 1, CAP: 2, - AirDefence: 0.3, + AirDefence: 0.8, } PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 30 @@ -187,7 +187,7 @@ class Game: if event_class is BaseAttackEvent: 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) def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]: @@ -273,12 +273,11 @@ class Game: else: event.skip() + for cp in self.theater.enemy_points(): + self._commision_units(cp) + self._budget_player() + 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(): cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY) From 36aa4edb059993529bad9667284e9915784fd22f Mon Sep 17 00:00:00 2001 From: Wrycu Date: Thu, 30 May 2019 21:32:39 -0700 Subject: [PATCH 02/10] refactor(units): add SAMs to air defense --- game/db.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/game/db.py b/game/db.py index 3b155721..98275334 100644 --- a/game/db.py +++ b/game/db.py @@ -104,9 +104,14 @@ PRICES = { AirDefence.AAA_Vulcan_M163: 5, 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_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 CV_1143_5_Admiral_Kuznetsov: 100, @@ -206,11 +211,13 @@ UNIT_BY_TASK = { AirDefence.SAM_Linebacker_M6, AirDefence.SPAAA_ZSU_23_4_Shilka, - AirDefence.SPAAA_ZSU_23_4_Shilka, - AirDefence.SPAAA_ZSU_23_4_Shilka, - AirDefence.SAM_SA_9_Strela_1_9P31, + AirDefence.AAA_ZU_23_Closed, AirDefence.SAM_SA_9_Strela_1_9P31, 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], @@ -229,6 +236,11 @@ SAM_BAN = [ AirDefence.SAM_SA_9_Strela_1_9P31, 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 """ EXTRA_AA = { - "Russia": AirDefence.SAM_SA_19_Tunguska_2S6, + "Russia": AirDefence.SAM_SA_8_Osa_9A33, "USA": AirDefence.SAM_Linebacker_M6, } @@ -289,6 +301,11 @@ UNIT_BY_COUNTRY = { AirDefence.SPAAA_ZSU_23_4_Shilka, AirDefence.SAM_SA_9_Strela_1_9P31, 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.MBT_T_90, From f5851d09f504f5eb2f183153e1ae01f9ed916430 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Sat, 22 Jun 2019 14:15:24 -0700 Subject: [PATCH 03/10] fix(overview): correct negative radius --- ui/overviewcanvas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index 0bf3d455..39d677d4 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -320,7 +320,7 @@ class OverviewCanvas: for cp in self.game.theater.controlpoints: coords = self._transform_point(cp.position) radius = 12 * math.pow(cp.importance, 1) - radius_m = radius * cp.base.strength - 2 + radius_m = radius * max(cp.base.strength - 2, 0) if cp.captured: color = self._player_color() From c7eae7e97aa01778a9de95e4d61c00c35fc2e995 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Sat, 22 Jun 2019 14:17:28 -0700 Subject: [PATCH 04/10] fix(base): correct AA spawn --- theater/base.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/theater/base.py b/theater/base.py index 5f3b99cb..163879ad 100644 --- a/theater/base.py +++ b/theater/base.py @@ -158,10 +158,8 @@ class Base: return int(self.total_armor * 0.5) def assemble_aa_count(self) -> int: - if self.strength > STRENGTH_AA_ASSEMBLE_MIN: - return self.total_aa - else: - return 0 + # previous logic removed because we always want the full air defense capabilities. + return self.total_aa def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]: return self._find_best_planes(CAP, self.scramble_count(multiplier, CAP)) From e9103acb076636f9e1df4091d4200e69ee556fb3 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Sat, 22 Jun 2019 14:30:27 -0700 Subject: [PATCH 05/10] feat(attack): base attack - now spawn all CAP aircraft when a base is attacked --- game/event/baseattack.py | 4 ++-- theater/base.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/game/event/baseattack.py b/game/event/baseattack.py index 77a7cb03..dfe08ff1 100644 --- a/game/event/baseattack.py +++ b/game/event/baseattack.py @@ -84,8 +84,8 @@ class BaseAttackEvent(Event): departure_cp=self.departure_cp, to_cp=self.to_cp) - defenders = self.to_cp.base.scramble_sweep(self.game.settings.multiplier) - defenders.update(self.to_cp.base.scramble_cas(self.game.settings.multiplier)) + defenders = self.to_cp.base.scramble_last_defense() + #defenders.update(self.to_cp.base.scramble_cas(self.game.settings.multiplier)) op.setup(cas=flights[CAS], escort=flights[CAP], diff --git a/theater/base.py b/theater/base.py index 163879ad..e77057df 100644 --- a/theater/base.py +++ b/theater/base.py @@ -164,6 +164,11 @@ class Base: def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]: 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]: return self._find_best_planes(CAS, self.scramble_count(multiplier, CAS)) From 89f122c3257bb89e166b71ea742fdfebcf2bb372 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Sun, 23 Jun 2019 13:43:16 -0700 Subject: [PATCH 06/10] feat(attack): add multi-unit SAM site support --- game/operation/operation.py | 1 + gen/aaa.py | 264 +++++++++++++++++++++++++++++++++++- 2 files changed, 264 insertions(+), 1 deletion(-) diff --git a/game/operation/operation.py b/game/operation/operation.py index b0851309..a035b808 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -82,6 +82,7 @@ class Operation: with open("resources/default_options.lua", "r") as f: options_dict = loads(f.read())["options"] + dcs.Mission.aaa_vehicle_group = aaa.aaa_vehicle_group self.current_mission = dcs.Mission(terrain) if is_quick: self.quick_mission = self.current_mission diff --git a/gen/aaa.py b/gen/aaa.py index 3aaf999a..e2311254 100644 --- a/gen/aaa.py +++ b/gen/aaa.py @@ -1,3 +1,5 @@ +import random +import math from .conflictgen import * from .naming import * @@ -9,6 +11,266 @@ EXTRA_AA_MAX_DISTANCE = 150000 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: def __init__(self, mission: Mission, conflict: Conflict): self.m = mission @@ -30,7 +292,7 @@ class AAConflictGenerator: distance = randint(self.conflict.size * DISTANCE_FACTOR[0], self.conflict.size * DISTANCE_FACTOR[1]) p = self.conflict.position.point_from_heading(radial, distance) - self.m.vehicle_group( + self.m.aaa_vehicle_group( country=self.conflict.defenders_side, name=namegen.next_unit_name(self.conflict.defenders_side, type), _type=type, From 84b1df75c2b595426560baffbd5410aa2ac589d7 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Sun, 23 Jun 2019 14:27:07 -0700 Subject: [PATCH 07/10] feat(attack): air defense spawns further from the thing they are defending --- gen/aaa.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/aaa.py b/gen/aaa.py index e2311254..3b2b0426 100644 --- a/gen/aaa.py +++ b/gen/aaa.py @@ -289,8 +289,8 @@ class AAConflictGenerator: def generate(self, units: db.AirDefenseDict): for type, count in units.items(): for _, radial in zip(range(count), self.conflict.radials): - distance = randint(self.conflict.size * DISTANCE_FACTOR[0], self.conflict.size * DISTANCE_FACTOR[1]) - p = self.conflict.position.point_from_heading(radial, distance) + distance = randint(self.conflict.size * DISTANCE_FACTOR[0] + 9000, self.conflict.size * DISTANCE_FACTOR[1] + 14000) + p = self.conflict.position.point_from_heading(random.choice(self.conflict.radials), distance) self.m.aaa_vehicle_group( country=self.conflict.defenders_side, From b17e34351c10a6a4fdc5482ec67624e70a6626bf Mon Sep 17 00:00:00 2001 From: Wrycu Date: Mon, 24 Jun 2019 19:01:56 -0700 Subject: [PATCH 08/10] fix(strike): spawn air defense SAM sites on strike --- gen/groundobjectsgen.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index 9ec1cb3f..f5427460 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -52,8 +52,6 @@ class GroundObjectsGenerator: for ground_object in cp.ground_objects: 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: continue @@ -61,7 +59,7 @@ class GroundObjectsGenerator: 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) - group = self.m.vehicle_group( + group = self.m.aaa_vehicle_group( country=side, name=ground_object.string_identifier, _type=unit_type, From 49de53f1c9bc36f95ba1e5e1382bca5c3a50ce27 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Mon, 24 Jun 2019 20:44:28 -0700 Subject: [PATCH 09/10] feat(strike): add chance of AAA/tanks to strike targets --- gen/groundobjectsgen.py | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index f5427460..dd5df011 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -50,6 +50,8 @@ class GroundObjectsGenerator: else: cp = self.conflict.from_cp + consumed_farps = set() + for ground_object in cp.ground_objects: if ground_object.dcs_identifier == "AA": @@ -78,6 +80,16 @@ class GroundObjectsGenerator: print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier)) 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( country=side, name=ground_object.string_identifier, @@ -88,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)) + + +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 + From 72d3863f8a3a11fb30f1ae1cb0c4976c55feea46 Mon Sep 17 00:00:00 2001 From: Wrycu Date: Tue, 25 Jun 2019 22:21:12 -0700 Subject: [PATCH 10/10] feat(intercept): add random delay to enemy intercept --- gen/triggergen.py | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/gen/triggergen.py b/gen/triggergen.py index 08abc9b1..19e815ce 100644 --- a/gen/triggergen.py +++ b/gen/triggergen.py @@ -42,29 +42,34 @@ class TriggersGenerator: self.game = game 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 = [] + flag_id = 2 for coalition_name, coalition in self.mission.coalition.items(): for country in coalition.countries.values(): if coalition_name == enemy_coalition: for plane_group in country.plane_group + country.helicopter_group: 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: vehicle_group.late_activation = True 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: activation_trigger.add_action(ActivateGroup(group.id)) @@ -143,6 +148,22 @@ class TriggersGenerator: for vehicle_group in country.vehicle_group: 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): player_coalition = self.game.player == "USA" and "blue" or "red" enemy_coalition = player_coalition == "blue" and "red" or "blue"