diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 4ff35f606..8a6890d38 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -13,13 +13,13 @@ -- === -- -- ## Example Missions: --- +-- -- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Auftrag). --- +-- -- === --- +-- -- ### Author: **funkyfranky** --- +-- -- === -- @module Ops.Auftrag -- @image OPS_Auftrag.png @@ -58,20 +58,20 @@ -- @field #number Nkills Number of (enemy) units killed by assets of this mission. -- @field #number Nelements Number of elements (units) assigned to mission. -- @field #number dTevaluate Time interval in seconds before the mission result is evaluated after mission is over. --- @field #number Tover Mission abs. time stamp, when mission was over. +-- @field #number Tover Mission abs. time stamp, when mission was over. -- @field #table conditionStart Condition(s) that have to be true, before the mission will be started. -- @field #table conditionSuccess If all conditions are true, the mission is cancelled. -- @field #table conditionFailure If all conditions are true, the mission is cancelled. -- @field #table conditionPush If all conditions are true, the mission is executed. Before, the group(s) wait at the mission execution waypoint. --- +-- -- @field #number orbitSpeed Orbit speed in m/s. -- @field #number orbitAltitude Orbit altitude in meters. -- @field #number orbitHeading Orbit heading in degrees. -- @field #number orbitLeg Length of orbit leg in meters. -- @field Core.Point#COORDINATE orbitRaceTrack Race-track orbit coordinate. --- +-- -- @field Ops.Target#TARGET engageTarget Target data to engage. --- +-- -- @field Core.Zone#ZONE_RADIUS engageZone *Circular* engagement zone. -- @field #table engageTargetTypes Table of target types that are engaged in the engagement zone. -- @field #number engageAltitude Engagement altitude in meters. @@ -82,34 +82,34 @@ -- @field #boolean engageAsGroup Group attack. -- @field #number engageMaxDistance Max engage distance. -- @field #number refuelSystem Refuel type (boom or probe) for TANKER missions. --- +-- -- @field Wrapper.Group#GROUP escortGroup The group to be escorted. -- @field DCS#Vec3 escortVec3 The 3D offset vector from the escorted group to the escort group. --- +-- -- @field #number facDesignation FAC designation type. -- @field #boolean facDatalink FAC datalink enabled. -- @field #number facFreq FAC radio frequency in MHz. -- @field #number facModu FAC radio modulation 0=AM 1=FM. --- +-- -- @field Core.Set#SET_GROUP transportGroupSet Groups to be transported. -- @field Core.Point#COORDINATE transportPickup Coordinate where to pickup the cargo. -- @field Core.Point#COORDINATE transportDropoff Coordinate where to drop off the cargo. -- @field #number transportPickupRadius Radius in meters for pickup zone. Default 500 m. --- +-- -- @field Ops.OpsTransport#OPSTRANSPORT opstransport OPS transport assignment. -- @field #number NcarriersMin Min number of required carrier assets. -- @field #number NcarriersMax Max number of required carrier assets. -- @field Core.Zone#ZONE transportDeployZone Deploy zone of an OPSTRANSPORT. -- @field Core.Zone#ZONE transportDisembarkZone Disembark zone of an OPSTRANSPORT. --- +-- -- @field #number artyRadius Radius in meters. -- @field #number artyShots Number of shots fired. -- @field #number artyAltitude Altitude in meters. Can be used for a Barrage. -- @field #number artyHeading Heading in degrees (for Barrage). -- @field #number artyAngle Shooting angle in degrees (for Barrage). --- +-- -- @field #string alert5MissionType Alert 5 mission type. This is the mission type, the alerted assets will be able to carry out. --- +-- -- @field Ops.Chief#CHIEF chief The CHIEF managing this mission. -- @field Ops.Commander#COMMANDER commander The COMMANDER managing this mission. -- @field #table assets Warehouse assets assigned for this mission. @@ -121,16 +121,16 @@ -- @field #table NassetsLegMin Number of required warehouse assets for each assigned legion. -- @field #table NassetsLegMax Number of required warehouse assets for each assigned legion. -- @field #table requestID The ID of the queued warehouse request. Necessary to cancel the request if the mission was cancelled before the request is processed. --- @field #table payloads User specified airwing payloads for this mission. Only these will be considered for the job! +-- @field #table payloads User specified airwing payloads for this mission. Only these will be considered for the job! -- @field Ops.AirWing#AIRWING.PatrolData patroldata Patrol data. --- +-- -- @field #table specialLegions User specified legions assigned for this mission. Only these will be considered for the job! -- @field #table specialCohorts User specified cohorts assigned for this mission. Only these will be considered for the job! -- @field #table transportLegions Legions explicitly requested for providing transport carrier assets. --- @field #table transportCohorts Cohorts explicitly requested for providing transport carrier assets. +-- @field #table transportCohorts Cohorts explicitly requested for providing transport carrier assets. -- @field #table escortLegions Legions explicitly requested for providing escorting assets. -- @field #table escortCohorts Cohorts explicitly requested for providing escorting assets. --- +-- -- @field #string missionTask Mission task. See `ENUMS.MissionTask`. -- @field #number missionAltitude Mission altitude in meters. -- @field #number missionSpeed Mission speed in km/h. @@ -139,20 +139,20 @@ -- @field Core.Point#COORDINATE missionWaypointCoord Mission waypoint coordinate. -- @field Core.Point#COORDINATE missionEgressCoord Mission egress waypoint coordinate. -- @field #number missionWaypointRadius Random radius in meters. --- +-- -- @field #table enrouteTasks Mission enroute tasks. --- +-- -- @field #number repeated Number of times mission was repeated. -- @field #number repeatedSuccess Number of times mission was repeated after a success. -- @field #number repeatedFailure Number of times mission was repeated after a failure. -- @field #number Nrepeat Number of times the mission is repeated. -- @field #number NrepeatFailure Number of times mission is repeated if failed. -- @field #number NrepeatSuccess Number of times mission is repeated if successful. --- +-- -- @field Ops.OpsGroup#OPSGROUP.Radio radio Radio freq and modulation. -- @field Ops.OpsGroup#OPSGROUP.Beacon tacan TACAN setting. -- @field Ops.OpsGroup#OPSGROUP.Beacon icls ICLS setting. --- +-- -- @field #number optionROE ROE. -- @field #number optionROT ROT. -- @field #number optionAlarm Alarm state. @@ -162,7 +162,7 @@ -- @field #number optionRTBammo RTB on out-of-ammo. -- @field #number optionRTBfuel RTB on out-of-fuel. -- @field #number optionECM ECM. --- +-- -- @extends Core.Fsm#FSM --- *A warrior's mission is to foster the success of others.* - Morihei Ueshiba @@ -170,158 +170,162 @@ -- === -- -- # The AUFTRAG Concept --- +-- -- The AUFTRAG class significantly simplifies the workflow of using DCS tasks. -- -- You can think of an AUFTRAG as document, which contains the mission briefing, i.e. information about the target location, mission altitude, speed and various other parameters. -- This document can be handed over directly to a pilot (or multiple pilots) via the @{Ops.FlightGroup#FLIGHTGROUP} class. The pilots will then execute the mission. --- +-- -- The AUFTRAG document can also be given to an AIRWING. The airwing will then determine the best assets (pilots and payloads) available for the job. --- +-- -- Similarly, an AUFTRAG can be given to ground or navel groups via the @{Ops.ArmyGroup#ARMYGROUP} or @{Ops.NavyGroup#NAVYGROUP} classes, respectively. These classes have also --- AIRWING analouges, which are called BRIGADE and FLEET. Brigades and fleets will likewise select the best assets they have available and pass on the AUFTRAG to them. --- --- +-- AIRWING analouges, which are called BRIGADE and FLEET. Brigades and fleets will likewise select the best assets they have available and pass on the AUFTRAG to them. +-- +-- -- One more up the food chain, an AUFTRAG can be passed to a COMMANDER. The commander will recruit the best assets of AIRWINGs, BRIGADEs and/or FLEETs and pass the job over to it. --- +-- -- -- # Airborne Missions --- +-- -- Several mission types are supported by this class. --- +-- -- ## Anti-Ship --- +-- -- An anti-ship mission can be created with the @{#AUFTRAG.NewANTISHIP}() function. --- +-- -- ## AWACS --- +-- -- An AWACS mission can be created with the @{#AUFTRAG.NewAWACS}() function. --- +-- -- ## BAI --- +-- -- A BAI mission can be created with the @{#AUFTRAG.NewBAI}() function. --- +-- -- ## Bombing --- +-- -- A bombing mission can be created with the @{#AUFTRAG.NewBOMBING}() function. --- +-- -- ## Bombing Runway --- +-- -- A bombing runway mission can be created with the @{#AUFTRAG.NewBOMBRUNWAY}() function. --- +-- -- ## Bombing Carpet --- +-- -- A carpet bombing mission can be created with the @{#AUFTRAG.NewBOMBCARPET}() function. --- +-- -- ## CAP --- +-- -- A CAP mission can be created with the @{#AUFTRAG.NewCAP}() function. --- +-- -- ## CAS --- +-- -- A CAS mission can be created with the @{#AUFTRAG.NewCAS}() function. --- +-- -- ## Escort --- +-- -- An escort mission can be created with the @{#AUFTRAG.NewESCORT}() function. --- +-- -- ## FACA --- +-- -- An FACA mission can be created with the @{#AUFTRAG.NewFACA}() function. --- +-- -- ## Ferry --- +-- -- Not implemented yet. --- +-- -- ## Intercept --- +-- -- An intercept mission can be created with the @{#AUFTRAG.NewINTERCEPT}() function. --- +-- -- ## Orbit --- +-- -- An orbit mission can be created with the @{#AUFTRAG.NewORBIT}() function. --- +-- -- ## GCICAP --- +-- -- An patrol mission can be created with the @{#AUFTRAG.NewGCICAP}() function. --- +-- -- ## RECON --- +-- -- An reconnaissance mission can be created with the @{#AUFTRAG.NewRECON}() function. --- +-- -- ## RESCUE HELO --- +-- -- An rescue helo mission can be created with the @{#AUFTRAG.NewRESCUEHELO}() function. --- +-- -- ## SEAD --- +-- -- An SEAD mission can be created with the @{#AUFTRAG.NewSEAD}() function. --- +-- -- ## STRIKE --- +-- -- An strike mission can be created with the @{#AUFTRAG.NewSTRIKE}() function. --- +-- -- ## Tanker --- +-- -- A refueling tanker mission can be created with the @{#AUFTRAG.NewTANKER}() function. --- +-- -- ## TROOPTRANSPORT --- +-- -- A troop transport mission can be created with the @{#AUFTRAG.NewTROOPTRANSPORT}() function. --- +-- +-- ## HOVER +-- +-- A mission for a helicoptre or VSTOL plane to Hover at a point for a certain amount of time can be created with the @{#AUFTRAG.NewHOVER}() function. +-- -- # Ground Missions --- +-- -- ## ARTY --- +-- -- An arty mission can be created with the @{#AUFTRAG.NewARTY}() function. --- +-- -- ## ARMORATTACK --- +-- -- A mission to send a tank group can be created with the @{#AUFTRAG.NewARMORATTACK}() function. --- +-- -- # Options and Parameters --- --- --- +-- +-- TODO +-- -- # Assigning Missions --- +-- -- An AUFTRAG can be assigned to groups (FLIGHTGROUP, ARMYGROUP, NAVYGROUP), legions (AIRWING, BRIGADE, FLEET) or to a COMMANDER. --- +-- -- ## Group Level --- +-- -- ### Flight Group --- +-- -- Assigning an AUFTRAG to a flight group is done via the @{Ops.FlightGroup#FLIGHTGROUP.AddMission} function. See FLIGHTGROUP docs for details. --- +-- -- ### Army Group --- +-- -- Assigning an AUFTRAG to an army group is done via the @{Ops.ArmyGroup#ARMYGROUP.AddMission} function. See ARMYGROUP docs for details. --- +-- -- ### Navy Group --- +-- -- Assigning an AUFTRAG to a navy group is done via the @{Ops.NavyGroup#NAVYGROUP.AddMission} function. See NAVYGROUP docs for details. --- +-- -- ## Legion Level --- +-- -- Adding an AUFTRAG to an airwing is done via the @{Ops.AirWing#AIRWING.AddMission} function. See AIRWING docs for further details. -- Similarly, an AUFTRAG can be added to a brigade via the @{Ops.Brigade#BRIGADE.AddMission} function. --- +-- -- ## Commander Level --- +-- -- Assigning an AUFTRAG to acommander is done via the @{Ops.Commander#COMMANDER.AddMission} function. See COMMANDER docs for details. --- --- +-- +-- -- # Events --- +-- -- The AUFTRAG class creates many useful (FSM) events, which can be used in the mission designers script. --- --- TODO --- --- --- # Examples --- +-- -- TODO --- +-- +-- +-- # Examples +-- +-- TODO +-- -- -- @field #AUFTRAG AUFTRAG = { @@ -388,7 +392,7 @@ _AUFTRAGSNR=0 -- @field #string GROUNDATTACK Ground attack. AUFTRAG.Type={ ANTISHIP="Anti Ship", - AWACS="AWACS", + AWACS="AWACS", BAI="BAI", BOMBING="Bombing", BOMBRUNWAY="Bomb Runway", @@ -558,7 +562,7 @@ AUFTRAG.Category={ -- @field #number waypointindex Mission (ingress) Waypoint UID. -- @field #number waypointEgressUID Egress Waypoint UID. -- @field Core.Point#COORDINATE wpegresscoordinate Egress waypoint coordinate. --- +-- -- @field Ops.OpsGroup#OPSGROUP.Task waypointtask Waypoint task. -- @field #string status Group mission status. -- @field Functional.Warehouse#WAREHOUSE.Assetitem asset The warehouse asset. @@ -606,22 +610,22 @@ function AUFTRAG:New(Type) -- Inherit everything from FSM class. local self=BASE:Inherit(self, FSM:New()) -- #AUFTRAG - + -- Increase global counter. _AUFTRAGSNR=_AUFTRAGSNR+1 - + -- Mission type. self.type=Type - + -- Auftragsnummer. self.auftragsnummer=_AUFTRAGSNR - + -- Log ID. self:_SetLogID() - + -- State is planned. self.status=AUFTRAG.Status.PLANNED - + -- Defaults . self:SetName() self:SetPriority() @@ -630,7 +634,7 @@ function AUFTRAG:New(Type) --self:SetRequiredCarriers() self.engageAsGroup=true self.dTevaluate=5 - + -- Init counters and stuff. self.repeated=0 self.repeatedSuccess=0 @@ -641,35 +645,35 @@ function AUFTRAG:New(Type) self.Ncasualties=0 self.Nkills=0 self.Nelements=0 - + -- FMS start state is PLANNED. self:SetStartState(self.status) - + -- PLANNED --> (QUEUED) --> (REQUESTED) --> SCHEDULED --> STARTED --> EXECUTING --> DONE self:AddTransition("*", "Planned", AUFTRAG.Status.PLANNED) -- Mission is in planning stage. Could be in the queue of a COMMANDER or CHIEF. self:AddTransition(AUFTRAG.Status.PLANNED, "Queued", AUFTRAG.Status.QUEUED) -- Mission is in queue of a LEGION. self:AddTransition(AUFTRAG.Status.QUEUED, "Requested", AUFTRAG.Status.REQUESTED) -- Mission assets have been requested from the warehouse. self:AddTransition(AUFTRAG.Status.REQUESTED, "Scheduled", AUFTRAG.Status.SCHEDULED) -- Mission added to the first ops group queue. - + self:AddTransition(AUFTRAG.Status.PLANNED, "Scheduled", AUFTRAG.Status.SCHEDULED) -- From planned directly to scheduled. - + self:AddTransition(AUFTRAG.Status.SCHEDULED, "Started", AUFTRAG.Status.STARTED) -- First asset has started the mission. self:AddTransition(AUFTRAG.Status.STARTED, "Executing", AUFTRAG.Status.EXECUTING) -- First asset is executing the mission. - + self:AddTransition("*", "Done", AUFTRAG.Status.DONE) -- All assets have reported that mission is done. - + self:AddTransition("*", "Cancel", AUFTRAG.Status.CANCELLED) -- Command to cancel the mission. - + self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS) self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED) - + self:AddTransition("*", "Status", "*") self:AddTransition("*", "Stop", "*") - + self:AddTransition("*", "Repeat", AUFTRAG.Status.PLANNED) self:AddTransition("*", "ElementDestroyed", "*") - self:AddTransition("*", "GroupDead", "*") + self:AddTransition("*", "GroupDead", "*") self:AddTransition("*", "AssetDead", "*") ------------------------ @@ -709,7 +713,7 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. + -- @param #string To To state. --- Triggers the FSM event "Queued". @@ -726,7 +730,7 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. + -- @param #string To To state. --- Triggers the FSM event "Requested". @@ -743,7 +747,7 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. + -- @param #string To To state. --- Triggers the FSM event "Scheduled". @@ -760,7 +764,7 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. + -- @param #string To To state. --- Triggers the FSM event "Started". @@ -777,7 +781,7 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. + -- @param #string To To state. --- Triggers the FSM event "Executing". @@ -794,7 +798,7 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. + -- @param #string To To state. --- Triggers the FSM event "Cancel". @@ -812,7 +816,7 @@ function AUFTRAG:New(Type) -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. - + --- Triggers the FSM event "Done". -- @function [parent=#AUFTRAG] Done @@ -877,11 +881,11 @@ function AUFTRAG:New(Type) -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. - -- @param #string To To state. - + -- @param #string To To state. + -- Init status update. self:__Status(-1) - + return self end @@ -897,25 +901,25 @@ end function AUFTRAG:NewANTISHIP(Target, Altitude) local mission=AUFTRAG:New(AUFTRAG.Type.ANTISHIP) - + mission:_TargetFromObject(Target) - + -- DCS task parameters: mission.engageWeaponType=ENUMS.WeaponFlag.Auto mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageAltitude=UTILS.FeetToMeters(Altitude or 2000) - + -- Mission options: mission.missionTask=ENUMS.MissionTask.ANTISHIPSTRIKE mission.missionAltitude=mission.engageAltitude mission.missionFraction=0.4 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.EvadeFire - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -930,26 +934,26 @@ end function AUFTRAG:NewHOVER(Coordinate, Altitude, Time, Speed, MissionAlt) local mission=AUFTRAG:New(AUFTRAG.Type.HOVER) - + -- Altitude. if Altitude then mission.hoverAltitude=Coordinate:GetLandHeight()+UTILS.FeetToMeters(Altitude) else mission.hoverAltitude=Coordinate:GetLandHeight()+UTILS.FeetToMeters(50) - end - + end + mission:_TargetFromObject(Coordinate) mission.hoverSpeed = 0.1 -- the DCS Task itself will shortly be build with this so MPS mission.hoverTime = Time or 300 - mission.missionSpeed = UTILS.KnotsToMps(Speed or 150) + mission.missionSpeed = UTILS.KnotsToMps(Speed or 150) -- Mission options: mission.missionAltitude=mission.MissionAlt or UTILS.FeetToMeters(1000) - mission.missionFraction=0.9 + mission.missionFraction=0.9 mission.optionROE=ENUMS.ROE.ReturnFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} mission.DCStask=mission:GetDCSMissionTask() @@ -961,26 +965,26 @@ end -- @param #AUFTRAG self -- @param Core.Point#COORDINATE Coordinate Where to orbit. -- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`. --- @param #number Speed Orbit speed in knots. Default 350 KIAS. +-- @param #number Speed Orbit speed in knots. Default 350 KIAS. -- @param #number Heading Heading of race-track pattern in degrees. If not specified, a circular orbit is performed. -- @param #number Leg Length of race-track in NM. If not specified, a circular orbit is performed. -- @return #AUFTRAG self function AUFTRAG:NewORBIT(Coordinate, Altitude, Speed, Heading, Leg) local mission=AUFTRAG:New(AUFTRAG.Type.ORBIT) - + -- Altitude. if Altitude then mission.orbitAltitude=UTILS.FeetToMeters(Altitude) else mission.orbitAltitude=Coordinate.y - end + end Coordinate.y=mission.orbitAltitude - + mission:_TargetFromObject(Coordinate) mission.orbitSpeed = UTILS.KnotsToMps(Speed or 350) -- the DCS Task itself will shortly be build with this so MPS - mission.missionSpeed = UTILS.KnotsToKmph(Speed or 350) + mission.missionSpeed = UTILS.KnotsToKmph(Speed or 350) if Heading and Leg then mission.orbitHeading=Heading @@ -988,13 +992,13 @@ function AUFTRAG:NewORBIT(Coordinate, Altitude, Speed, Heading, Leg) mission.orbitRaceTrack=Coordinate:Translate(mission.orbitLeg, mission.orbitHeading, true) end - + -- Mission options: - mission.missionAltitude=mission.orbitAltitude*0.9 - mission.missionFraction=0.9 + mission.missionAltitude=mission.orbitAltitude*0.9 + mission.missionFraction=0.9 mission.optionROE=ENUMS.ROE.ReturnFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} mission.DCStask=mission:GetDCSMissionTask() @@ -1006,7 +1010,7 @@ end -- @param #AUFTRAG self -- @param Core.Point#COORDINATE Coordinate Position where to orbit around. -- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`. --- @param #number Speed Orbit speed in knots. Default 350 KIAS. +-- @param #number Speed Orbit speed in knots. Default 350 KIAS. -- @return #AUFTRAG self function AUFTRAG:NewORBIT_CIRCLE(Coordinate, Altitude, Speed) @@ -1029,7 +1033,7 @@ function AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) Leg = Leg or 10 local mission=AUFTRAG:NewORBIT(Coordinate, Altitude, Speed, Heading, Leg) - + return mission end @@ -1046,18 +1050,18 @@ function AUFTRAG:NewGCICAP(Coordinate, Altitude, Speed, Heading, Leg) -- Create ORBIT first. local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) - + -- Mission type GCICAP. mission.type=AUFTRAG.Type.GCICAP - + mission:_SetLogID() - -- Mission options: + -- Mission options: mission.missionTask=ENUMS.MissionTask.INTERCEPT mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + return mission end @@ -1074,23 +1078,23 @@ function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSyst -- Create ORBIT first. local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) - + -- Mission type TANKER. mission.type=AUFTRAG.Type.TANKER - + mission:_SetLogID() - + mission.refuelSystem=RefuelSystem - + -- Mission options: - mission.missionTask=ENUMS.MissionTask.REFUELING + mission.missionTask=ENUMS.MissionTask.REFUELING mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1106,21 +1110,21 @@ function AUFTRAG:NewAWACS(Coordinate, Altitude, Speed, Heading, Leg) -- Create ORBIT first. local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) - + -- Mission type AWACS. mission.type=AUFTRAG.Type.AWACS - + mission:_SetLogID() - + -- Mission options: - mission.missionTask=ENUMS.MissionTask.AWACS + mission.missionTask=ENUMS.MissionTask.AWACS mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1131,21 +1135,21 @@ end -- @param Wrapper.Positionable#POSITIONABLE Target The target to intercept. Can also be passed as simple @{Wrapper.Group#GROUP} or @{Wrapper.Unit#UNIT} object. -- @return #AUFTRAG self function AUFTRAG:NewINTERCEPT(Target) - + local mission=AUFTRAG:New(AUFTRAG.Type.INTERCEPT) - + mission:_TargetFromObject(Target) - + -- Mission options: - mission.missionTask=ENUMS.MissionTask.INTERCEPT - mission.missionFraction=0.1 + mission.missionTask=ENUMS.MissionTask.INTERCEPT + mission.missionFraction=0.1 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.EvadeFire - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1170,24 +1174,24 @@ function AUFTRAG:NewCAP(ZoneCAP, Altitude, Speed, Coordinate, Heading, Leg, Targ -- Create ORBIT first. local mission=AUFTRAG:NewORBIT(Coordinate or ZoneCAP:GetCoordinate(), Altitude or 10000, Speed, Heading, Leg) - + -- Mission type CAP. mission.type=AUFTRAG.Type.CAP mission:_SetLogID() - + -- DCS task parameters: mission.engageZone=ZoneCAP mission.engageTargetTypes=TargetTypes or {"Air"} -- Mission options: - mission.missionTask=ENUMS.MissionTask.CAP + mission.missionTask=ENUMS.MissionTask.CAP mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.EvadeFire - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1212,24 +1216,24 @@ function AUFTRAG:NewCAS(ZoneCAS, Altitude, Speed, Coordinate, Heading, Leg, Targ -- Create ORBIT first. local mission=AUFTRAG:NewORBIT(Coordinate or ZoneCAS:GetCoordinate(), Altitude or 10000, Speed, Heading, Leg) - + -- Mission type CAS. mission.type=AUFTRAG.Type.CAS mission:_SetLogID() - + -- DCS Task options: mission.engageZone=ZoneCAS mission.engageTargetTypes=TargetTypes or {"Helicopters", "Ground Units", "Light armed ships"} - + -- Mission options: - mission.missionTask=ENUMS.MissionTask.CAS + mission.missionTask=ENUMS.MissionTask.CAS mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.EvadeFire - + mission.categories={AUFTRAG.Category.AIRCRAFT} mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1245,27 +1249,27 @@ end function AUFTRAG:NewCASENHANCED(CasZone, Altitude, Speed, RangeMax, NoEngageZoneSet, TargetTypes) local mission=AUFTRAG:New(AUFTRAG.Type.CASENHANCED) - + -- Ensure we got a ZONE and not just the zone name. if type(CasZone)=="string" then CasZone=ZONE:New(CasZone) end - + mission:_TargetFromObject(CasZone) - + mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.CASENHANCED) - + mission:SetEngageDetected(RangeMax, TargetTypes or {"Helicopters", "Ground Units", "Light armed ships"}, CasZone, NoEngageZoneSet) - + mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.EvadeFire - - mission.missionFraction=1.0 + + mission.missionFraction=1.0 mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil mission.missionAltitude=Altitude and UTILS.FeetToMeters(Altitude) or nil - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1285,26 +1289,26 @@ function AUFTRAG:NewFACA(Target, Designation, DataLink, Frequency, Modulation) local mission=AUFTRAG:New(AUFTRAG.Type.FACA) mission:_TargetFromObject(Target) - + -- TODO: check that target is really a group object! - + -- DCS Task options: mission.facDesignation=Designation --or AI.Task.Designation.AUTO mission.facDatalink=true mission.facFreq=Frequency or 133 mission.facModu=Modulation or radio.modulation.AM - + -- Mission options: mission.missionTask=ENUMS.MissionTask.AFAC mission.missionAltitude=nil mission.missionFraction=0.5 mission.optionROE=ENUMS.ROE.ReturnFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1315,27 +1319,27 @@ end -- @param #number Altitude Engage altitude in feet. Default 5000 ft. -- @return #AUFTRAG self function AUFTRAG:NewBAI(Target, Altitude) - + local mission=AUFTRAG:New(AUFTRAG.Type.BAI) mission:_TargetFromObject(Target) - + -- DCS Task options: mission.engageWeaponType=ENUMS.WeaponFlag.AnyAG mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageAltitude=UTILS.FeetToMeters(Altitude or 5000) - + -- Mission options: mission.missionTask=ENUMS.MissionTask.GROUNDATTACK mission.missionAltitude=mission.engageAltitude mission.missionFraction=0.75 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} - - mission.DCStask=mission:GetDCSMissionTask() - + + mission.DCStask=mission:GetDCSMissionTask() + return mission end @@ -1345,16 +1349,16 @@ end -- @param #number Altitude Engage altitude in feet. Default 8000 ft. -- @return #AUFTRAG self function AUFTRAG:NewSEAD(Target, Altitude) - + local mission=AUFTRAG:New(AUFTRAG.Type.SEAD) mission:_TargetFromObject(Target) - + -- DCS Task options: mission.engageWeaponType=ENUMS.WeaponFlag.AnyAG --ENUMS.WeaponFlag.Cannons mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageAltitude=UTILS.FeetToMeters(Altitude or 8000) - + -- Mission options: mission.missionTask=ENUMS.MissionTask.SEAD mission.missionAltitude=mission.engageAltitude @@ -1362,11 +1366,11 @@ function AUFTRAG:NewSEAD(Target, Altitude) mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.EvadeFire --mission.optionROT=ENUMS.ROT.AllowAbortMission - + mission.categories={AUFTRAG.Category.AIRCRAFT} - - mission.DCStask=mission:GetDCSMissionTask() - + + mission.DCStask=mission:GetDCSMissionTask() + return mission end @@ -1378,25 +1382,25 @@ end function AUFTRAG:NewSTRIKE(Target, Altitude) local mission=AUFTRAG:New(AUFTRAG.Type.STRIKE) - + mission:_TargetFromObject(Target) - + -- DCS Task options: mission.engageWeaponType=ENUMS.WeaponFlag.AnyAG mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL - mission.engageAltitude=UTILS.FeetToMeters(Altitude or 2000) - + mission.engageAltitude=UTILS.FeetToMeters(Altitude or 2000) + -- Mission options: mission.missionTask=ENUMS.MissionTask.GROUNDATTACK mission.missionAltitude=mission.engageAltitude mission.missionFraction=0.75 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1408,9 +1412,9 @@ end function AUFTRAG:NewBOMBING(Target, Altitude) local mission=AUFTRAG:New(AUFTRAG.Type.BOMBING) - + mission:_TargetFromObject(Target) - + -- DCS task options: mission.engageWeaponType=ENUMS.WeaponFlag.AnyBomb mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL @@ -1418,19 +1422,19 @@ function AUFTRAG:NewBOMBING(Target, Altitude) -- Mission options: mission.missionTask=ENUMS.MissionTask.GROUNDATTACK - mission.missionAltitude=mission.engageAltitude*0.8 + mission.missionAltitude=mission.engageAltitude*0.8 mission.missionFraction=0.5 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.NoReaction -- No reaction is better. - + -- Evaluate result after 5 min. We might need time until the bombs have dropped and targets have been detroyed. mission.dTevaluate=5*60 - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + -- Get DCS task. mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1446,9 +1450,9 @@ function AUFTRAG:NewBOMBRUNWAY(Airdrome, Altitude) end local mission=AUFTRAG:New(AUFTRAG.Type.BOMBRUNWAY) - - mission:_TargetFromObject(Airdrome) - + + mission:_TargetFromObject(Airdrome) + -- DCS task options: mission.engageWeaponType=ENUMS.WeaponFlag.AnyBomb mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL @@ -1456,19 +1460,19 @@ function AUFTRAG:NewBOMBRUNWAY(Airdrome, Altitude) -- Mission options: mission.missionTask=ENUMS.MissionTask.RUNWAYATTACK - mission.missionAltitude=mission.engageAltitude*0.8 + mission.missionAltitude=mission.engageAltitude*0.8 mission.missionFraction=0.75 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.PassiveDefense - + -- Evaluate result after 5 min. mission.dTevaluate=5*60 - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + -- Get DCS task. mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1481,9 +1485,9 @@ end function AUFTRAG:NewBOMBCARPET(Target, Altitude, CarpetLength) local mission=AUFTRAG:New(AUFTRAG.Type.BOMBCARPET) - - mission:_TargetFromObject(Target) - + + mission:_TargetFromObject(Target) + -- DCS task options: mission.engageWeaponType=ENUMS.WeaponFlag.AnyBomb mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL @@ -1494,19 +1498,19 @@ function AUFTRAG:NewBOMBCARPET(Target, Altitude, CarpetLength) -- Mission options: mission.missionTask=ENUMS.MissionTask.GROUNDATTACK - mission.missionAltitude=mission.engageAltitude*0.8 + mission.missionAltitude=mission.engageAltitude*0.8 mission.missionFraction=0.5 mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.NoReaction - + -- Evaluate result after 5 min. mission.dTevaluate=5*60 - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + -- Get DCS task. mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1521,7 +1525,7 @@ end function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetTypes) local mission=AUFTRAG:New(AUFTRAG.Type.ESCORT) - + -- If only a string is passed we set a variable and check later if the group exists. if type(EscortGroup)=="string" then mission.escortGroupName=EscortGroup @@ -1529,23 +1533,23 @@ function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetT else mission:_TargetFromObject(EscortGroup) end - + -- DCS task parameters: mission.escortVec3=OffsetVector or {x=-100, y=0, z=200} mission.engageMaxDistance=EngageMaxDistance and UTILS.NMToMeters(EngageMaxDistance) or nil mission.engageTargetTypes=TargetTypes or {"Air"} - + -- Mission options: - mission.missionTask=ENUMS.MissionTask.ESCORT + mission.missionTask=ENUMS.MissionTask.ESCORT mission.missionFraction=0.1 mission.missionAltitude=1000 mission.optionROE=ENUMS.ROE.OpenFire -- TODO: what's the best ROE here? Make dependent on ESCORT or FOLLOW! mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1558,17 +1562,17 @@ function AUFTRAG:NewRESCUEHELO(Carrier) local mission=AUFTRAG:New(AUFTRAG.Type.RESCUEHELO) mission:_TargetFromObject(Carrier) - + -- Mission options: mission.missionTask=ENUMS.MissionTask.NOTHING mission.missionFraction=0.5 mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.NoReaction - + mission.categories={AUFTRAG.Category.HELICOPTER} - + mission.DCStask=mission:GetDCSMissionTask() - + return mission end @@ -1583,7 +1587,7 @@ end function AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet, DropoffCoordinate, PickupCoordinate, PickupRadius) local mission=AUFTRAG:New(AUFTRAG.Type.TROOPTRANSPORT) - + if TransportGroupSet:IsInstanceOf("GROUP") then mission.transportGroupSet=SET_GROUP:New() mission.transportGroupSet:AddGroup(TransportGroupSet) @@ -1593,16 +1597,16 @@ function AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet, DropoffCoordinate, PickupC mission:E(mission.lid.."ERROR: TransportGroupSet must be a GROUP or SET_GROUP object!") return nil end - + mission:_TargetFromObject(mission.transportGroupSet) - + mission.transportPickup=PickupCoordinate or mission:GetTargetCoordinate() mission.transportDropoff=DropoffCoordinate - + mission.transportPickupRadius=PickupRadius or 100 mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.TROOPTRANSPORT) - + -- Debug. --mission.transportPickup:MarkToAll("Pickup Transport") --mission.transportDropoff:MarkToAll("Drop off") @@ -1610,9 +1614,9 @@ function AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet, DropoffCoordinate, PickupC -- TODO: what's the best ROE here? mission.optionROE=ENUMS.ROE.ReturnFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.HELICOPTER, AUFTRAG.Category.GROUND} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1629,27 +1633,27 @@ end function AUFTRAG:NewOPSTRANSPORT(CargoGroupSet, PickupZone, DeployZone) local mission=AUFTRAG:New(AUFTRAG.Type.OPSTRANSPORT) - + mission.transportGroupSet=CargoGroupSet - + mission:_TargetFromObject(mission.transportGroupSet) - + mission.opstransport=OPSTRANSPORT:New(CargoGroupSet, PickupZone, DeployZone) - + function mission.opstransport:OnAfterExecuting(From, Event, To) mission:Executing() end - + function mission.opstransport:OnAfterDelivered(From, Event, To) mission:Done() end - + -- TODO: what's the best ROE here? mission.optionROE=ENUMS.ROE.ReturnFire mission.optionROT=ENUMS.ROT.PassiveDefense - + mission.categories={AUFTRAG.Category.ALL} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1667,25 +1671,25 @@ end function AUFTRAG:NewARTY(Target, Nshots, Radius, Altitude) local mission=AUFTRAG:New(AUFTRAG.Type.ARTY) - + mission:_TargetFromObject(Target) - + mission.artyShots=Nshots or nil mission.artyRadius=Radius or 100 mission.artyAltitude=Altitude - + mission.engageWeaponType=ENUMS.WeaponFlag.Auto - + mission.optionROE=ENUMS.ROE.OpenFire -- Ground/naval need open fire! mission.optionAlarm=0 - + mission.missionFraction=0.0 - + -- Evaluate after 8 min. mission.dTevaluate=8*60 - + mission.categories={AUFTRAG.Category.GROUND, AUFTRAG.Category.NAVAL} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1703,27 +1707,27 @@ end function AUFTRAG:NewBARRAGE(Zone, Heading, Angle, Radius, Altitude, Nshots) local mission=AUFTRAG:New(AUFTRAG.Type.BARRAGE) - + mission:_TargetFromObject(Zone) - + mission.artyShots=Nshots mission.artyRadius=Radius or 100 mission.artyAltitude=Altitude mission.artyHeading=Heading mission.artyAngle=Angle - + mission.engageWeaponType=ENUMS.WeaponFlag.Auto - + mission.optionROE=ENUMS.ROE.OpenFire -- Ground/naval need open fire! mission.optionAlarm=0 - + mission.missionFraction=0.0 - + -- Evaluate after instantly. mission.dTevaluate=10 - + mission.categories={AUFTRAG.Category.GROUND, AUFTRAG.Category.NAVAL} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1739,28 +1743,28 @@ end function AUFTRAG:NewPATROLZONE(Zone, Speed, Altitude, Formation) local mission=AUFTRAG:New(AUFTRAG.Type.PATROLZONE) - + -- Ensure we got a ZONE and not just the zone name. if type(Zone)=="string" then Zone=ZONE:New(Zone) end - + mission:_TargetFromObject(Zone) - + mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.PATROLZONE) - + mission.optionROE=ENUMS.ROE.OpenFire mission.optionROT=ENUMS.ROT.PassiveDefense mission.optionAlarm=ENUMS.AlarmState.Auto - - mission.missionFraction=1.0 + + mission.missionFraction=1.0 mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil mission.missionAltitude=Altitude and UTILS.FeetToMeters(Altitude) or nil - + mission.categories={AUFTRAG.Category.ALL} - + mission.DCStask=mission:GetDCSMissionTask() - + mission.DCStask.params.formation=Formation return mission @@ -1769,28 +1773,28 @@ end --- **[GROUND]** Create a ARMORATTACK mission. Armoured ground group(s) will go to the zone and attack. -- @param #AUFTRAG self --- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be a GROUP, UNIT or STATIC object. +-- @param Ops.Target#TARGET Target The target to attack. Can be a GROUP, UNIT or STATIC object. -- @param #number Speed Speed in knots. --- @param #string Formation The attack formation, e.g. "Wedge", "Vee" etc. +-- @param #string Formation The attack formation, e.g. "Wedge", "Vee" etc. -- @return #AUFTRAG self function AUFTRAG:NewARMORATTACK(Target, Speed, Formation) local mission=AUFTRAG:New(AUFTRAG.Type.ARMORATTACK) - + mission:_TargetFromObject(Target) - + mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.ARMORATTACK) - + mission.optionROE=ENUMS.ROE.OpenFire mission.optionAlarm=ENUMS.AlarmState.Auto - mission.optionFormation="Off Road" + mission.optionFormation="On Road" mission.optionAttackFormation=Formation or "Wedge" - - mission.missionFraction=1.0 + + mission.missionFraction=1.0 mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or 20 - + mission.categories={AUFTRAG.Category.GROUND} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1800,26 +1804,26 @@ end -- @param #AUFTRAG self -- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be a GROUP, UNIT or STATIC object. -- @param #number Speed Speed in knots. --- @param #string Formation The attack formation, e.g. "Wedge", "Vee" etc. +-- @param #string Formation The attack formation, e.g. "Wedge", "Vee" etc. -- @return #AUFTRAG self function AUFTRAG:NewGROUNDATTACK(Target, Speed, Formation) local mission=AUFTRAG:New(AUFTRAG.Type.GROUNDATTACK) - + mission:_TargetFromObject(Target) - + mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.GROUNDATTACK) - + mission.optionROE=ENUMS.ROE.OpenFire mission.optionAlarm=ENUMS.AlarmState.Auto mission.optionFormation="On Road" mission.optionAttackFormation=Formation or "Wedge" - + mission.missionFraction=0.75 mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or 20 - + mission.categories={AUFTRAG.Category.GROUND} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1836,25 +1840,25 @@ end function AUFTRAG:NewRECON(ZoneSet, Speed, Altitude, Adinfinitum, Randomly) local mission=AUFTRAG:New(AUFTRAG.Type.RECON) - + mission:_TargetFromObject(ZoneSet) - + mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.RECON) - + mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.PassiveDefense mission.optionAlarm=ENUMS.AlarmState.Auto - + mission.missionFraction=0.5 mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil mission.missionAltitude=Altitude and UTILS.FeetToMeters(Altitude) or UTILS.FeetToMeters(2000) - + mission.categories={AUFTRAG.Category.ALL} - + mission.DCStask=mission:GetDCSMissionTask() mission.DCStask.params.adinfinitum=Adinfinitum mission.DCStask.params.randomly=Randomly - + if Randomly then local targets = mission.DCStask.params.target.targets -- Ops.Target#TARGET local shuffled = UTILS.ShuffleTable(targets) @@ -1871,18 +1875,18 @@ end function AUFTRAG:NewAMMOSUPPLY(Zone) local mission=AUFTRAG:New(AUFTRAG.Type.AMMOSUPPLY) - + mission:_TargetFromObject(Zone) - + mission.optionROE=ENUMS.ROE.WeaponHold mission.optionAlarm=ENUMS.AlarmState.Auto - + mission.missionFraction=1.0 - + mission.missionWaypointRadius=0 - + mission.categories={AUFTRAG.Category.GROUND} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1895,16 +1899,16 @@ end function AUFTRAG:NewFUELSUPPLY(Zone) local mission=AUFTRAG:New(AUFTRAG.Type.FUELSUPPLY) - + mission:_TargetFromObject(Zone) - + mission.optionROE=ENUMS.ROE.WeaponHold mission.optionAlarm=ENUMS.AlarmState.Auto - + mission.missionFraction=1.0 - + mission.categories={AUFTRAG.Category.GROUND} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1919,18 +1923,18 @@ end function AUFTRAG:NewALERT5(MissionType) local mission=AUFTRAG:New(AUFTRAG.Type.ALERT5) - + mission.missionTask=self:GetMissionTaskforMissionType(MissionType) - + mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.NoReaction - + mission.alert5MissionType=MissionType - + mission.missionFraction=1.0 - + mission.categories={AUFTRAG.Category.AIRCRAFT} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1943,16 +1947,16 @@ end function AUFTRAG:NewONGUARD(Coordinate) local mission=AUFTRAG:New(AUFTRAG.Type.ONGUARD) - + mission:_TargetFromObject(Coordinate) - + mission.optionROE=ENUMS.ROE.OpenFire mission.optionAlarm=ENUMS.AlarmState.Auto - + mission.missionFraction=1.0 - + mission.categories={AUFTRAG.Category.GROUND, AUFTRAG.Category.NAVAL} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1966,18 +1970,18 @@ end function AUFTRAG:NewARMOREDGUARD(Coordinate,Formation) local mission=AUFTRAG:New(AUFTRAG.Type.ARMOREDGUARD) - + mission:_TargetFromObject(Coordinate) - + mission.optionROE=ENUMS.ROE.OpenFire mission.optionAlarm=ENUMS.AlarmState.Auto mission.optionFormation=Formation or "On Road" --mission.optionAttackFormation=Formation or "Wedge" - + mission.missionFraction=1.0 - + mission.categories={AUFTRAG.Category.GROUND} - + mission.DCStask=mission:GetDCSMissionTask() return mission @@ -1991,7 +1995,7 @@ end function AUFTRAG:NewFromTarget(Target, MissionType) local mission=nil --#AUFTRAG - + if MissionType==AUFTRAG.Type.ANTISHIP then mission=self:NewANTISHIP(Target, Altitude) elseif MissionType==AUFTRAG.Type.ARTY then @@ -2015,7 +2019,7 @@ function AUFTRAG:NewFromTarget(Target, MissionType) else return nil end - + return mission end @@ -2033,7 +2037,7 @@ function AUFTRAG:_DetermineAuftragType(Target) local auftrag=nil if Target:IsInstanceOf("GROUP") then - group=Target --Target is already a group. + group=Target --Target is already a group. elseif Target:IsInstanceOf("UNIT") then group=Target:GetGroup() elseif Target:IsInstanceOf("AIRBASE") then @@ -2041,69 +2045,69 @@ function AUFTRAG:_DetermineAuftragType(Target) elseif Target:IsInstanceOf("SCENERY") then scenery=Target end - + if group then local category=group:GetCategory() local attribute=group:GetAttribute() if category==Group.Category.AIRPLANE or category==Group.Category.HELICOPTER then - + --- -- A2A: Intercept --- - + auftrag=AUFTRAG.Type.INTERCEPT - + elseif category==Group.Category.GROUND or category==Group.Category.TRAIN then - + --- -- GROUND --- if attribute==GROUP.Attribute.GROUND_SAM then - + -- SEAD/DEAD - + auftrag=AUFTRAG.Type.SEAD - + elseif attribute==GROUP.Attribute.GROUND_AAA then - + auftrag=AUFTRAG.Type.BAI - + elseif attribute==GROUP.Attribute.GROUND_ARTILLERY then - + auftrag=AUFTRAG.Type.BAI - + elseif attribute==GROUP.Attribute.GROUND_INFANTRY then - + auftrag=AUFTRAG.Type.CAS - + elseif attribute==GROUP.Attribute.GROUND_TANK then - + auftrag=AUFTRAG.Type.BAI - + else auftrag=AUFTRAG.Type.BAI - + end - + elseif category==Group.Category.SHIP then - + --- -- NAVAL --- - + auftrag=AUFTRAG.Type.ANTISHIP - + else self:T(self.lid.."ERROR: Unknown Group category!") end - + elseif airbase then - auftrag=AUFTRAG.Type.BOMBRUNWAY + auftrag=AUFTRAG.Type.BOMBRUNWAY elseif scenery then auftrag=AUFTRAG.Type.STRIKE elseif coordinate then @@ -2120,11 +2124,11 @@ end function AUFTRAG:NewAUTO(EngageGroup) local mission=nil --#AUFTRAG - + local Target=EngageGroup local auftrag=self:_DetermineAuftragType(EngageGroup) - + if auftrag==AUFTRAG.Type.ANTISHIP then mission=AUFTRAG:NewANTISHIP(Target) elseif auftrag==AUFTRAG.Type.ARTY then @@ -2142,13 +2146,13 @@ function AUFTRAG:NewAUTO(EngageGroup) elseif auftrag==AUFTRAG.Type.CAP then mission=AUFTRAG:NewCAP(ZoneCAP,Altitude,Speed,Coordinate,Heading,Leg,TargetTypes) elseif auftrag==AUFTRAG.Type.CAS then - mission=AUFTRAG:NewCAS(ZoneCAS,Altitude,Speed,Coordinate,Heading,Leg,TargetTypes) + mission=AUFTRAG:NewCAS(ZoneCAS,Altitude,Speed,Coordinate,Heading,Leg,TargetTypes) elseif auftrag==AUFTRAG.Type.ESCORT then - mission=AUFTRAG:NewESCORT(EscortGroup,OffsetVector,EngageMaxDistance,TargetTypes) + mission=AUFTRAG:NewESCORT(EscortGroup,OffsetVector,EngageMaxDistance,TargetTypes) elseif auftrag==AUFTRAG.Type.FACA then mission=AUFTRAG:NewFACA(Target,Designation,DataLink,Frequency,Modulation) elseif auftrag==AUFTRAG.Type.FERRY then - -- Not implemented yet. + -- Not implemented yet. elseif auftrag==AUFTRAG.Type.GCICAP then mission=AUFTRAG:NewGCICAP(Coordinate,Altitude,Speed,Heading,Leg) elseif auftrag==AUFTRAG.Type.INTERCEPT then @@ -2156,7 +2160,7 @@ function AUFTRAG:NewAUTO(EngageGroup) elseif auftrag==AUFTRAG.Type.ORBIT then mission=AUFTRAG:NewORBIT(Coordinate,Altitude,Speed,Heading,Leg) elseif auftrag==AUFTRAG.Type.RECON then - -- Not implemented yet. + -- Not implemented yet. elseif auftrag==AUFTRAG.Type.RESCUEHELO then mission=AUFTRAG:NewRESCUEHELO(Carrier) elseif auftrag==AUFTRAG.Type.SEAD then @@ -2168,9 +2172,9 @@ function AUFTRAG:NewAUTO(EngageGroup) elseif auftrag==AUFTRAG.Type.TROOPTRANSPORT then mission=AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet,DropoffCoordinate,PickupCoordinate) else - + end - + if mission then mission:SetPriority(10, true) end @@ -2191,7 +2195,7 @@ function AUFTRAG:SetTime(ClockStart, ClockStop) -- Current mission time. local Tnow=timer.getAbsTime() - + -- Set start time. Default in 5 sec. local Tstart=Tnow+5 if ClockStart and type(ClockStart)=="number" then @@ -2207,13 +2211,13 @@ function AUFTRAG:SetTime(ClockStart, ClockStop) elseif ClockStop and type(ClockStop)=="string" then Tstop=UTILS.ClockToSeconds(ClockStop) end - + self.Tstart=Tstart self.Tstop=Tstop if Tstop then self.duration=self.Tstop-self.Tstart - end + end return self end @@ -2245,7 +2249,7 @@ function AUFTRAG:SetPushTime(ClockPush) return self end ---- Set mission priority and (optional) urgency. Urgent missions can cancel other running missions. +--- Set mission priority and (optional) urgency. Urgent missions can cancel other running missions. -- @param #AUFTRAG self -- @param #number Prio Priority 1=high, 100=low. Default 50. -- @param #boolean Urgent If *true*, another running mission might be cancelled if it has a lower priority. @@ -2293,7 +2297,7 @@ end function AUFTRAG:SetRequiredAssets(NassetsMin, NassetsMax) self.NassetsMin=NassetsMin or 1 - + self.NassetsMax=NassetsMax or self.NassetsMin -- Ensure that max is at least equal to min. @@ -2328,14 +2332,14 @@ end function AUFTRAG:SetRequiredEscorts(NescortMin, NescortMax) self.NescortMin=NescortMin or 1 - + self.NescortMax=NescortMax or self.NescortMin -- Ensure that max is at least equal to min. if self.NescortMaxself.Tstop then return false end - + -- All start conditions true? local startme=self:EvalConditionsAll(self.conditionStart) - + if not startme then return false end - + -- We're good to go! return true @@ -3179,7 +3183,7 @@ end -- @param #AUFTRAG self -- @return #boolean If true, mission should be cancelled. function AUFTRAG:IsReadyToCancel() - + local Tnow=timer.getAbsTime() -- Stop time already passed. @@ -3189,20 +3193,20 @@ function AUFTRAG:IsReadyToCancel() -- Evaluate failure condition. One is enough. local failure=self:EvalConditionsAny(self.conditionFailure) - + if failure then self.failurecondition=true return true - end - + end + -- Evaluate success consitions. One is enough. local success=self:EvalConditionsAny(self.conditionSuccess) - + if success then self.successcondition=true return true end - + -- No criterion matched. return false end @@ -3213,7 +3217,7 @@ end -- @param #AUFTRAG self -- @return #boolean If true, mission groups can push. function AUFTRAG:IsReadyToPush() - + local Tnow=timer.getAbsTime() -- Push time passed? @@ -3223,7 +3227,7 @@ function AUFTRAG:IsReadyToPush() -- Evaluate push condition(s) if any. All need to be true. local push=self:EvalConditionsAll(self.conditionPush) - + return push end @@ -3236,15 +3240,15 @@ function AUFTRAG:EvalConditionsAll(Conditions) -- Any stop condition must be true. for _,_condition in pairs(Conditions or {}) do local condition=_condition --#AUFTRAG.Condition - + -- Call function. local istrue=condition.func(unpack(condition.arg)) - + -- Any false will return false. if not istrue then return false end - + end -- All conditions were true. @@ -3261,15 +3265,15 @@ function AUFTRAG:EvalConditionsAny(Conditions) -- Any stop condition must be true. for _,_condition in pairs(Conditions or {}) do local condition=_condition --#AUFTRAG.Condition - + -- Call function. local istrue=condition.func(unpack(condition.arg)) - + -- Any true will return true. if istrue then return true end - + end -- No condition was true. @@ -3289,70 +3293,70 @@ function AUFTRAG:onafterStatus(From, Event, To) -- Current abs. mission time. local Tnow=timer.getAbsTime() - + -- ESCORT: Check if only the group NAME of an escort had been specified. if self.escortGroupName then -- Try to find the group. local group=GROUP:FindByName(self.escortGroupName) if group and group:IsAlive() then - + -- Debug info. - self:T(self.lid..string.format("ESCORT group %s is now alive. Updating DCS task and adding group to TARGET", tostring(self.escortGroupName))) - + self:T(self.lid..string.format("ESCORT group %s is now alive. Updating DCS task and adding group to TARGET", tostring(self.escortGroupName))) + -- Add TARGET object. self.engageTarget:AddObject(group) - + -- Update DCS task with the known group ID. self.DCStask=self:GetDCSMissionTask() - + -- Set value to nil so we do not do this again in the next cycle. - self.escortGroupName=nil + self.escortGroupName=nil end end -- Number of alive mission targets. local Ntargets=self:CountMissionTargets() local Ntargets0=self:GetTargetInitialNumber() - + -- Number of alive groups attached to this mission. local Ngroups=self:CountOpsGroups() -- Check if mission is not OVER yet. if self:IsNotOver() then - + if self:CheckGroupsDone() then - + -- All groups have reported MISSON DONE. self:Done() - + elseif (self.Tstop and Tnow>self.Tstop+10) then -- Cancel mission if stop time passed. self:Cancel() - + elseif self.durationExe and self.Texecuting and Tnow-self.Texecuting>self.durationExe then - + -- Backup repeat values local Nrepeat=self.Nrepeat local NrepeatS=self.NrepeatSuccess local NrepeatF=self.NrepeatFailure -- Cancel mission if stop time passed. - self:Cancel() - + self:Cancel() + self.Nrepeat=Nrepeat self.NrepeatSuccess=NrepeatS self.NrepeatFailure=NrepeatF - + elseif (Ntargets0>0 and Ntargets==0) then -- Cancel mission if mission targets are gone (if there were any in the beginning). -- TODO: I commented this out for some reason but I forgot why... self:T(self.lid.."No targets left cancelling mission!") self:Cancel() - + elseif self:IsExecuting() then - + -- Had the case that mission was in state Executing but all assigned groups were dead. -- TODO: might need to loop over all assigned groups if Ngroups==0 then @@ -3370,41 +3374,41 @@ function AUFTRAG:onafterStatus(From, Event, To) self:Done() end end - + end - + end - + -- Current FSM state. local fsmstate=self:GetState() - - -- Check for error. + + -- Check for error. if fsmstate~=self.status then self:T(self.lid..string.format("ERROR: FSM state %s != %s mission status!", fsmstate, self.status)) end - + -- General info. if self.verbose>=1 then - + -- Mission start stop time. local Cstart=UTILS.SecondsToClock(self.Tstart, true) local Cstop=self.Tstop and UTILS.SecondsToClock(self.Tstop, true) or "INF" - + local targetname=self:GetTargetName() or "unknown" - + local Nlegions=#self.legions local commander=self.commander and self.statusCommander or "N/A" local chief=self.chief and self.statusChief or "N/A" - + -- Info message. - self:T(self.lid..string.format("Status %s: Target=%s, T=%s-%s, assets=%d, groups=%d, targets=%d, legions=%d, commander=%s, chief=%s", + self:T(self.lid..string.format("Status %s: Target=%s, T=%s-%s, assets=%d, groups=%d, targets=%d, legions=%d, commander=%s, chief=%s", self.status, targetname, Cstart, Cstop, #self.assets, Ngroups, Ntargets, Nlegions, commander, chief)) end -- Group info. if self.verbose>=2 then -- Data on assigned groups. - local text="Group data:" + local text="Group data:" for groupname,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData text=text..string.format("\n- %s: status mission=%s opsgroup=%s", groupname, groupdata.status, groupdata.opsgroup and groupdata.opsgroup:GetState() or "N/A") @@ -3422,12 +3426,12 @@ function AUFTRAG:onafterStatus(From, Event, To) else self:__Status(-30) end - + -- Update F10 marker. if self.markerOn then self:UpdateMarker() end - + end --- Evaluate mission outcome - success or failure. @@ -3437,51 +3441,51 @@ function AUFTRAG:Evaluate() -- Assume success and check if any failed condition applies. local failed=false - + -- Target damage in %. local targetdamage=self:GetTargetDamage() - + -- Own damage in %. local owndamage=self.Ncasualties/self.Nelements*100 -- Current number of mission targets. local Ntargets=self:CountMissionTargets() local Ntargets0=self:GetTargetInitialNumber() - + local Life=self:GetTargetLife() local Life0=self:GetTargetInitialLife() - - + + if Ntargets0>0 then - + --- -- Mission had targets --- - + -- Check if failed. if self.type==AUFTRAG.Type.TROOPTRANSPORT or self.type==AUFTRAG.Type.ESCORT then - + -- Transported or escorted groups have to survive. if Ntargets0 then failed=true end - + end - + else --- @@ -3492,13 +3496,13 @@ function AUFTRAG:Evaluate() if self.Nelements==self.Ncasualties then failed=true end - + end -- Any success condition true? local successCondition=self:EvalConditionsAny(self.conditionSuccess) - + -- Any failure condition true? local failureCondition=self:EvalConditionsAny(self.conditionFailure) @@ -3507,14 +3511,14 @@ function AUFTRAG:Evaluate() elseif successCondition then failed=false end - + -- Debug text. if self.verbose > 0 then local text=string.format("Evaluating mission:\n") text=text..string.format("Own casualties = %d/%d\n", self.Ncasualties, self.Nelements) text=text..string.format("Own losses = %.1f %%\n", owndamage) text=text..string.format("Killed units = %d\n", self.Nkills) - text=text..string.format("--------------------------\n") + text=text..string.format("--------------------------\n") text=text..string.format("Targets left = %d/%d\n", Ntargets, Ntargets0) text=text..string.format("Targets life = %.1f/%.1f\n", Life, Life0) text=text..string.format("Enemy losses = %.1f %%\n", targetdamage) @@ -3524,9 +3528,9 @@ function AUFTRAG:Evaluate() text=text..string.format("--------------------------\n") text=text..string.format("Final Success = %s\n", tostring(not failed)) text=text..string.format("=========================") - self:I(self.lid..text) + self:I(self.lid..text) end - + -- Trigger events. if failed then self:I(self.lid..string.format("Mission %d [%s] failed!", self.auftragsnummer, self.type)) @@ -3539,7 +3543,7 @@ function AUFTRAG:Evaluate() if self.chief then self.chief.Nsuccess=self.chief.Nsuccess+1 end - self:Success() + self:Success() end return self @@ -3603,13 +3607,13 @@ function AUFTRAG:SetGroupStatus(opsgroup, status) self:T(self.lid.."WARNING: Could not SET flight data for flight group. Setting status to DONE") end end - + -- Check if mission is NOT over. local isNotOver=self:IsNotOver() - + -- Check if all assigned groups are done. local groupsDone=self:CheckGroupsDone() - + -- Debug info. self:T2(self.lid..string.format("Setting OPSGROUP %s status to %s. IsNotOver=%s CheckGroupsDone=%s", opsgroup.groupname, self:GetGroupStatus(opsgroup), tostring(self:IsNotOver()), tostring(groupsDone))) @@ -3619,8 +3623,8 @@ function AUFTRAG:SetGroupStatus(opsgroup, status) self:Done() else self:T3(self.lid.."Mission NOT DONE yet!") - end - + end + return self end @@ -3630,16 +3634,16 @@ end -- @return #string The group status. function AUFTRAG:GetGroupStatus(opsgroup) self:T3(self.lid..string.format("Trying to get Flight status for flight group %s", opsgroup and opsgroup.groupname or "nil")) - + local groupdata=self:GetGroupData(opsgroup) - + if groupdata then return groupdata.status else - + self:T(self.lid..string.format("WARNING: Could not GET groupdata for opsgroup %s. Returning status DONE.", opsgroup and opsgroup.groupname or "nil")) return AUFTRAG.GroupStatus.DONE - + end end @@ -3654,7 +3658,7 @@ function AUFTRAG:AddLegion(Legion) -- Add legion to table. table.insert(self.legions, Legion) - + return self end @@ -3669,12 +3673,12 @@ function AUFTRAG:RemoveLegion(Legion) local legion=self.legions[i] --Ops.Legion#LEGION if legion.alias==Legion.alias then -- Debug info. - self:T(self.lid..string.format("Removing legion %s", Legion.alias)) + self:T(self.lid..string.format("Removing legion %s", Legion.alias)) table.remove(self.legions, i) return self end end - + self:T(self.lid..string.format("ERROR: Legion %s not found and could not be removed!", Legion.alias)) return self end @@ -3823,11 +3827,11 @@ function AUFTRAG:CheckGroupsDone() if not (groupdata.status==AUFTRAG.GroupStatus.DONE or groupdata.status==AUFTRAG.GroupStatus.CANCELLED) then -- At least this flight is not DONE or CANCELLED. self:T(self.lid..string.format("CheckGroupsDone: OPSGROUP %s is not DONE or CANCELLED but in state %s. Mission NOT DONE!", groupdata.opsgroup.groupname, groupdata.status)) - return false + return false end end end - + -- Check status of all LEGIONs. for _,_legion in pairs(self.legions) do local legion=_legion --Ops.Legion#LEGION @@ -3838,7 +3842,7 @@ function AUFTRAG:CheckGroupsDone() return false end end - + -- Check commander status. if self.commander then if not self.statusCommander==AUFTRAG.Status.CANCELLED then @@ -3846,28 +3850,28 @@ function AUFTRAG:CheckGroupsDone() return false end end - + -- Check chief status. if self.chief then if not self.statusChief==AUFTRAG.Status.CANCELLED then - self:T(self.lid..string.format("CheckGroupsDone: CHIEF is not CANCELLED but in state %s. Mission NOT DONE!", self.statusChief)) + self:T(self.lid..string.format("CheckGroupsDone: CHIEF is not CANCELLED but in state %s. Mission NOT DONE!", self.statusChief)) return false end end - + -- These are early stages, where we might not even have a opsgroup defined to be checked. If there were any groups, we checked above. if self:IsPlanned() or self:IsQueued() or self:IsRequested() then self:T(self.lid..string.format("CheckGroupsDone: Mission is still in state %s [FSM=%s] (PLANNED or QUEUED or REQUESTED). Mission NOT DONE!", self.status, self:GetState())) return false end - + -- It could be that all flights were destroyed on the way to the mission execution waypoint. -- TODO: would be better to check if everybody is dead by now. if self:IsStarted() and self:CountOpsGroups()==0 then self:T(self.lid..string.format("CheckGroupsDone: Mission is STARTED state %s [FSM=%s] but count of alive OPSGROUP is zero. Mission DONE!", self.status, self:GetState())) return true end - + return true end @@ -3885,14 +3889,14 @@ function AUFTRAG:OnEventUnitLost(EventData) local unit=EventData.IniUnit local group=EventData.IniGroup local unitname=EventData.IniUnitName - + for _,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData if groupdata and groupdata.opsgroup and groupdata.opsgroup.groupname==EventData.IniGroupName then self:T(self.lid..string.format("UNIT LOST event for opsgroup %s unit %s", groupdata.opsgroup.groupname, EventData.IniUnitName)) end end - + end end @@ -3933,14 +3937,14 @@ function AUFTRAG:onafterRequested(From, Event, To) self:T(self.lid..string.format("New mission status=%s", self.status)) end ---- On after "Assign" event. +--- On after "Assign" event. -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. function AUFTRAG:onafterAssign(From, Event, To) self.status=AUFTRAG.Status.ASSIGNED - self:T(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Schedule" event. Mission is added to the mission queue of an OPSGROUP. @@ -3950,7 +3954,7 @@ end -- @param #string To To state. function AUFTRAG:onafterScheduled(From, Event, To) self.status=AUFTRAG.Status.SCHEDULED - self:T(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Start" event. @@ -3961,7 +3965,7 @@ end function AUFTRAG:onafterStarted(From, Event, To) self.status=AUFTRAG.Status.STARTED self.Tstarted=timer.getAbsTime() - self:T(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Execute" event. @@ -3972,7 +3976,7 @@ end function AUFTRAG:onafterExecuting(From, Event, To) self.status=AUFTRAG.Status.EXECUTING self.Texecuting=timer.getAbsTime() - self:T(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "ElementDestroyed" event. @@ -3998,7 +4002,7 @@ function AUFTRAG:onafterGroupDead(From, Event, To, OpsGroup) if asset then self:AssetDead(asset) end - + end --- On after "AssetDead" event. @@ -4008,25 +4012,25 @@ end -- @param #string To To state. -- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset. function AUFTRAG:onafterAssetDead(From, Event, To, Asset) - - -- Number of groups alive. + + -- Number of groups alive. local N=self:CountOpsGroups() - + self:T(self.lid..string.format("Asset %s dead! Number of ops groups remaining %d", tostring(Asset.spawngroupname), N)) - + -- All assets dead? if N==0 then - + if self:IsNotOver() then - + -- Cancel mission. Wait for next mission update to evaluate SUCCESS or FAILURE. self:Cancel() - + else - + --self:E(self.lid.."ERROR: All assets are dead not but mission was already over... Investigate!") -- Now this can happen, because when a opsgroup dies (sometimes!), the mission is DONE - + end end @@ -4047,59 +4051,59 @@ function AUFTRAG:onafterCancel(From, Event, To) -- Debug info. self:T(self.lid..string.format("CANCELLING mission in status %s. Will wait for %d groups to report mission DONE before evaluation", self.status, Ngroups)) - + -- Time stamp. self.Tover=timer.getAbsTime() - + -- No more repeats. self.Nrepeat=self.repeated self.NrepeatFailure=self.repeatedFailure self.NrepeatSuccess=self.repeatedSuccess - + -- Not necessary to delay the evaluaton?! self.dTevaluate=0 - + if self.chief then -- Debug info. self:T(self.lid..string.format("CHIEF will cancel the mission. Will wait for mission DONE before evaluation!")) - + -- CHIEF will cancel the mission. self.chief:MissionCancel(self) - + elseif self.commander then - + -- Debug info. self:T(self.lid..string.format("COMMANDER will cancel the mission. Will wait for mission DONE before evaluation!")) - + -- COMMANDER will cancel the mission. self.commander:MissionCancel(self) elseif self.legions and #self.legions>0 then - + -- Loop over all LEGIONs. for _,_legion in pairs(self.legions or {}) do local legion=_legion --Ops.Legion#LEGION - + -- Debug info. self:T(self.lid..string.format("LEGION %s will cancel the mission. Will wait for mission DONE before evaluation!", legion.alias)) - + -- Legion will cancel all flight missions and remove queued request from warehouse queue. legion:MissionCancel(self) - + end - - else - + + else + -- Debug info. self:T(self.lid..string.format("No legion, commander or chief. Attached flights will cancel the mission on their own. Will wait for mission DONE before evaluation!")) - + -- Loop over all groups. for _,_groupdata in pairs(self.groupdata or {}) do local groupdata=_groupdata --#AUFTRAG.GroupData groupdata.opsgroup:MissionCancel(self) end - + end -- Special mission states. @@ -4118,21 +4122,21 @@ end function AUFTRAG:onafterDone(From, Event, To) self.status=AUFTRAG.Status.DONE self:T(self.lid..string.format("New mission status=%s", self.status)) - + -- Set time stamp. self.Tover=timer.getAbsTime() - + -- Not executing any more. self.Texecuting=nil - + -- Set status for CHIEF, COMMANDER and LEGIONs - self.statusChief=AUFTRAG.Status.DONE - self.statusCommander=AUFTRAG.Status.DONE + self.statusChief=AUFTRAG.Status.DONE + self.statusCommander=AUFTRAG.Status.DONE for _,_legion in pairs(self.legions) do local Legion=_legion --Ops.Legion#LEGION self:SetLegionStatus(Legion, AUFTRAG.Status.DONE) end - + end --- On after "Success" event. @@ -4144,17 +4148,17 @@ function AUFTRAG:onafterSuccess(From, Event, To) self.status=AUFTRAG.Status.SUCCESS self:T(self.lid..string.format("New mission status=%s", self.status)) - + -- Set status for CHIEF, COMMANDER and LEGIONs - self.statusChief=self.status - self.statusCommander=self.status + self.statusChief=self.status + self.statusCommander=self.status for _,_legion in pairs(self.legions) do local Legion=_legion --Ops.Legion#LEGION self:SetLegionStatus(Legion, self.status) - end - + end + local repeatme=self.repeatedSuccess Repeat mission!", self.repeated+1, N)) self:Repeat() - + else - + -- Stop mission. self:T(self.lid..string.format("Mission SUCCESS! Number of max repeats %d reached ==> Stopping mission!", self.repeated+1)) self:Stop() - + end end @@ -4188,34 +4192,34 @@ function AUFTRAG:onafterFailed(From, Event, To) self:T(self.lid..string.format("New mission status=%s", self.status)) -- Set status for CHIEF, COMMANDER and LEGIONs - self.statusChief=self.status - self.statusCommander=self.status + self.statusChief=self.status + self.statusCommander=self.status for _,_legion in pairs(self.legions) do local Legion=_legion --Ops.Legion#LEGION self:SetLegionStatus(Legion, self.status) - end - + end + local repeatme=self.repeatedFailure Repeat mission!", self.repeated+1, N)) self:Repeat() - + else - + -- Stop mission. self:T(self.lid..string.format("Mission FAILED! Number of max repeats %d reached ==> Stopping mission!", self.repeated+1)) self:Stop() - - end + + end end @@ -4228,7 +4232,7 @@ function AUFTRAG:onbeforeRepeat(From, Event, To) if not (self.chief or self.commander or #self.legions>0) then self:E(self.lid.."ERROR: Mission can only be repeated by a CHIEF, COMMANDER or LEGION! Stopping AUFTRAG") - self:Stop() + self:Stop() return false end @@ -4244,69 +4248,69 @@ function AUFTRAG:onafterRepeat(From, Event, To) -- Set mission status to PLANNED. self.status=AUFTRAG.Status.PLANNED - + -- Debug info. self:T(self.lid..string.format("New mission status=%s (on Repeat)", self.status)) - + -- Set status for CHIEF, COMMANDER and LEGIONs - self.statusChief=self.status - self.statusCommander=self.status + self.statusChief=self.status + self.statusCommander=self.status for _,_legion in pairs(self.legions) do local Legion=_legion --Ops.Legion#LEGION self:SetLegionStatus(Legion, self.status) - end + end -- Increase repeat counter. self.repeated=self.repeated+1 - + if self.chief then - + self.statusChief=AUFTRAG.Status.PLANNED -- Remove mission from wingcommander because Chief will assign it again. if self.commander then self.commander:RemoveMission(self) self.statusCommander=AUFTRAG.Status.PLANNED - end - + end + -- Remove mission from airwing because WC will assign it again but maybe to a different wing. for _,_legion in pairs(self.legions) do local legion=_legion --Ops.Legion#LEGION legion:RemoveMission(self) - end - + end + elseif self.commander then - + self.statusCommander=AUFTRAG.Status.PLANNED - + -- Remove mission from airwing because WC will assign it again but maybe to a different wing. for _,_legion in pairs(self.legions) do local legion=_legion --Ops.Legion#LEGION legion:RemoveMission(self) self:SetLegionStatus(legion, AUFTRAG.Status.PLANNED) - end - + end + elseif #self.legions>0 then - + -- Remove mission from airwing because WC will assign it again but maybe to a different wing. for _,_legion in pairs(self.legions) do local legion=_legion --Ops.Legion#LEGION legion:RemoveMission(self) self:SetLegionStatus(legion, AUFTRAG.Status.PLANNED) legion:AddMission(self) - end - + end + else self:E(self.lid.."ERROR: Mission can only be repeated by a CHIEF, COMMANDER or LEGION! Stopping AUFTRAG") self:Stop() return end - - + + -- No mission assets. self.assets={} - - + + -- Remove OPS groups. This also removes the mission from the OPSGROUP mission queue. for groupname,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData @@ -4314,18 +4318,18 @@ function AUFTRAG:onafterRepeat(From, Event, To) if opsgroup then self:DelOpsGroup(opsgroup) end - - end + + end -- No flight data. self.groupdata={} - + -- Reset casualties and units assigned. self.Ncasualties=0 self.Nelements=0 - + -- Update DCS mission task. Could be that the initial task (e.g. for bombing) was destroyed. Then we need to update the coordinate. self.DCStask=self:GetDCSMissionTask() - + -- Call status again. self:__Status(-30) @@ -4340,19 +4344,19 @@ function AUFTRAG:onafterStop(From, Event, To) -- Debug info. self:T(self.lid..string.format("STOPPED mission in status=%s. Removing missions from queues. Stopping CallScheduler!", self.status)) - + -- TODO: Mission should be OVER! we dont want to remove running missions from any queues. - + -- Remove mission from CHIEF queue. if self.chief then self.chief:RemoveMission(self) end - + -- Remove mission from WINGCOMMANDER queue. if self.commander then self.commander:RemoveMission(self) end - + -- Remove mission from LEGION queues. if #self.legions>0 then for _,_legion in pairs(self.legions) do @@ -4369,13 +4373,13 @@ function AUFTRAG:onafterStop(From, Event, To) -- No mission assets. self.assets={} - + -- No flight data. self.groupdata={} -- Clear pending scheduler calls. self.CallScheduler:Clear() - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -4388,26 +4392,26 @@ end function AUFTRAG:_TargetFromObject(Object) if not self.engageTarget then - + if Object and Object:IsInstanceOf("TARGET") then - + self.engageTarget=Object - + else --if Object then - + self.engageTarget=TARGET:New(Object) - - end - + + end + else - + -- Target was already specified elsewhere. - + end - + -- Debug info. --self:T2(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", self.engageTarget.lid, self.engageTarget.lid, self.engageTarget.N0, self.engageTarget:GetLife())) - + return self end @@ -4418,11 +4422,11 @@ end function AUFTRAG:CountMissionTargets() local N=0 - + if self.engageTarget then N=self.engageTarget:CountTargets() end - + return N end @@ -4524,23 +4528,23 @@ end -- @param #AUFTRAG self -- @return Core.Point#COORDINATE The target coordinate or *nil*. function AUFTRAG:GetTargetCoordinate() - + if self.transportPickup then - - -- Special case where we defined a + + -- Special case where we defined a return self.transportPickup - + elseif self.engageTarget then local coord=self.engageTarget:GetCoordinate() return coord - + elseif self.type==AUFTRAG.Type.ALERT5 then - + -- For example, COMMANDER will not assign a coordiante. This will be done later, when the mission is assigned to an airwing. return nil - - else + + else self:T(self.lid.."ERROR: Cannot get target coordinate!") end @@ -4551,12 +4555,12 @@ end -- @param #AUFTRAG self -- @return #string Name of the target or "N/A". function AUFTRAG:GetTargetName() - + if self.engageTarget then local name=self.engageTarget:GetName() return name end - + return "N/A" end @@ -4568,13 +4572,13 @@ end function AUFTRAG:GetTargetDistance(FromCoord) local TargetCoord=self:GetTargetCoordinate() - + if TargetCoord and FromCoord then return TargetCoord:Get2DDistance(FromCoord) else self:T(self.lid.."ERROR: TargetCoord or FromCoord does not exist in AUFTRAG:GetTargetDistance() function! Returning 0") end - + return 0 end @@ -4607,13 +4611,13 @@ function AUFTRAG:DelAsset(Asset) for i,_asset in pairs(self.assets or {}) do local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem - + if asset.uid==Asset.uid then self:T(self.lid..string.format("Removing asset \"%s\" from mission", tostring(Asset.spawngroupname))) table.remove(self.assets, i) return self end - + end return self @@ -4627,11 +4631,11 @@ function AUFTRAG:GetAssetByName(Name) for i,_asset in pairs(self.assets or {}) do local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem - + if asset.spawngroupname==Name then return asset end - + end return nil @@ -4672,7 +4676,7 @@ end -- @return #AUFTRAG self function AUFTRAG:SetMissionWaypointCoord(Coordinate) - -- Obviously a zone was passed. We get the coordinate. + -- Obviously a zone was passed. We get the coordinate. if Coordinate:IsInstanceOf("ZONE_BASE") then Coordinate=Coordinate:GetCoordinate() end @@ -4693,17 +4697,17 @@ end --- Set the mission egress coordinate. This is the coordinate where the assigned group will go once the mission is finished. -- @param #AUFTRAG self -- @param Core.Point#COORDINATE Coordinate Egrees coordinate. --- @param #number Altitude (Optional) Altitude in feet. Default is y component of coordinate. +-- @param #number Altitude (Optional) Altitude in feet. Default is y component of coordinate. -- @return #AUFTRAG self function AUFTRAG:SetMissionEgressCoord(Coordinate, Altitude) - -- Obviously a zone was passed. We get the coordinate. + -- Obviously a zone was passed. We get the coordinate. if Coordinate:IsInstanceOf("ZONE_BASE") then Coordinate=Coordinate:GetCoordinate() end self.missionEgressCoord=Coordinate - + if Altitude then self.missionEgressCoord.y=UTILS.FeetToMeters(Altitude) end @@ -4734,14 +4738,14 @@ function AUFTRAG:GetMissionWaypointCoord(group, randomradius, surfacetypes) end -- Create waypoint coordinate half way between us and the target. - local waypointcoord=group:GetCoordinate():GetIntermediateCoordinate(self:GetTargetCoordinate(), self.missionFraction) + local waypointcoord=group:GetCoordinate():GetIntermediateCoordinate(self:GetTargetCoordinate(), self.missionFraction) local alt=waypointcoord.y - + -- Add some randomization. if randomradius then waypointcoord=ZONE_RADIUS:New("Temp", waypointcoord:GetVec2(), randomradius):GetRandomCoordinate(nil, nil, surfacetypes):SetAltitude(alt, false) end - + -- Set altitude of mission waypoint. if self.missionAltitude then waypointcoord:SetAltitude(self.missionAltitude, true) @@ -4771,22 +4775,22 @@ function AUFTRAG:UpdateMarker() text=text..string.format("\nOpsGroups %d/%d", self:CountOpsGroups(), self:GetNumberOfRequiredAssets()) if not self.marker then - + -- Get target coordinates. Can be nil! local targetcoord=self:GetTargetCoordinate() - + if self.markerCoaliton and self.markerCoaliton>=0 then self.marker=MARKER:New(targetcoord, text):ReadOnly():ToCoalition(self.markerCoaliton) else self.marker=MARKER:New(targetcoord, text):ReadOnly():ToAll() - end - + end + else - + if self.marker:GetText()~=text then self.marker:UpdateText(text) end - + end return self @@ -4802,109 +4806,109 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) -- Create DCS task based on current self. if self.type==AUFTRAG.Type.ANTISHIP then - + ---------------------- -- ANTISHIP Mission -- ---------------------- self:_GetDCSAttackTask(self.engageTarget, DCStasks) - + elseif self.type==AUFTRAG.Type.AWACS then - + ------------------- -- AWACS Mission -- - ------------------- + ------------------- local DCStask=CONTROLLABLE.EnRouteTaskAWACS(nil) - + table.insert(self.enrouteTasks, DCStask) - + elseif self.type==AUFTRAG.Type.BAI then - + ----------------- -- BAI Mission -- - ----------------- + ----------------- self:_GetDCSAttackTask(self.engageTarget, DCStasks) elseif self.type==AUFTRAG.Type.BOMBING then - + --------------------- -- BOMBING Mission -- --------------------- - + local DCStask=CONTROLLABLE.TaskBombing(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType, Divebomb) - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.BOMBRUNWAY then - + ------------------------ -- BOMBRUNWAY Mission -- ------------------------ - + local DCStask=CONTROLLABLE.TaskBombingRunway(nil, self.engageTarget:GetObject(), self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAsGroup) - - table.insert(DCStasks, DCStask) + + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.BOMBCARPET then - + ------------------------ -- BOMBCARPET Mission -- ------------------------ - + local DCStask=CONTROLLABLE.TaskCarpetBombing(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType, self.engageCarpetLength) - - table.insert(DCStasks, DCStask) + + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.CAP then - + ----------------- -- CAP Mission -- - ----------------- + ----------------- local DCStask=CONTROLLABLE.EnRouteTaskEngageTargetsInZone(nil, self.engageZone:GetVec2(), self.engageZone:GetRadius(), self.engageTargetTypes, Priority) - + table.insert(self.enrouteTasks, DCStask) - + elseif self.type==AUFTRAG.Type.CAS then - + ----------------- -- CAS Mission -- ----------------- local DCStask=CONTROLLABLE.EnRouteTaskEngageTargetsInZone(nil, self.engageZone:GetVec2(), self.engageZone:GetRadius(), self.engageTargetTypes, Priority) - + table.insert(self.enrouteTasks, DCStask) elseif self.type==AUFTRAG.Type.ESCORT then - + -------------------- -- ESCORT Mission -- -------------------- local DCStask=CONTROLLABLE.TaskEscort(nil, self.engageTarget:GetObject(), self.escortVec3, LastWaypointIndex, self.engageMaxDistance, self.engageTargetTypes) - + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.FACA then - + ----------------- -- FAC Mission -- - ----------------- + ----------------- local DCStask=CONTROLLABLE.TaskFAC_AttackGroup(nil, self.engageTarget:GetObject(), self.engageWeaponType, self.facDesignation, self.facDatalink, self.facFreq, self.facModu, CallsignName, CallsignNumber) - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.FERRY then - + ------------------- -- FERRY Mission -- ------------------- - + -- TODO: Ferry mission type. How? - + elseif self.type==AUFTRAG.Type.INTERCEPT then ----------------------- @@ -4914,88 +4918,88 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) self:_GetDCSAttackTask(self.engageTarget, DCStasks) elseif self.type==AUFTRAG.Type.ORBIT then - + ------------------- -- ORBIT Mission -- ------------------- - + -- Done below as also other mission types use the orbit task. elseif self.type==AUFTRAG.Type.GCICAP then - + -------------------- -- GCICAP Mission -- -------------------- - + -- Done below as also other mission types use the orbit task. - + elseif self.type==AUFTRAG.Type.RECON then - + ------------------- -- RECON Mission -- - ------------------- - + ------------------- + local DCStask={} - + DCStask.id="ReconMission" - + -- We create a "fake" DCS task and pass the parameters to the OPSGROUP. local param={} param.target=self.engageTarget param.altitude=self.missionAltitude - param.speed=self.missionSpeed - param.lastindex=nil - + param.speed=self.missionSpeed + param.lastindex=nil + DCStask.params=param - - table.insert(DCStasks, DCStask) + + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.SEAD then - + ------------------ -- SEAD Mission -- - ------------------ + ------------------ --[[ local DCStask=CONTROLLABLE.EnRouteTaskEngageTargets(nil, nil ,{"Air Defence"} , 0) table.insert(self.enrouteTasks, DCStask) DCStask.key="SEAD" ]] - + self:_GetDCSAttackTask(self.engageTarget, DCStasks) - + elseif self.type==AUFTRAG.Type.STRIKE then - + -------------------- -- STRIKE Mission -- - -------------------- - + -------------------- + local DCStask=CONTROLLABLE.TaskAttackMapObject(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType) - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.TANKER then - + -------------------- -- TANKER Mission -- - -------------------- + -------------------- local DCStask=CONTROLLABLE.EnRouteTaskTanker(nil) - - table.insert(self.enrouteTasks, DCStask) - + + table.insert(self.enrouteTasks, DCStask) + elseif self.type==AUFTRAG.Type.TROOPTRANSPORT then ---------------------------- -- TROOPTRANSPORT Mission -- ---------------------------- - + -- Task to embark the troops at the pick up point. local TaskEmbark=CONTROLLABLE.TaskEmbarking(TaskControllable, self.transportPickup, self.transportGroupSet, self.transportWaitForCargo) - + -- Task to disembark the troops at the drop off point. - local TaskDisEmbark=CONTROLLABLE.TaskDisembarking(TaskControllable, self.transportDropoff, self.transportGroupSet) - + local TaskDisEmbark=CONTROLLABLE.TaskDisembarking(TaskControllable, self.transportDropoff, self.transportGroupSet) + table.insert(DCStasks, TaskEmbark) table.insert(DCStasks, TaskDisEmbark) @@ -5006,26 +5010,26 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) -------------------------- local DCStask={} - + DCStask.id="OpsTransport" - + -- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP. - local param={} + local param={} DCStask.params=param - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.RESCUEHELO then ------------------------- -- RESCUE HELO Mission -- ------------------------- - + local DCStask={} - + DCStask.id="Formation" - + -- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP. local param={} param.unitname=self:GetTargetName() @@ -5033,9 +5037,9 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) param.offsetZ=240 param.altitude=70 param.dtFollow=1.0 - + DCStask.params=param - + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.ARTY then @@ -5043,11 +5047,11 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) ------------------ -- ARTY Mission -- ------------------ - + local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, self:GetTargetVec2(), self.artyRadius, self.artyShots, self.engageWeaponType, self.artyAltitude) - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.BARRAGE then --------------------- @@ -5055,9 +5059,9 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) --------------------- local DCStask={} - + DCStask.id=AUFTRAG.SpecialTask.BARRAGE - + -- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP. local param={} param.zone=self:GetObjective() @@ -5067,9 +5071,9 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) param.angle=self.artyAngle param.shots=self.artyShots param.weaponTypoe=self.engageWeaponType - + DCStask.params=param - + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.PATROLZONE then @@ -5077,19 +5081,19 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) ------------------------- -- PATROL ZONE Mission -- ------------------------- - + local DCStask={} - + DCStask.id="PatrolZone" - + -- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP. local param={} param.zone=self:GetObjective() param.altitude=self.missionAltitude param.speed=self.missionSpeed - + DCStask.params=param - + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.CASENHANCED then @@ -5097,77 +5101,79 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) ------------------------- -- CAS ENHANCED Mission -- ------------------------- - + local DCStask={} - + DCStask.id="PatrolZone" - + -- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP. local param={} param.zone=self:GetObjective() param.altitude=self.missionAltitude param.speed=self.missionSpeed - + DCStask.params=param - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.ARMORATTACK then ------------------------- -- ARMOR ATTACK Mission -- ------------------------- - + local DCStask={} - + DCStask.id=AUFTRAG.SpecialTask.ARMORATTACK - + -- We create a "fake" DCS task and pass the parameters to the ARMYGROUP. local param={} param.zone=self:GetObjective() + param.tVec2=param.zone:GetVec2() + param.tzone=ZONE_RADIUS:New("ARMORATTACK-Zone-"..self.auftragsnummer,param.tVec2,1000) param.action="Wedge" param.speed=self.missionSpeed - + DCStask.params=param - - table.insert(DCStasks, DCStask) + + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.GROUNDATTACK then --------------------------- -- GROUND ATTACK Mission -- --------------------------- - + local DCStask={} - + DCStask.id=AUFTRAG.SpecialTask.GROUNDATTACK - + -- We create a "fake" DCS task and pass the parameters to the ARMYGROUP. local param={} param.target=self:GetTargetData() param.action="Wedge" param.speed=self.missionSpeed - + DCStask.params=param - - table.insert(DCStasks, DCStask) + + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.AMMOSUPPLY then ------------------------- -- AMMO SUPPLY Mission -- ------------------------- - + local DCStask={} - + DCStask.id=AUFTRAG.SpecialTask.AMMOSUPPLY - + -- We create a "fake" DCS task and pass the parameters to the OPSGROUP. local param={} param.zone=self:GetObjective() - + DCStask.params=param - + table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.FUELSUPPLY then @@ -5175,113 +5181,113 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) ------------------------- -- FUEL SUPPLY Mission -- ------------------------- - + local DCStask={} - + DCStask.id=AUFTRAG.SpecialTask.FUELSUPPLY - + -- We create a "fake" DCS task and pass the parameters to the OPSGROUP. local param={} param.zone=self:GetObjective() - + DCStask.params=param - + table.insert(DCStasks, DCStask) - + elseif self.type==AUFTRAG.Type.ALERT5 then --------------------- -- ALERT 5 Mission -- --------------------- - + local DCStask={} - + DCStask.id=AUFTRAG.SpecialTask.ALERT5 - + -- We create a "fake" DCS task and pass the parameters to the OPSGROUP. local param={} - + DCStask.params=param - - table.insert(DCStasks, DCStask) - + + table.insert(DCStasks, DCStask) + elseif self.type==AUFTRAG.Type.HOVER then --------------------- -- HOVER Mission -- --------------------- - + local DCStask={} DCStask.id=AUFTRAG.SpecialTask.HOVER - + local param={} - + param.hoverAltitude=self.hoverAltitude param.hoverTime = self.hoverTime param.missionSpeed = self.missionSpeed param.missionAltitude = self.missionAltitude - + DCStask.params=param - + --[[ Task script. local DCSScript = {} - + local altitude = self.hoverAltitude DCSScript[#DCSScript+1] = 'local group = ...' DCSScript[#DCSScript+1] = 'local helo = GROUP:Find(group)' DCSScript[#DCSScript+1] = 'helo:SetSpeed(0.1,true)' DCSScript[#DCSScript+1] = string.format('helo:SetAltitude(UTILS.FeetToMeters(%d),true,"BARO")',altitude) -- Call the function, e.g. myfunction.(warehouse,mygroup) - + -- Create task. local DCSTask=CONTROLLABLE.TaskWrappedAction(self, CONTROLLABLE.CommandDoScript(self, table.concat(DCSScript))) - --]] - - table.insert(DCStasks, DCStask) - + --]] + + table.insert(DCStasks, DCStask) + elseif self.type==AUFTRAG.Type.ONGUARD or self.type==AUFTRAG.Type.ARMOREDGUARD then ---------------------- -- ON GUARD Mission -- ---------------------- - + local DCStask={} - + DCStask.id= self.type==AUFTRAG.Type.ONGUARD and AUFTRAG.SpecialTask.ONGUARD or AUFTRAG.SpecialTask.ARMOREDGUARD - + -- We create a "fake" DCS task and pass the parameters to the OPSGROUP. local param={} param.coordinate=self:GetObjective() - + DCStask.params=param - - table.insert(DCStasks, DCStask) - + + table.insert(DCStasks, DCStask) + else self:T(self.lid..string.format("ERROR: Unknown mission task!")) return nil end - - + + -- Set ORBIT task. Also applies to other missions: AWACS, TANKER, CAP, CAS. - if self.type==AUFTRAG.Type.ORBIT or + if self.type==AUFTRAG.Type.ORBIT or self.type==AUFTRAG.Type.CAP or self.type==AUFTRAG.Type.CAS or self.type==AUFTRAG.Type.GCICAP or - self.type==AUFTRAG.Type.AWACS or + self.type==AUFTRAG.Type.AWACS or self.type==AUFTRAG.Type.TANKER then ------------------- -- ORBIT Mission -- ------------------- - + local Coordinate=self:GetTargetCoordinate() - + local DCStask=CONTROLLABLE.TaskOrbit(nil, Coordinate, self.orbitAltitude, self.orbitSpeed, self.orbitRaceTrack) - + table.insert(DCStasks, DCStask) - + end - + -- Debug info. self:T3({missiontask=DCStasks}) @@ -5302,26 +5308,26 @@ end function AUFTRAG:_GetDCSAttackTask(Target, DCStasks) DCStasks=DCStasks or {} - + for _,_target in pairs(Target.targets) do local target=_target --Ops.Target#TARGET.Object if target.Type==TARGET.ObjectType.GROUP then - + local DCStask=CONTROLLABLE.TaskAttackGroup(nil, target.Object, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageAsGroup) - + table.insert(DCStasks, DCStask) - + elseif target.Type==TARGET.ObjectType.UNIT or target.Type==TARGET.ObjectType.STATIC then - + local DCStask=CONTROLLABLE.TaskAttackUnit(nil, target.Object, self.engageAsGroup, self.WeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType) - + table.insert(DCStasks, DCStask) - + end - + end - + return DCStasks end @@ -5332,7 +5338,7 @@ end function AUFTRAG:GetMissionTaskforMissionType(MissionType) local mtask=ENUMS.MissionTask.NOTHING - + if MissionType==AUFTRAG.Type.ANTISHIP then mtask=ENUMS.MissionTask.ANTISHIPSTRIKE elseif MissionType==AUFTRAG.Type.AWACS then @@ -5399,7 +5405,7 @@ function AUFTRAG.CheckMissionType(MissionType, PossibleTypes) for _,canmission in pairs(PossibleTypes) do if canmission==MissionType then return true - end + end end return false @@ -5427,7 +5433,7 @@ function AUFTRAG.CheckMissionCapability(MissionTypes, Capabilities, All) else if capability.MissionType==MissionType then return true - end + end end end end @@ -5447,7 +5453,7 @@ end function AUFTRAG.CheckMissionCapabilityAny(MissionTypes, Capabilities) local res=AUFTRAG.CheckMissionCapability(MissionTypes, Capabilities, false) - + return res end @@ -5459,7 +5465,7 @@ end function AUFTRAG.CheckMissionCapabilityAll(MissionTypes, Capabilities) local res=AUFTRAG.CheckMissionCapability(MissionTypes, Capabilities, true) - + return res end diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 4ae5f4720..de3225630 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -870,8 +870,12 @@ do -- -- ## 5. Support for Hercules mod by Anubis -- --- Basic support for the Hercules mod By Anubis has been build into CTLD. Currently this does **not** cover objects and troops which can --- be loaded from the Rearm/Refuel menu, i.e. you can drop them into the field, but you cannot use them in functions scripted with this class. +-- Basic support for the Hercules mod By Anubis has been build into CTLD - that is you can load/drop/build the same objects as the helicopters. +-- To also cover objects and troops which can be loaded from the groud crew Rearm/Refuel menu, you need to use @{#CTLD_HERCULES.New}() and link +-- this object to your CTLD setup. In this case, do **not** use the `Hercules_Cargo.lua` or `Hercules_Cargo_CTLD.lua` which are part of the mod +-- in your mission! +-- +-- ### 5.1 Create an own CTLD instance and allow the usage of the Hercules mod: -- -- local my_ctld = CTLD:New(coalition.side.BLUE,{"Helicargo", "Hercules"},"Lufttransportbrigade I") -- @@ -882,10 +886,33 @@ do -- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft -- my_ctld.HercMaxSpeed = 77 -- 77mps or 270kph or 150kn -- +-- Hint: you can **only** airdrop from the Hercules if you are "in parameters", i.e. at or below `HercMaxSpeed` and in the AGL bracket between +-- `HercMinAngels` and `HercMaxAngels`! +-- -- Also, the following options need to be set to `true`: -- -- my_ctld.useprefix = true -- this is true by default and MUST BE ON. -- +-- ### 5.2 Integrate Hercules ground crew loadable objects +-- +-- Add ground crew loadable objects to your CTLD instance like so, where `my_ctld` is the previously created CTLD instance: +-- +-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld) +-- +-- You also need: +-- +-- * A template called "Infantry" for 10 Paratroopers (as set via herccargo.infantrytemplate). +-- * Depending on what you are loading with the help of the ground crew, there are 42 more templates for the various vehicles that are loadable. +-- +-- There's a **quick check output in the `dcs.log`** which tells you what's there and what not. +-- E.g.: +-- ...Checking template for APC BTR-82A Air [24998lb] (BTR-82A) ... MISSING) +-- ...Checking template for ART 2S9 NONA Skid [19030lb] (SAU 2-C9) ... MISSING) +-- ...Checking template for EWR SBORKA Air [21624lb] (Dog Ear radar) ... MISSING) +-- ...Checking template for Transport Tigr Air [15900lb] (Tigr_233036) ... OK) +-- +-- Expected template names are the ones in the rounded brackets. +-- -- Standard transport capabilities as per the real Hercules are: -- -- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers @@ -3787,8 +3814,8 @@ end local ucoord = Unit:GetCoordinate() local gheight = ucoord:GetLandHeight() local aheight = uheight - gheight -- height above ground - local maxh = self.HercMinAngels-- 1500m - local minh = self.HercMaxAngels -- 5000m + local minh = self.HercMinAngels-- 1500m + local maxh = self.HercMaxAngels -- 5000m local maxspeed = self.HercMaxSpeed -- 77 mps -- DONE: TEST - Speed test for Herc, should not be above 280kph/150kn local kmspeed = uspeed * 3.6 diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 085063d6a..4634143cc 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -4748,11 +4748,15 @@ function OPSGROUP:RouteToMission(mission, delay) local armorwaypointcoord = nil if mission.type==AUFTRAG.Type.ARMORATTACK then local target=mission.engageTarget:GetObject() -- Wrapper.Positionable#POSITIONABLE - local zone = ZONE_RADIUS:New("AttackZone",target:GetVec2(),1000) + --BASE:I({mission.DCStask}) + --BASE:I({mission.DCStask.params}) + --local zone = ZONE_RADIUS:New("AttackZone",target:GetVec2(),1000) + local zone = mission.DCStask.params.tzone -- Core.Zone#ZONE_RADIUS -- final WP waypointcoord=zone:GetRandomCoordinate(0, 100, surfacetypes) -- Core.Point#COORDINATE -- Ingress - add formation to this one armorwaypointcoord = zone:GetRandomCoordinate(1000, 500, surfacetypes) -- Core.Point#COORDINATE + self:__EngageTarget(2,target) end -- Add enroute tasks. diff --git a/Moose Development/Moose/Ops/Target.lua b/Moose Development/Moose/Ops/Target.lua index 1ecece092..a71b5fed8 100644 --- a/Moose Development/Moose/Ops/Target.lua +++ b/Moose Development/Moose/Ops/Target.lua @@ -990,8 +990,12 @@ function TARGET:GetTargetVec3(Target) if object and object:IsAlive() then local vec3=object:GetVec3() - return vec3 + if vec3 then + return vec3 + else + return nil + end else return nil diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index 59ffbad8d..84ee9cf83 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -316,6 +316,9 @@ AIRBASE.PersianGulf = { -- * AIRBASE.TheChannel.Lympne -- * AIRBASE.TheChannel.Detling -- * AIRBASE.TheChannel.High_Halden +-- * AIRBASE.TheChannel.Biggin_Hill +-- * AIRBASE.TheChannel.Eastchurch +-- * AIRBASE.TheChannel.Headcorn -- -- @field TheChannel AIRBASE.TheChannel = { @@ -328,6 +331,9 @@ AIRBASE.TheChannel = { ["Lympne"] = "Lympne", ["Detling"] = "Detling", ["High_Halden"] = "High Halden", + ["Biggin_Hill"] = "Biggin Hill", + ["Eastchurch"] = "Eastchurch", + ["Headcorn"] = "Headcorn", } --- Airbases of the Syria map: @@ -346,7 +352,6 @@ AIRBASE.TheChannel = { -- * AIRBASE.Syria.Wujah_Al_Hajar -- * AIRBASE.Syria.Al_Dumayr -- * AIRBASE.Syria.Gazipasa --- * AIRBASE.Syria.Ru_Convoy_4 -- * AIRBASE.Syria.Hatay -- * AIRBASE.Syria.Nicosia -- * AIRBASE.Syria.Pinarbashi @@ -364,7 +369,6 @@ AIRBASE.TheChannel = { -- * AIRBASE.Syria.Akrotiri -- * AIRBASE.Syria.Naqoura -- * AIRBASE.Syria.Gaziantep --- * AIRBASE.Syria.CVN_71 -- * AIRBASE.Syria.Sayqal -- * AIRBASE.Syria.Tiyas -- * AIRBASE.Syria.Shayrat @@ -412,7 +416,7 @@ AIRBASE.Syria={ ["Wujah_Al_Hajar"]="Wujah Al Hajar", ["Al_Dumayr"]="Al-Dumayr", ["Gazipasa"]="Gazipasa", - ["Ru_Convoy_4"]="Ru Convoy-4", + --["Ru_Convoy_4"]="Ru Convoy-4", ["Hatay"]="Hatay", ["Nicosia"]="Nicosia", ["Pinarbashi"]="Pinarbashi", @@ -460,6 +464,7 @@ AIRBASE.Syria={ ["Ruwayshid"]="Ruwayshid", ["Sanliurfa"]="Sanliurfa", ["Tal_Siman"]="Tal Siman", + ["Deir_ez-Zor"] = "Deir ez-Zor", } --- Airbases of the Mariana Islands map: