RotorOps/Generator/RotorOpsImport.py
spencershepard f382a2e3cc
Develop (#40)
For users:
-Added KA-50 III and AV8BNA Harrier to slot selection
-Changed message in mission generated success dialog
-Zone protect SAMs now part of 'Advanced Defenses' feature
-Late activated friendly/enemy CAP units are placed in mission as a template for Deployed CAP fighters (ie will not be active unless using Advanced Defenses or 'DEPLOY_FIGHTERS' name for radar ground unit)
-improve idle troop behavior at bases/FARPs

For Mission creators:
-Updated pydcs library supports new units such as technicals
-Updated pydcs library supports Falklands map
-allow troop pickup from HELO_CARRIER
-enemy units with radar can be designated to deploy intercept fighters on detection (see RotorOps.fighter options in RotorOps.lua for details) with options for min detection altitude and distance (min detection altitude allows helis to fly 'under the radar')
-Insert RotorOpsServer.lua script and trigger actions if option set in scenario config: rotorops_server: true
-scenario template triggers should now be 'untouched' after mission generation, allowing previously unsupported triggers and actions to be used, along with color coding
-block adding player helicopters if slots locked in scenario config
-Added RotorOps.draw_conflict_zones setting to give users the ability to disable or enable displaying of zones on the map.
-allow disabling spinboxes in scenario config
-mission ends 10 mins after mission success/fail
-copy helicopter start type from templates

Internal:
-github actions workflow to automatically deploy to update server
-Startup version check will ignore micro version
-bypassing triggers and merging before save (to preserve unsupported triggers in pydcs). Our goal is to leave the trigrules and trig from the source mission untouched
-if using random weather, set ice halo to auto and crystals to none
-dont put planes at airports without ILS (to avoid putting planes at helicopter airports ie. Syria)
-improved guardPosition task
-refactored 'coalition' variables to 'coal' to help prevent introducing errors in RotorOps.lua
2023-01-03 12:05:18 -08:00

247 lines
12 KiB
Python

import math
import dcs
from MissionGenerator import logger
import os
class ImportObjects:
def __init__(self, mizfile):
self.pad_unit = True # todo: use this to hold a unit for helicopter placement on ships ie flight_group_from_unit
if not mizfile or not os.path.exists(mizfile):
raise Exception("Cannot find required file: " + str(mizfile))
logger.info("Importing objects from " + mizfile)
self.source_mission = dcs.mission.Mission()
self.source_mission.load_file(mizfile)
self.source_heading = None
self.source_point = None
self.statics = []
self.vehicles = []
self.helicopters = []
self.extractUnits()
def getStatics(self):
return self.statics
def getVehicles(self):
return self.vehicles
def getHelicopters(self):
return self.helicopters
def copyAll(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
return self.copyStatics(mission, dest_country_name, dest_name, dest_point, dest_heading), \
self.copyVehicles(mission, dest_country_name, dest_name, dest_point, dest_heading), \
self.copyHelicopters(mission, dest_country_name, dest_name, dest_point, dest_heading)
def anchorByGroupName(self, group_name):
group = self.source_mission.find_group(group_name)
if group:
self.source_point = group.units[0].position
self.source_heading = group.units[0].heading
else:
logger.warning("Unable to find group for anchor.")
raise Exception(
"Import template file error: " + self.mizfile + " does not contain a group called " + group_name)
def extractUnits(self):
for side in "red", "blue", "neutrals":
coalition = self.source_mission.coalition.get(side)
for country_name in coalition.countries:
group_types = [coalition.countries[country_name].static_group,
coalition.countries[country_name].vehicle_group,
coalition.countries[country_name].helicopter_group,
coalition.countries[country_name].plane_group,
coalition.countries[country_name].ship_group]
for index, group_type in enumerate(group_types):
for group in group_type:
if index == 0: # Statics
self.statics.append(group)
elif index == 1: # Vehicles
self.vehicles.append(group)
elif index == 2: # Helicopters
self.helicopters.append(group)
elif index == 3:
logger.warn(group.name + ": Planes not available for import")
elif index == 4:
logger.warn(group.name + ": Ships not available for import")
def copyStatics(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
logger.info("Copying " + str(len(self.statics)) + " static objects as " + dest_name)
new_groups = []
if not dest_point:
dest_point = dcs.Point(mission.terrain.bullseye_blue["x"], mission.terrain.bullseye_blue["y"])
# Statics
statics_copy = self.statics.copy()
for group in statics_copy:
self.groupToPoint(group, self.source_point, dest_point, self.source_heading, dest_heading)
class temp(dcs.unittype.StaticType):
id = group.units[0].type
name = group.units[0].name
shape_name = group.units[0].shape_name
rate = group.units[0].rate
can_cargo = group.units[0].can_cargo
mass = group.units[0].mass
ng = mission.static_group(mission.country(dest_country_name),
dest_name + " " + group.name,
temp,
group.units[0].position,
group.units[0].heading,
hidden=False)
ng.units[0].name = group.units[0].name
new_groups.append(ng)
# if ng.units[0].type == "Invisible FARP":
# self.pad_unit = ng
return new_groups
def copyVehicles(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
logger.info("Copying " + str(len(self.vehicles)) + " vehicle groups as " + dest_name)
new_groups = []
if not dest_point:
dest_point = dcs.Point(mission.terrain.bullseye_blue["x"], mission.terrain.bullseye_blue["y"])
vehicles_copy = self.vehicles
for group in vehicles_copy:
self.groupToPoint(group, self.source_point, dest_point, self.source_heading, dest_heading)
for i, unit in enumerate(group.units):
if i == 0:
ng = mission.vehicle_group(mission.country(dest_country_name),
dest_name + " " + group.name,
dcs.vehicles.vehicle_map[group.units[0].type],
group.units[0].position,
group.units[0].heading)
# ng.units[0].livery_id = group.units[0].livery_id
ng.units[0].name = dest_name + " " + group.units[i].name
new_groups.append(ng)
else:
u = mission.vehicle(dest_name + " " + group.units[i].name,
dcs.vehicles.vehicle_map[group.units[i].type])
u.position = group.units[i].position
u.heading = group.units[i].heading
# u.livery_id = group.units[i].livery_id
ng.add_unit(u)
return new_groups
def copyHelicopters(self, mission, dest_country_name, dest_name, dest_point, dest_heading=0,
start_type=None):
logger.info("Copying " + str(len(self.helicopters)) + " helicopters as " + dest_name)
new_groups = []
helicopters_copy = self.helicopters.copy()
for group in helicopters_copy:
self.groupToPoint(group, self.source_point, dest_point, self.source_heading, dest_heading)
if self.pad_unit:
if group.units[0].skill == dcs.unit.Skill.Client or group.units[0].skill == dcs.unit.Skill.Player:
# we'll create a new FARP for each helicopter. we've tried adding the flight group to an existing FARP, but they stack on top of each other
# trying to move the units into position after adding the flight group moves the 2D graphic of the helicopter, but the unit marker remains stacked on top
# of the unit marker in ME
# farp = mission.country(country_name).find_group(self.pad_unit.name)
#
# farp = mission.farp(mission.country(dest_country_name), dest_name + " " + group.name + " Pad", group.units[0].position, hidden=True, dead=False,
# farp_type=dcs.unit.InvisibleFARP)
#
#
# ng = mission.flight_group_from_unit(mission.country(dest_country_name),
# dest_name + " " + group.name,
# dcs.helicopters.helicopter_map[group.units[0].type],
# farp,
# group_size=1, start_type=start_type)
ng = mission.flight_group(mission.country(dest_country_name),
dest_name + " " + group.name,
dcs.helicopters.helicopter_map[group.units[0].type],
airport=None,
position=group.units[0].position,
group_size=1, start_type=start_type)
if start_type == dcs.mission.StartType.Warm:
ng.points[0].action = dcs.point.PointAction.FromGroundAreaHot
ng.points[0].type = "TakeOffGroundHot"
elif start_type == dcs.mission.StartType.Cold:
ng.points[0].action = dcs.point.PointAction.FromGroundArea
ng.points[0].type = "TakeOffGround"
else:
ng.points[0].action = group.points[0].action
ng.points[0].type = group.points[0].type
ng.units[0].heading = group.units[0].heading
ng.units[0].skill = group.units[0].skill
ng.units[0].livery_id = group.units[0].livery_id
ng.units[0].pylons = group.units[0].pylons
ng.units[0].fuel = group.units[0].fuel
ng.units[0].gun = group.units[0].gun
ng.units[0].hardpoint_racks = group.units[0].hardpoint_racks
new_groups.append(ng)
else:
logger.warn("No pad unit (ie FARP, carrier) found, so can't add helicopters.")
return new_groups
def copyVehiclesAsGroup(self, mission, dest_country_name, dest_name, dest_point, dest_heading=0):
logger.info("Copying " + str(len(self.vehicles)) + " vehicle groups as single group name: " + dest_name)
new_group = None
unit_count = 0
vehicles_copy = self.vehicles.copy()
for group in vehicles_copy:
self.groupToPoint(group, self.source_point, dest_point, self.source_heading, dest_heading)
for i, unit in enumerate(group.units):
if unit_count == 0:
# print("Group:" + group.name)
new_group = mission.vehicle_group(mission.country(dest_country_name),
dest_name,
dcs.vehicles.vehicle_map[group.units[0].type],
group.units[0].position,
group.units[0].heading)
unit_count = unit_count + 1
# new_group.units[0].livery_id = group.units[0].livery_id
new_group.units[0].name = dest_name + " " + group.units[i].name
else:
# print("Unit:" + group.units[i].name)
u = mission.vehicle(dest_name + " " + group.units[i].name,
dcs.vehicles.vehicle_map[group.units[i].type])
u.position = group.units[i].position
u.heading = group.units[i].heading
# u.livery_id = group.units[i].livery_id
new_group.add_unit(u)
unit_count = unit_count + 1
print("Made a group with units: " + str(unit_count))
# print("group actually has units: " + str(len(new_group.units)))
return new_group
@staticmethod
def groupToPoint(group, src_point, dest_point, src_heading=0, dest_heading=0):
for unit in group.units:
heading_to_unit = dcs.mapping.heading_between_points(src_point.x, src_point.y, unit.position.x,
unit.position.y)
new_heading_to_unit = dest_heading + heading_to_unit
unit_distance = src_point.distance_to_point(unit.position)
unit.position = dest_point.point_from_heading(new_heading_to_unit, unit_distance)
unit.heading = unit.heading + dest_heading
return group