added imports feature

adds an import feature for getting complex unit arrangements from miz files
This commit is contained in:
spencer-ki 2022-02-25 18:12:49 -08:00
parent 58bdc17b00
commit 8160fc29ff
6 changed files with 196 additions and 13 deletions

View File

@ -0,0 +1,8 @@
You can put .miz files in this folder to be copied into the generated mission at marker points. This feature is currently very 'alpha' and may produce errors.
1) Make an empty mission on Cauacasus.
2) Place units/objects on the map.
3) Make one unit group name: 'ANCHOR' This will represent the point of insertion into the target mission.
4) In a Scenario template, place a static object (flag, etc) and call it "IMPORT-[filename of .miz created in first step]"
Tip: You can change the heading of the imported group by changing the heading of the insertion object.

View File

@ -36,7 +36,7 @@ sys.excepthook = handle_exception
maj_version = 0
minor_version = 4
minor_version = 5
version_string = str(maj_version) + "." + str(minor_version)
scenarios = []
red_forces_files = []

View File

@ -6,11 +6,11 @@ import random
import RotorOpsGroups
import RotorOpsUnits
import RotorOpsUtils
import time
from MissionGenerator import logger
class RotorOpsMission:
def __init__(self):
@ -23,6 +23,7 @@ class RotorOpsMission:
self.sound_directory = self.home_dir + "\sound\embedded"
self.output_dir = self.home_dir + "\Generator\Output"
self.assets_dir = self.home_dir + "\Generator/assets"
self.imports_dir = self.home_dir + "\Generator\Imports"
self.conflict_zones = {}
self.staging_zones = {}
@ -119,6 +120,8 @@ class RotorOpsMission:
self.m.load_file(options["scenario_filename"])
self.importObjects()
if not self.m.country("Combined Joint Task Forces Red") or not self.m.country("Combined Joint Task Forces Blue"):
failure_msg = "You must include a CombinedJointTaskForcesBlue and CombinedJointTaskForcesRed unit in the scenario template. See the instructions in " + self.scenarios_dir
return {"success": False, "failure_msg": failure_msg}
@ -134,7 +137,6 @@ class RotorOpsMission:
self.m.add_picture_blue(self.assets_dir + '/briefing2.png')
# add zones to target mission
zone_names = ["ALPHA", "BRAVO", "CHARLIE", "DELTA"]
zone_flag = 101
@ -235,6 +237,9 @@ class RotorOpsMission:
self.addResources(self.sound_directory, self.script_directory)
self.scriptTriggerSetup(options)
# test adding static objects from a .miz
#self.addStatics()
#Save the mission file
os.chdir(self.output_dir)
output_filename = options["scenario_filename"].removesuffix('.miz') + " " + time.strftime('%a%H%M%S') + '.miz'
@ -631,7 +636,7 @@ class RotorOpsMission:
else:
return
if source_helo:
if source_helo and afg:
for unit in afg.units:
unit.pylons = source_helo.pylons
unit.livery_id = source_helo.livery_id
@ -661,10 +666,10 @@ class RotorOpsMission:
group_size=group_size)
zone_attack(afg, airport)
if source_plane:
for unit in afg.units:
unit.pylons = source_plane.pylons
unit.livery_id = source_plane.livery_id
if source_plane:
for unit in afg.units:
unit.pylons = source_plane.pylons
unit.livery_id = source_plane.livery_id
if options["e_transport_helos"]:
source_helo = None
@ -690,10 +695,10 @@ class RotorOpsMission:
afg.late_activation = True
afg.units[0].skill = dcs.unit.Skill.Excellent
if source_helo:
for unit in afg.units:
unit.pylons = source_helo.pylons
unit.livery_id = source_helo.livery_id
if source_helo:
for unit in afg.units:
unit.pylons = source_helo.pylons
unit.livery_id = source_helo.livery_id
def scriptTriggerSetup(self, options):
@ -841,3 +846,23 @@ class RotorOpsMission:
self.m.triggerrules.triggers.append(trig)
def addStatics(self):
os.chdir(self.home_dir + "/Generator/Statics")
logger.info("Looking for .miz files in '" + os.getcwd())
dest_point = self.conflict_zones["ALPHA"].position
grps = RotorOpsUtils.extractUnits.toPoint("test.miz", dest_point, 180)
for grp in grps:
self.m.country("Combined Joint Task Forces Blue").add_vehicle_group(grp)
def importObjects(self):
os.chdir(self.imports_dir)
logger.info("Looking for import .miz files in '" + os.getcwd())
for group in self.m.country("Combined Joint Task Forces Blue").static_group:
prefix = "IMPORT-"
if group.name.find(prefix) == 0:
filename = group.name.removeprefix(prefix) + ".miz"
i = RotorOpsUtils.ImportObjects(filename)
i.anchorByGroupName("ANCHOR")
i.copyTo(self.m, group.units[0].position)

View File

