import typing import random from datetime import datetime, timedelta, time from dcs.mission import Mission from dcs.triggers import * from dcs.condition import * from dcs.action import * from dcs.unit import Skill from dcs.point import MovingPoint, PointProperties from dcs.action import * from game import db from theater import * from gen.airsupportgen import AirSupportConflictGenerator from gen import * PUSH_TRIGGER_SIZE = 3000 PUSH_TRIGGER_ACTIVATION_AGL = 25 REGROUP_ZONE_DISTANCE = 12000 REGROUP_ALT = 5000 TRIGGER_WAYPOINT_OFFSET = 2 TRIGGER_MIN_DISTANCE_FROM_START = 10000 # modified since we now have advanced SAM units TRIGGER_RADIUS_MINIMUM = 3000000 TRIGGER_RADIUS_SMALL = 50000 TRIGGER_RADIUS_MEDIUM = 100000 TRIGGER_RADIUS_LARGE = 150000 TRIGGER_RADIUS_ALL_MAP = 3000000 class Silence(Option): Key = 7 class TriggersGenerator: def __init__(self, mission: Mission, conflict: Conflict, game): self.mission = mission self.conflict = conflict 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 self.delayed_trigger( plane_group, flag_id, flag_lower_limit=180, flag_upper_limit=2400, ) flag_id += 1 for vehicle_group in country.vehicle_group: vehicle_group.late_activation = True activate_by_trigger.append(vehicle_group) for group in activate_by_trigger: activation_trigger.add_action(ActivateGroup(group.id)) self.mission.triggerrules.triggers.append(activation_trigger) def _gen_push_trigger(self, player_cp: ControlPoint, player_coalition: str): push_by_trigger = [] for coalition_name, coalition in self.mission.coalition.items(): for country in coalition.countries.values(): if coalition_name == player_coalition: for group in country.plane_group + country.helicopter_group: if group.task == AWACS.name or group.task == Refueling.name: continue push_by_trigger.append(group) """if not group.units[0].is_human(): regroup_heading = self.conflict.to_cp.position.heading_between_point(player_cp.position) pos1 = group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE) pos2 = group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE+5000) w1 = group.add_waypoint(pos1, REGROUP_ALT) w2 = group.add_waypoint(pos2, REGROUP_ALT) group.points.remove(w1) group.points.remove(w2) group.points.insert(1, w2) group.points.insert(1, w1) w1.tasks.append(Silence(True)) switch_waypoint_task = ControlledTask(SwitchWaypoint(from_waypoint=3, to_waypoint=2)) switch_waypoint_task.start_if_user_flag(1, False) w2.tasks.append(switch_waypoint_task) group.points[3].tasks.append(Silence(False)) group.add_trigger_action(SwitchWaypoint(to_waypoint=4))""" push_trigger = TriggerOnce(Event.NoEvent, "Push trigger") for group in push_by_trigger: for unit in group.units: push_trigger.add_condition(UnitAltitudeHigherAGL(unit.id, PUSH_TRIGGER_ACTIVATION_AGL)) if not group.units[0].is_human(): push_trigger.add_action(AITaskPush(group.id, 1)) message_string = self.mission.string("Task force is in the air, proceed with the objective.") push_trigger.add_action(MessageToAll(message_string, clearview=True)) push_trigger.add_action(SetFlagValue()) self.mission.triggerrules.triggers.append(push_trigger) def _set_allegiances(self, player_coalition: str, enemy_coalition: str): for cp in self.game.theater.controlpoints: if cp.is_global: continue self.mission.terrain.airport_by_id(cp.at.id).set_coalition(cp.captured and player_coalition or enemy_coalition) def _set_skill(self, player_coalition: str, enemy_coalition: str): for coalition_name, coalition in self.mission.coalition.items(): if coalition_name == player_coalition: skill_level = self.game.settings.player_skill, self.game.settings.player_skill elif coalition_name == enemy_coalition: skill_level = self.game.settings.enemy_skill, self.game.settings.enemy_vehicle_skill else: continue for country in coalition.countries.values(): for plane_group in country.plane_group: for plane_unit in plane_group.units: if plane_unit.skill != Skill.Client and plane_unit.skill != Skill.Player: plane_unit.skill = Skill(skill_level[0]) for vehicle_group in country.vehicle_group: vehicle_group.set_skill(Skill(skill_level[1])) def delayed_trigger(self, group, flag_id, flag_lower_limit, flag_upper_limit): """ Create an activation trigger a randomized amount after the main activation occurs :param group: group to activate :param flag_id: ID of the flag to use :param flag_lower_limit: lower limit of what the random time can be (shouldn't be negative) :param flag_upper_limit: uopper limit of what the random time can be :return: N/A """ trigger_one = TriggerOnce(Event.NoEvent, "Activation trigger") trigger_one.add_condition(FlagEquals(1, 1)) trigger_one.add_action(SetFlagValue(flag_id, 1)) trigger_two = TriggerCondition() trigger_two.add_condition( TimeSinceFlag( flag_id, seconds=random.randint( flag_lower_limit, flag_upper_limit ) ) ) trigger_two.add_action(ActivateGroup(group.id)) self.mission.triggerrules.triggers.append(trigger_one) self.mission.triggerrules.triggers.append(trigger_two) def generate(self, player_cp: ControlPoint, is_quick: bool, activation_trigger_radius: int, awacs_enabled: bool): player_coalition = self.game.player_country in ["USA", "France", "Germany", "Uk"] and "blue" or "red" enemy_coalition = player_coalition == "blue" and "red" or "blue" self.mission.coalition[player_coalition].bullseye = {"x": self.conflict.position.x, "y": self.conflict.position.y} self._set_skill(player_coalition, enemy_coalition) self._set_allegiances(player_coalition, enemy_coalition) if not is_quick: # TODO: waypoint parts of this should not be post-hacked but added in airgen self._gen_activation_trigger(activation_trigger_radius, player_cp, player_coalition, enemy_coalition) self._gen_push_trigger(player_cp, player_coalition)