mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Fix range for ai flight planner so they are more likely to plan CAS flights (It's up to the player to setup flight on the runway or in flight)
204 lines
8.5 KiB
Python
204 lines
8.5 KiB
Python
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 db.BLUEFOR_FACTIONS 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)
|
|
|