@ -1,5 +1,6 @@
import math
import dcs
from MissionGenerator import logger
def getDistance(point1=dcs.Point, point2=dcs.Point):
@ -15,3 +16,111 @@ def getDistance(point1=dcs.Point, point2=dcs.Point):
def convertMeterToNM(meters=int):
nm = meters / 1852
return nm
class ImportObjects:
def __init__(self, mizfile, ref_point=None, ref_heading=0):
self.source_mission = dcs.mission.Mission()
self.source_mission.load_file(mizfile)
self.ref_heading = ref_heading
if ref_point:
self.ref_point = ref_point
else:
self.ref_point = dcs.Point(self.source_mission.terrain.bullseye_blue["x"], self.source_mission.terrain.bullseye_blue["y"])
def anchorByGroupName(self, group_name):
group = self.source_mission.find_group(group_name)
if group:
self.ref_point = group.units[0].position
self.ref_heading = group.units[0].heading
else:
logger.warning("Unable to find group for anchor.")
def copyTo(self, mission, dest_point=None, dest_heading=0):
if not dest_point:
dest_point = dcs.Point(mission.terrain.bullseye_blue["x"], mission.terrain.bullseye_blue["y"])
#iterate over group types first?
for side in "red", "blue":
coalition = self.source_mission.coalition.get(side)
for country in coalition.countries:
group_types = [coalition.countries[country].static_group, coalition.countries[country].vehicle_group, coalition.countries[country].helicopter_group, coalition.countries[country].plane_group,
coalition.countries[country].ship_group]
for index, group_type in enumerate(group_types):
for group in group_type:
self.groupToPoint(group, self.ref_point, dest_point, self.ref_heading, dest_heading)
if index == 0:
mission.country(country).add_static_group(group)
elif index == 1:
mission.country(country).add_vehicle_group(group)
elif index == 2:
#mission.country(country).add_helicopter_group(group)
print("helicopter groups not available for import")
elif index == 3:
#mission.country(country).add_plane_group(group)
print("plane groups not available for import")
elif index == 4:
mission.country(country).add_ship_group(group)
@staticmethod
def groupToPoint(group, ref_point, dest_point, ref_heading=0, dest_heading=0):
for unit in group.units:
heading_to_unit = dcs.mapping.heading_between_points(ref_point.x, ref_point.y, unit.position.x,
unit.position.y)
new_heading_to_unit = dest_heading + heading_to_unit
unit_distance = ref_point.distance_to_point(unit.position)
unit.position = dest_point.point_from_heading(new_heading_to_unit, unit_distance)
return group
# class extractUnits:
#
# @staticmethod
# def toPoint(filename, group_type, dest_point, dest_heading=0, side="blue"):
# print("Attempting to extract units from " + filename + " relative to 'HELO_FARP' initial point.")
#
# source_mission = dcs.mission.Mission()
# source_mission.load_file(filename)
#
#
# # country = source_mission.country('Combined Joint Task Forces Blue')
# # country.find
#
# #group_types = []
#
# groups = []
#
# for country in source_mission.coalition.get(side).countries:
#
# ref_point = country.find_static_group("HELO_FARP").position #units position instead of group?
# ref_heading = country.find_static_group("HELO_FARP").heading
# group_types = [country.static_group, country.vehicle_group, country.helicopter_group, country.plane_group, country.ship_group]
#
# for group_type in group_types:
# for group in group_type:
# for unit in group.units:
# x_rel = ref_point.x - unit.position.x
# y_rel = ref_point.y - unit.position.y
# #heading_rel = ref_heading - unit.heading # heading of unit relative to heading of the reference object
# heading_to_unit = dcs.mapping.heading_between_points(ref_point.x, ref_point.y, unit.position.x, unit.position.y)
# new_heading_to_unit = dest_heading + heading_to_unit
# unit_distance = ref_point.distance_to_point(unit.position)
# unit.position = dest_point.point_from_heading(new_heading_to_unit, unit_distance)
#
# # unit.position.x = x - x_rel
# # unit.position.y = y - y_rel
#
# groups.append(group)
# return groups

Binary file not shown.

View File

@ -1,5 +1,5 @@
RotorOps = {}
RotorOps.version = "1.2.6"
RotorOps.version = "1.2.7"
local debug = true
@ -345,6 +345,7 @@ end
function RotorOps.isUnitInZone(unit, zone_name)
local zone = trigger.misc.getZone(zone_name)
local distance = getDistance(unit:getPoint(), zone.point)
--local distance = mist.utils.get2DDist(unit:getPoint(), zone.point)
if distance <= zone.radius then
return true
else
@ -1497,3 +1498,43 @@ function RotorOps.spawnTranspHelos(troops, max_drops)
end
--- USEFUL PUBLIC 'LUA PREDICATE' FUNCTIONS FOR MISSION EDITOR TRIGGERS
--determine if any players have broken a defined ceiling above ground level
function RotorOps.predPlayerMaxAGL(max_agl, hide_display)
for uName, uData in pairs(mist.DBs.humansByName) do
local player_unit = Unit.getByName(uData.unitName)
if player_unit then
local player_pos = player_unit:getPosition().p
local terrain_height = land.getHeight({x = player_pos.x, y = player_pos.z})
local player_agl = player_pos.y - terrain_height
if player_agl > max_agl then
env.info(uData.unitName.." broke the AGL limit of "..max_agl)
if not hide_display then
trigger.action.outText(uData.unitName.." is above the maximum altitude of "..max_agl.."m AGL.", 1, true)
end
return true
else
return false
end
end
end
end
--determine if any players are in a zone (not currently working)
function RotorOps.predPlayerInZone(zone_name)
local players_in_zone = 0
for uName, uData in pairs(mist.DBs.humansByName) do
local player_unit = Unit.getByName(uData.unitName)
if player_unit and RotorOps.isUnitInZone(player_unit, zone_name) then
players_in_zone = players_in_zone + 1
end
end
if players_in_zone > 0 then
return true
else
return false
end
end