This commit is contained in:
Frank 2023-10-31 10:45:58 +01:00
commit 059d8ccfc0
21 changed files with 694 additions and 126 deletions

View File

@ -67,3 +67,12 @@ jobs:
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@v1 uses: actions/deploy-pages@v1
check:
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Setup Node
uses: actions/setup-node@v3
- run: npm install linkinator
- run: npx linkinator https://flightcontrol-master.github.io/MOOSE/ --recurse

2
.gitignore vendored
View File

@ -234,3 +234,5 @@ MooseCodeWS.code-workspace
# Excludes for act (https://github.com/nektos/act) # Excludes for act (https://github.com/nektos/act)
.secrets .secrets
.env .env
.actrc
.vars

View File

@ -135,6 +135,22 @@ do -- env
end -- env end -- env
do -- radio
---@type radio
-- @field #radio.modulation modulation
---
-- @type radio.modulation
-- @field AM
-- @field FM
radio = {}
radio.modulation = {}
radio.modulation.AM = 0
radio.modulation.FM = 1
end
do -- timer do -- timer
@ -329,11 +345,11 @@ end -- country
do -- Command do -- Command
--- @type Command -- @type Command
-- @field #string id -- @field #string id
-- @field #Command.params params -- @field #Command.params params
--- @type Command.params -- @type Command.params
end -- Command end -- Command
@ -374,7 +390,7 @@ end -- coalition
do -- Types do -- Types
--- @type Desc -- @type Desc
-- @field #number speedMax0 Max speed in meters/second at zero altitude. -- @field #number speedMax0 Max speed in meters/second at zero altitude.
-- @field #number massEmpty Empty mass in kg. -- @field #number massEmpty Empty mass in kg.
-- @field #number tankerType Type of refueling system: 0=boom, 1=probe. -- @field #number tankerType Type of refueling system: 0=boom, 1=probe.
@ -471,16 +487,16 @@ do -- Types
-- @type AttributeNameArray -- @type AttributeNameArray
-- @list <#AttributeName> -- @list <#AttributeName>
--- @type Zone -- @type Zone
-- @field DCSVec3#Vec3 point -- @field DCSVec3#Vec3 point
-- @field #number radius -- @field #number radius
Zone = {} Zone = {}
--- @type ModelTime -- @type ModelTime
-- @extends #number -- @extends #number
--- @type Time -- @type Time
-- @extends #number -- @extends #number
--- A task descriptor (internal structure for DCS World). See [https://wiki.hoggitworld.com/view/Category:Tasks](https://wiki.hoggitworld.com/view/Category:Tasks). --- A task descriptor (internal structure for DCS World). See [https://wiki.hoggitworld.com/view/Category:Tasks](https://wiki.hoggitworld.com/view/Category:Tasks).
@ -489,7 +505,7 @@ do -- Types
-- @field #string id -- @field #string id
-- @field #Task.param param -- @field #Task.param param
--- @type Task.param -- @type Task.param
--- List of @{#Task} --- List of @{#Task}
-- @type TaskArray -- @type TaskArray
@ -536,7 +552,7 @@ do -- Object
-- @field SCENERY -- @field SCENERY
-- @field CARGO -- @field CARGO
--- @type Object.Desc -- @type Object.Desc
-- @extends #Desc -- @extends #Desc
-- @field #number life initial life level -- @field #number life initial life level
-- @field #Box3 box bounding box of collision geometry -- @field #Box3 box bounding box of collision geometry
@ -1085,7 +1101,7 @@ end -- Controller
do -- Unit do -- Unit
--- @type Unit -- @type Unit
-- @extends #CoalitionObject -- @extends #CoalitionObject
-- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically. -- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically.
-- @field #Unit.Category Category -- @field #Unit.Category Category
@ -1200,15 +1216,18 @@ do -- Unit
-- @field #Distance detectionDistanceHRM detection distance for RCS=1m^2 in high-resolution mapping mode, nil if radar has no HRM -- @field #Distance detectionDistanceHRM detection distance for RCS=1m^2 in high-resolution mapping mode, nil if radar has no HRM
-- @field #Unit.Radar.detectionDistanceAir detectionDistanceAir detection distance for RCS=1m^2 airborne target, nil if radar doesn't support air search -- @field #Unit.Radar.detectionDistanceAir detectionDistanceAir detection distance for RCS=1m^2 airborne target, nil if radar doesn't support air search
--- @type Unit.Radar.detectionDistanceAir --- A radar.
-- @type Unit.Radar.detectionDistanceAir
-- @field #Unit.Radar.detectionDistanceAir.upperHemisphere upperHemisphere -- @field #Unit.Radar.detectionDistanceAir.upperHemisphere upperHemisphere
-- @field #Unit.Radar.detectionDistanceAir.lowerHemisphere lowerHemisphere -- @field #Unit.Radar.detectionDistanceAir.lowerHemisphere lowerHemisphere
--- @type Unit.Radar.detectionDistanceAir.upperHemisphere --- A radar.
-- @type Unit.Radar.detectionDistanceAir.upperHemisphere
-- @field #Distance headOn -- @field #Distance headOn
-- @field #Distance tailOn -- @field #Distance tailOn
--- @type Unit.Radar.detectionDistanceAir.lowerHemisphere --- A radar.
-- @type Unit.Radar.detectionDistanceAir.lowerHemisphere
-- @field #Distance headOn -- @field #Distance headOn
-- @field #Distance tailOn -- @field #Distance tailOn
@ -1510,22 +1529,26 @@ do -- AI
-- @field IR_POINTER -- @field IR_POINTER
-- @field LASER -- @field LASER
--- @type AI.Task.WaypointType ---
-- @type AI.Task.WaypointType
-- @field TAKEOFF -- @field TAKEOFF
-- @field TAKEOFF_PARKING -- @field TAKEOFF_PARKING
-- @field TURNING_POINT -- @field TURNING_POINT
-- @field TAKEOFF_PARKING_HOT -- @field TAKEOFF_PARKING_HOT
-- @field LAND -- @field LAND
--- @type AI.Task.TurnMethod ---
-- @type AI.Task.TurnMethod
-- @field FLY_OVER_POINT -- @field FLY_OVER_POINT
-- @field FIN_POINT -- @field FIN_POINT
--- @type AI.Task.AltitudeType ---
-- @type AI.Task.AltitudeType
-- @field BARO -- @field BARO
-- @field RADIO -- @field RADIO
--- @type AI.Task.VehicleFormation ---
-- @type AI.Task.VehicleFormation
-- @field OFF_ROAD -- @field OFF_ROAD
-- @field ON_ROAD -- @field ON_ROAD
-- @field RANK -- @field RANK
@ -1535,27 +1558,30 @@ do -- AI
-- @field ECHELON_LEFT -- @field ECHELON_LEFT
-- @field ECHELON_RIGHT -- @field ECHELON_RIGHT
--- @type AI.Option ---
-- @type AI.Option
-- @field #AI.Option.Air Air -- @field #AI.Option.Air Air
-- @field #AI.Option.Ground Ground -- @field #AI.Option.Ground Ground
-- @field #AI.Option.Naval Naval -- @field #AI.Option.Naval Naval
--- @type AI.Option.Air ---
-- @type AI.Option.Air
-- @field #AI.Option.Air.id id -- @field #AI.Option.Air.id id
-- @field #AI.Option.Air.val val -- @field #AI.Option.Air.val val
--- @type AI.Option.Ground ---
-- @type AI.Option.Ground
-- @field #AI.Option.Ground.id id -- @field #AI.Option.Ground.id id
-- @field #AI.Option.Ground.val val -- @field #AI.Option.Ground.val val
-- @field #AI.Option.Ground.mid mid -- @field #AI.Option.Ground.mid mid
-- @field #AI.Option.Ground.mval mval -- @field #AI.Option.Ground.mval mval
-- --
--- @type AI.Option.Naval -- @type AI.Option.Naval
-- @field #AI.Option.Naval.id id -- @field #AI.Option.Naval.id id
-- @field #AI.Option.Naval.val val -- @field #AI.Option.Naval.val val
---
--- @type AI.Option.Air.id -- @type AI.Option.Air.id
-- @field NO_OPTION -- @field NO_OPTION
-- @field ROE -- @field ROE
-- @field REACTION_ON_THREAT -- @field REACTION_ON_THREAT
@ -1578,72 +1604,60 @@ do -- AI
-- @field JETT_TANKS_IF_EMPTY -- @field JETT_TANKS_IF_EMPTY
-- @field FORCED_ATTACK -- @field FORCED_ATTACK
--- @type AI.Option.Air.id.FORMATION ---
-- @field LINE_ABREAST -- @type AI.Option.Air.val
-- @field TRAIL
-- @field WEDGE
-- @field ECHELON_RIGHT
-- @field ECHELON_LEFT
-- @field FINGER_FOUR
-- @field SPREAD_FOUR
-- @field WW2_BOMBER_ELEMENT
-- @field WW2_BOMBER_ELEMENT_HEIGHT
-- @field WW2_FIGHTER_VIC
-- @field HEL_WEDGE
-- @field HEL_ECHELON
-- @field HEL_FRONT
-- @field HEL_COLUMN
-- @field COMBAT_BOX
-- @field JAVELIN_DOWN
--- @type AI.Option.Air.val
-- @field #AI.Option.Air.val.ROE ROE -- @field #AI.Option.Air.val.ROE ROE
-- @field #AI.Option.Air.val.REACTION_ON_THREAT REACTION_ON_THREAT -- @field #AI.Option.Air.val.REACTION_ON_THREAT REACTION_ON_THREAT
-- @field #AI.Option.Air.val.RADAR_USING RADAR_USING -- @field #AI.Option.Air.val.RADAR_USING RADAR_USING
-- @field #AI.Option.Air.val.FLARE_USING FLARE_USING -- @field #AI.Option.Air.val.FLARE_USING FLARE_USING
--- @type AI.Option.Air.val.ROE ---
-- @type AI.Option.Air.val.ROE
-- @field WEAPON_FREE -- @field WEAPON_FREE
-- @field OPEN_FIRE_WEAPON_FREE -- @field OPEN_FIRE_WEAPON_FREE
-- @field OPEN_FIRE -- @field OPEN_FIRE
-- @field RETURN_FIRE -- @field RETURN_FIRE
-- @field WEAPON_HOLD -- @field WEAPON_HOLD
--- @type AI.Option.Air.val.REACTION_ON_THREAT ---
-- @type AI.Option.Air.val.REACTION_ON_THREAT
-- @field NO_REACTION -- @field NO_REACTION
-- @field PASSIVE_DEFENCE -- @field PASSIVE_DEFENCE
-- @field EVADE_FIRE -- @field EVADE_FIRE
-- @field BYPASS_AND_ESCAPE -- @field BYPASS_AND_ESCAPE
-- @field ALLOW_ABORT_MISSION -- @field ALLOW_ABORT_MISSION
--- @type AI.Option.Air.val.RADAR_USING ---
-- @type AI.Option.Air.val.RADAR_USING
-- @field NEVER -- @field NEVER
-- @field FOR_ATTACK_ONLY -- @field FOR_ATTACK_ONLY
-- @field FOR_SEARCH_IF_REQUIRED -- @field FOR_SEARCH_IF_REQUIRED
-- @field FOR_CONTINUOUS_SEARCH -- @field FOR_CONTINUOUS_SEARCH
--- @type AI.Option.Air.val.FLARE_USING ---
-- @type AI.Option.Air.val.FLARE_USING
-- @field NEVER -- @field NEVER
-- @field AGAINST_FIRED_MISSILE -- @field AGAINST_FIRED_MISSILE
-- @field WHEN_FLYING_IN_SAM_WEZ -- @field WHEN_FLYING_IN_SAM_WEZ
-- @field WHEN_FLYING_NEAR_ENEMIES -- @field WHEN_FLYING_NEAR_ENEMIES
--- @type AI.Option.Air.val.ECM_USING ---
-- @type AI.Option.Air.val.ECM_USING
-- @field NEVER_USE -- @field NEVER_USE
-- @field USE_IF_ONLY_LOCK_BY_RADAR -- @field USE_IF_ONLY_LOCK_BY_RADAR
-- @field USE_IF_DETECTED_LOCK_BY_RADAR -- @field USE_IF_DETECTED_LOCK_BY_RADAR
-- @field ALWAYS_USE -- @field ALWAYS_USE
--- @type AI.Option.Air.val.MISSILE_ATTACK ---
-- @type AI.Option.Air.val.MISSILE_ATTACK
-- @field MAX_RANGE -- @field MAX_RANGE
-- @field NEZ_RANGE -- @field NEZ_RANGE
-- @field HALF_WAY_RMAX_NEZ -- @field HALF_WAY_RMAX_NEZ
-- @field TARGET_THREAT_EST -- @field TARGET_THREAT_EST
-- @field RANDOM_RANGE -- @field RANDOM_RANGE
---
--- @type AI.Option.Ground.id -- @type AI.Option.Ground.id
-- @field NO_OPTION -- @field NO_OPTION
-- @field ROE @{#AI.Option.Ground.val.ROE} -- @field ROE @{#AI.Option.Ground.val.ROE}
-- @field FORMATION -- @field FORMATION
@ -1652,42 +1666,51 @@ do -- AI
-- @field ENGAGE_AIR_WEAPONS -- @field ENGAGE_AIR_WEAPONS
-- @field AC_ENGAGEMENT_RANGE_RESTRICTION -- @field AC_ENGAGEMENT_RANGE_RESTRICTION
--- @type AI.Option.Ground.mid -- Moose added ---
-- @type AI.Option.Ground.mid -- Moose added
-- @field RESTRICT_AAA_MIN 27 -- @field RESTRICT_AAA_MIN 27
-- @field RESTRICT_AAA_MAX 29 -- @field RESTRICT_AAA_MAX 29
-- @field RESTRICT_TARGETS @{#AI.Option.Ground.mval.ENGAGE_TARGETS} 28 -- @field RESTRICT_TARGETS @{#AI.Option.Ground.mval.ENGAGE_TARGETS} 28
--- @type AI.Option.Ground.val ---
-- @type AI.Option.Ground.val
-- @field #AI.Option.Ground.val.ROE ROE -- @field #AI.Option.Ground.val.ROE ROE
-- @field #AI.Option.Ground.val.ALARM_STATE ALARM_STATE -- @field #AI.Option.Ground.val.ALARM_STATE ALARM_STATE
-- @field #AI.Option.Ground.val.ENGAGE_TARGETS RESTRICT_TARGETS -- @field #AI.Option.Ground.val.ENGAGE_TARGETS RESTRICT_TARGETS
--- @type AI.Option.Ground.val.ROE ---
-- @type AI.Option.Ground.val.ROE
-- @field OPEN_FIRE -- @field OPEN_FIRE
-- @field RETURN_FIRE -- @field RETURN_FIRE
-- @field WEAPON_HOLD -- @field WEAPON_HOLD
--- @type AI.Option.Ground.mval -- Moose added ---
-- @type AI.Option.Ground.mval -- Moose added
-- @field #AI.Option.Ground.mval.ENGAGE_TARGETS ENGAGE_TARGETS -- @field #AI.Option.Ground.mval.ENGAGE_TARGETS ENGAGE_TARGETS
--- @type AI.Option.Ground.mval.ENGAGE_TARGETS -- Moose added ---
-- @type AI.Option.Ground.mval.ENGAGE_TARGETS -- Moose added
-- @field ANY_TARGET -- 0 -- @field ANY_TARGET -- 0
-- @field AIR_UNITS_ONLY -- 1 -- @field AIR_UNITS_ONLY -- 1
-- @field GROUND_UNITS_ONLY -- 2 -- @field GROUND_UNITS_ONLY -- 2
--- @type AI.Option.Ground.val.ALARM_STATE ---
-- @type AI.Option.Ground.val.ALARM_STATE
-- @field AUTO -- @field AUTO
-- @field GREEN -- @field GREEN
-- @field RED -- @field RED
--- @type AI.Option.Naval.id ---
-- @type AI.Option.Naval.id
-- @field NO_OPTION -- @field NO_OPTION
-- @field ROE -- @field ROE
--- @type AI.Option.Naval.val ---
-- @type AI.Option.Naval.val
-- @field #AI.Option.Naval.val.ROE ROE -- @field #AI.Option.Naval.val.ROE ROE
--- @type AI.Option.Naval.val.ROE ---
-- @type AI.Option.Naval.val.ROE
-- @field OPEN_FIRE -- @field OPEN_FIRE
-- @field RETURN_FIRE -- @field RETURN_FIRE
-- @field WEAPON_HOLD -- @field WEAPON_HOLD

View File

@ -3616,9 +3616,10 @@ function WAREHOUSE:onafterStatus(From, Event, To)
end end
-- Print queue after processing requests. -- Print queue after processing requests.
if self.verbosity > 2 then
self:_PrintQueue(self.queue, "Queue waiting") self:_PrintQueue(self.queue, "Queue waiting")
self:_PrintQueue(self.pending, "Queue pending") self:_PrintQueue(self.pending, "Queue pending")
end
-- Check fuel for all assets. -- Check fuel for all assets.
--self:_CheckFuel() --self:_CheckFuel()
@ -8234,7 +8235,7 @@ end
-- @return #number Request ID. -- @return #number Request ID.
function WAREHOUSE:_GetIDsFromGroupName(groupname) function WAREHOUSE:_GetIDsFromGroupName(groupname)
---@param #string text The text to analyse. -- @param #string text The text to analyse.
local function analyse(text) local function analyse(text)
-- Get rid of #0001 tail from spawn. -- Get rid of #0001 tail from spawn.

View File

@ -54,6 +54,8 @@
-- @field #string takeoffType Take of type. -- @field #string takeoffType Take of type.
-- @field #boolean despawnAfterLanding Aircraft are despawned after landing. -- @field #boolean despawnAfterLanding Aircraft are despawned after landing.
-- @field #boolean despawnAfterHolding Aircraft are despawned after holding. -- @field #boolean despawnAfterHolding Aircraft are despawned after holding.
-- @field #boolean capOptionPatrolRaceTrack Use closer patrol race track or standard orbit auftrag.
-- @field #number capFormation If capOptionPatrolRaceTrack is true, set the formation, also.
-- --
-- @extends Ops.Legion#LEGION -- @extends Ops.Legion#LEGION
@ -128,6 +130,8 @@ AIRWING = {
pointsAWACS = {}, pointsAWACS = {},
pointsRecon = {}, pointsRecon = {},
markpoints = false, markpoints = false,
capOptionPatrolRaceTrack = false,
capFormation = nil,
} }
--- Payload data. --- Payload data.
@ -179,7 +183,7 @@ AIRWING = {
--- AIRWING class version. --- AIRWING class version.
-- @field #string version -- @field #string version
AIRWING.version="0.9.3" AIRWING.version="0.9.4"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@ -699,6 +703,24 @@ function AIRWING:SetNumberCAP(n)
return self return self
end end
--- Set CAP flight formation.
-- @param #AIRWING self
-- @param #number Formation Formation to take, e.g. ENUMS.Formation.FixedWing.Trail.Close, also see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_option_formation).
-- @return #AIRWING self
function AIRWING:SetCAPFormation(Formation)
self.capFormation = Formation
return self
end
--- Set CAP close race track.We'll utilize the AUFTRAG PatrolRaceTrack instead of a standard race track orbit task.
-- @param #AIRWING self
-- @param #boolean OnOff If true, switch this on, else switch off. Off by default.
-- @return #AIRWING self
function AIRWING:SetCapCloseRaceTrack(OnOff)
self.capOptionPatrolRaceTrack = OnOff
return self
end
--- Set number of TANKER flights with Boom constantly in the air. --- Set number of TANKER flights with Boom constantly in the air.
-- @param #AIRWING self -- @param #AIRWING self
-- @param #number Nboom Number of flights. Default 1. -- @param #number Nboom Number of flights. Default 1.
@ -1112,13 +1134,14 @@ end
-- @return #AIRWING self -- @return #AIRWING self
function AIRWING:CheckCAP() function AIRWING:CheckCAP()
local Ncap=0 --self:CountMissionsInQueue({AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT}) local Ncap=0
-- Count CAP missions. -- Count CAP missions.
for _,_mission in pairs(self.missionqueue) do for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
if mission:IsNotOver() and mission.type==AUFTRAG.Type.GCICAP and mission.patroldata then if mission:IsNotOver() and (mission.type==AUFTRAG.Type.GCICAP or mission.type == AUFTRAG.Type.PATROLRACETRACK) and mission.patroldata then
Ncap=Ncap+1 Ncap=Ncap+1
end end
@ -1130,7 +1153,17 @@ function AIRWING:CheckCAP()
local altitude=patrol.altitude+1000*patrol.noccupied local altitude=patrol.altitude+1000*patrol.noccupied
local missionCAP=AUFTRAG:NewGCICAP(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg) local missionCAP = nil -- Ops.Auftrag#AUFTRAG
if self.capOptionPatrolRaceTrack then
missionCAP=AUFTRAG:NewPATROL_RACETRACK(patrol.coord,altitude,patrol.speed,patrol.heading,patrol.leg, self.capFormation)
else
missionCAP=AUFTRAG:NewGCICAP(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg)
end
missionCAP.patroldata=patrol missionCAP.patroldata=patrol
@ -1150,7 +1183,7 @@ end
-- @return #AIRWING self -- @return #AIRWING self
function AIRWING:CheckRECON() function AIRWING:CheckRECON()
local Ncap=0 --self:CountMissionsInQueue({AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT}) local Ncap=0
-- Count CAP missions. -- Count CAP missions.
for _,_mission in pairs(self.missionqueue) do for _,_mission in pairs(self.missionqueue) do
@ -1278,7 +1311,6 @@ function AIRWING:CheckAWACS()
end end
for i=1,self.nflightsAWACS-N do for i=1,self.nflightsAWACS-N do
local patrol=self:_GetPatrolData(self.pointsAWACS) local patrol=self:_GetPatrolData(self.pointsAWACS)

View File

@ -443,6 +443,7 @@ _AUFTRAGSNR=0
-- @field #string REARMING Rearming mission. -- @field #string REARMING Rearming mission.
-- @field #string CAPTUREZONE Capture zone mission. -- @field #string CAPTUREZONE Capture zone mission.
-- @field #string NOTHING Nothing. -- @field #string NOTHING Nothing.
-- @field #string PATROLRACETRACK Patrol Racetrack.
AUFTRAG.Type={ AUFTRAG.Type={
ANTISHIP="Anti Ship", ANTISHIP="Anti Ship",
AWACS="AWACS", AWACS="AWACS",
@ -484,10 +485,10 @@ AUFTRAG.Type={
RELOCATECOHORT="Relocate Cohort", RELOCATECOHORT="Relocate Cohort",
AIRDEFENSE="Air Defence", AIRDEFENSE="Air Defence",
EWR="Early Warning Radar", EWR="Early Warning Radar",
--RECOVERYTANKER="Recovery Tanker",
REARMING="Rearming", REARMING="Rearming",
CAPTUREZONE="Capture Zone", CAPTUREZONE="Capture Zone",
NOTHING="Nothing", NOTHING="Nothing",
PATROLRACETRACK="Patrol Racetrack",
} }
--- Special task description. --- Special task description.
@ -511,6 +512,7 @@ AUFTRAG.Type={
-- @field #string REARMING Rearming. -- @field #string REARMING Rearming.
-- @field #string CAPTUREZONE Capture OPS zone. -- @field #string CAPTUREZONE Capture OPS zone.
-- @field #string NOTHING Nothing. -- @field #string NOTHING Nothing.
-- @field #string PATROLRACETRACK Patrol Racetrack.
AUFTRAG.SpecialTask={ AUFTRAG.SpecialTask={
FORMATION="Formation", FORMATION="Formation",
PATROLZONE="PatrolZone", PATROLZONE="PatrolZone",
@ -532,6 +534,7 @@ AUFTRAG.SpecialTask={
REARMING="Rearming", REARMING="Rearming",
CAPTUREZONE="Capture Zone", CAPTUREZONE="Capture Zone",
NOTHING="Nothing", NOTHING="Nothing",
PATROLRACETRACK="Patrol Racetrack",
} }
--- Mission status. --- Mission status.
@ -652,7 +655,7 @@ AUFTRAG.Category={
--- AUFTRAG class version. --- AUFTRAG class version.
-- @field #string version -- @field #string version
AUFTRAG.version="1.2.0" AUFTRAG.version="1.2.1"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -1017,7 +1020,7 @@ end
-- @param #number Altitude Hover altitude in feet AGL. Default is 50 feet above ground. -- @param #number Altitude Hover altitude in feet AGL. Default is 50 feet above ground.
-- @param #number Time Time in seconds to hold the hover. Default 300 seconds. -- @param #number Time Time in seconds to hold the hover. Default 300 seconds.
-- @param #number Speed Speed in knots to fly to the target coordinate. Default 150kn. -- @param #number Speed Speed in knots to fly to the target coordinate. Default 150kn.
-- @param #number MissionAlt Altitide to fly towards the mission in feet AGL. Default 1000ft. -- @param #number MissionAlt Altitude to fly towards the mission in feet AGL. Default 1000ft.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewHOVER(Coordinate, Altitude, Time, Speed, MissionAlt) function AUFTRAG:NewHOVER(Coordinate, Altitude, Time, Speed, MissionAlt)
@ -1049,6 +1052,58 @@ function AUFTRAG:NewHOVER(Coordinate, Altitude, Time, Speed, MissionAlt)
return mission return mission
end end
--- **[AIR]** Create an enhanced orbit race track mission. Planes will keep closer to the track.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to start the race track.
-- @param #number Altitude (Optional) Altitude in feet. Defaults to 20,000ft ASL.
-- @param #number Speed (Optional) Speed in knots. Defaults to 300kn TAS.
-- @param #number Heading (Optional) Heading in degrees, 0 to 360. Defaults to 90 degree (East).
-- @param #number Leg (Optional) Leg of the race track in NM. Defaults to 10nm.
-- @param #number Formation (Optional) Formation to take, e.g. ENUMS.Formation.FixedWing.Trail.Close, also see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_option_formation).
-- @return #AUFTRAG self
function AUFTRAG:NewPATROL_RACETRACK(Coordinate,Altitude,Speed,Heading,Leg,Formation)
local mission = AUFTRAG:New(AUFTRAG.Type.PATROLRACETRACK)
-- Target.
mission:_TargetFromObject(Coordinate)
-- Set Altitude.
if Altitude then
mission.TrackAltitude=UTILS.FeetToMeters(Altitude)
else
mission.TrackAltitude=UTILS.FeetToMeters(20000)
end
-- Points
mission.TrackPoint1 = Coordinate
local leg = UTILS.NMToMeters(Leg) or UTILS.NMToMeters(10)
local heading = Heading or 90
if heading < 0 or heading > 360 then heading = 90 end
mission.TrackPoint2 = Coordinate:Translate(leg,heading,true)
-- Orbit speed in m/s TAS.
mission.TrackSpeed = UTILS.IasToTas(UTILS.KnotsToKmph(Speed or 300), mission.TrackAltitude)
-- Mission speed in km/h and altitude
mission.missionSpeed = UTILS.KnotsToKmph(Speed or 300)
mission.missionAltitude = mission.TrackAltitude * 0.9
mission.missionTask=ENUMS.MissionTask.CAP
mission.optionROE=ENUMS.ROE.ReturnFire
mission.optionROT=ENUMS.ROT.PassiveDefense
mission.categories={AUFTRAG.Category.AIRCRAFT}
mission.DCStask=mission:GetDCSMissionTask()
return mission
end
--- **[AIR]** Create an ORBIT mission, which can be either a circular orbit or a race-track pattern. --- **[AIR]** Create an ORBIT mission, which can be either a circular orbit or a race-track pattern.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit. -- @param Core.Point#COORDINATE Coordinate Where to orbit.
@ -1181,7 +1236,7 @@ function AUFTRAG:NewORBIT_GROUP(Group, Altitude, Speed, Leg, Heading, OffsetVec2
end end
--- **[AIR]** Create a Ground Controlled CAP (GCICAP) mission. Flights with this task are considered for A2A INTERCEPT missions by the CHIEF class. They will perform a compat air patrol but not engage by --- **[AIR]** Create a Ground Controlled CAP (GCICAP) mission. Flights with this task are considered for A2A INTERCEPT missions by the CHIEF class. They will perform a combat air patrol but not engage by
-- themselfs. They wait for the CHIEF to tell them whom to engage. -- themselfs. They wait for the CHIEF to tell them whom to engage.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit. -- @param Core.Point#COORDINATE Coordinate Where to orbit.
@ -2688,6 +2743,8 @@ function AUFTRAG:NewAUTO(EngageGroup)
mission=AUFTRAG:NewTANKER(Coordinate,Altitude,Speed,Heading,Leg,RefuelSystem) mission=AUFTRAG:NewTANKER(Coordinate,Altitude,Speed,Heading,Leg,RefuelSystem)
elseif auftrag==AUFTRAG.Type.TROOPTRANSPORT then elseif auftrag==AUFTRAG.Type.TROOPTRANSPORT then
mission=AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet,DropoffCoordinate,PickupCoordinate) mission=AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet,DropoffCoordinate,PickupCoordinate)
elseif auftrag==AUFTRAG.Type.PATROLRACETRACK then
mission=AUFTRAG:NewPATROL_RACETRACK(Coordinate,Altitude,Speed,Heading,Leg,Formation)
else else
end end
@ -6345,6 +6402,30 @@ function AUFTRAG:GetDCSMissionTask()
table.insert(DCStasks, DCStask) table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.PATROLRACETRACK then
---------------------
-- Enhanced Orbit Racetrack --
---------------------
local DCStask={}
DCStask.id=AUFTRAG.SpecialTask.PATROLRACETRACK
local param={}
-- ONTROLLABLE:PatrolRaceTrack(Point1, Point2, Altitude, Speed, Formation, Delay)
param.TrackAltitude = self.TrackAltitude
param.TrackSpeed = self.TrackSpeed
param.TrackPoint1 = self.TrackPoint1
param.TrackPoint2 = self.TrackPoint2
param.missionSpeed = self.missionSpeed
param.missionAltitude = self.missionAltitude
param.TrackFormation = self.TrackFormation
DCStask.params=param
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.HOVER then elseif self.type==AUFTRAG.Type.HOVER then
--------------------- ---------------------
@ -6619,6 +6700,8 @@ function AUFTRAG:GetMissionTaskforMissionType(MissionType)
mtask=ENUMS.MissionTask.NOTHING mtask=ENUMS.MissionTask.NOTHING
elseif MissionType==AUFTRAG.Type.HOVER then elseif MissionType==AUFTRAG.Type.HOVER then
mtask=ENUMS.MissionTask.NOTHING mtask=ENUMS.MissionTask.NOTHING
elseif MissionType==AUFTRAG.Type.PATROLRACETRACK then
mtask=ENUMS.MissionTask.CAP
end end
return mtask return mtask

View File

@ -75,7 +75,7 @@ COHORT = {
livery = nil, livery = nil,
skill = nil, skill = nil,
legion = nil, legion = nil,
Ngroups = nil, --Ngroups = nil,
Ngroups = 0, Ngroups = 0,
engageRange = nil, engageRange = nil,
tacanChannel = {}, tacanChannel = {},
@ -1098,7 +1098,7 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
-- Assets on mission NOTHING are considered. -- Assets on mission NOTHING are considered.
table.insert(assets, asset) table.insert(assets, asset)
elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.GCICAP) and MissionType==AUFTRAG.Type.INTERCEPT then elseif self.legion:IsAssetOnMission(asset, {AUFTRAG.Type.GCICAP, AUFTRAG.Type.PATROLRACETRACK}) and MissionType==AUFTRAG.Type.INTERCEPT then
-- Check if the payload of this asset is compatible with the mission. -- Check if the payload of this asset is compatible with the mission.
-- Note: we do not check the payload as an asset that is on a GCICAP mission should be able to do an INTERCEPT as well! -- Note: we do not check the payload as an asset that is on a GCICAP mission should be able to do an INTERCEPT as well!
@ -1595,4 +1595,3 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -64,6 +64,7 @@
-- @field Core.Set#SET_ZONE NoGoZoneSet -- @field Core.Set#SET_ZONE NoGoZoneSet
-- @field #boolean Monitor -- @field #boolean Monitor
-- @field #boolean TankerInvisible -- @field #boolean TankerInvisible
-- @field #number CapFormation
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown. --- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
@ -207,6 +208,7 @@ EASYGCICAP = {
NoGoZoneSet = nil, NoGoZoneSet = nil,
Monitor = false, Monitor = false,
TankerInvisible = true, TankerInvisible = true,
CapFormation = nil,
} }
--- Internal Squadron data type --- Internal Squadron data type
@ -242,7 +244,7 @@ EASYGCICAP = {
--- EASYGCICAP class version. --- EASYGCICAP class version.
-- @field #string version -- @field #string version
EASYGCICAP.version="0.0.8" EASYGCICAP.version="0.0.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -289,6 +291,7 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
self.repeatsonfailure = 3 self.repeatsonfailure = 3
self.Monitor = false self.Monitor = false
self.TankerInvisible = true self.TankerInvisible = true
self.CapFormation = ENUMS.Formation.FixedWing.FingerFour.Group
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("EASYGCICAP %s | ", self.alias) self.lid=string.format("EASYGCICAP %s | ", self.alias)
@ -313,6 +316,14 @@ end
-- Functions -- Functions
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- Set CAP formation.
-- @param #EASYGCICAP self
-- @param #number Formation Formation to fly, defaults to ENUMS.Formation.FixedWing.FingerFour.Group
-- @return #EASYGCICAP self
function EASYGCICAP:SetCAPFormation(Formation)
self.CapFormation = Formation
return self
end
--- Set Tanker and AWACS to be invisible to enemy AI eyes --- Set Tanker and AWACS to be invisible to enemy AI eyes
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
@ -476,6 +487,8 @@ end
function EASYGCICAP:_AddAirwing(Airbasename, Alias) function EASYGCICAP:_AddAirwing(Airbasename, Alias)
self:T(self.lid.."_AddAirwing "..Airbasename) self:T(self.lid.."_AddAirwing "..Airbasename)
local CapFormation = self.CapFormation
-- Create Airwing -- Create Airwing
local CAP_Wing = AIRWING:New(Airbasename,Alias) local CAP_Wing = AIRWING:New(Airbasename,Alias)
CAP_Wing:SetVerbosityLevel(3) CAP_Wing:SetVerbosityLevel(3)
@ -484,11 +497,15 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename)) CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
CAP_Wing:SetRespawnAfterDestroyed() CAP_Wing:SetRespawnAfterDestroyed()
CAP_Wing:SetNumberCAP(self.capgrouping) CAP_Wing:SetNumberCAP(self.capgrouping)
CAP_Wing:SetCapCloseRaceTrack(true)
if CapFormation then
CAP_Wing:SetCAPFormation(CapFormation)
end
if #self.ManagedTK > 0 then if #self.ManagedTK > 0 then
CAP_Wing:SetNumberTankerBoom(1) CAP_Wing:SetNumberTankerBoom(1)
CAP_Wing:SetNumberTankerProbe(1) CAP_Wing:SetNumberTankerProbe(1)
end end
if #self.ManagedAW > 0 then if #self.ManagedEWR > 0 then
CAP_Wing:SetNumberAWACS(1) CAP_Wing:SetNumberAWACS(1)
end end
if #self.ManagedREC > 0 then if #self.ManagedREC > 0 then
@ -515,6 +532,9 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
flightgroup:SetDetection(true) flightgroup:SetDetection(true)
flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet) flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet)
flightgroup:SetOutOfAAMRTB() flightgroup:SetOutOfAAMRTB()
if CapFormation then
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
end
end end
if Mission.type == AUFTRAG.Type.TANKER or Mission.type == AUFTRAG.Type.AWACS or Mission.type == AUFTRAG.Type.RECON then if Mission.type == AUFTRAG.Type.TANKER or Mission.type == AUFTRAG.Type.AWACS or Mission.type == AUFTRAG.Type.RECON then
if TankerInvisible then if TankerInvisible then
@ -549,8 +569,8 @@ end
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase -- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate. -- @param Core.Point#COORDINATE Coordinate.
-- @param #number Altitude Defaults to 25000 feet. -- @param #number Altitude Defaults to 25000 feet ASL.
-- @param #number Speed Defaults to 300 knots. -- @param #number Speed Defaults to 300 knots TAS.
-- @param #number Heading Defaults to 90 degrees (East). -- @param #number Heading Defaults to 90 degrees (East).
-- @param #number LegLength Defaults to 15 NM. -- @param #number LegLength Defaults to 15 NM.
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
@ -888,7 +908,7 @@ function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames
self:T(self.lid.."_AddSquadron "..SquadName) self:T(self.lid.."_AddSquadron "..SquadName)
-- Add Squadrons -- Add Squadrons
local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName) local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName)
Squadron_One:AddMissionCapability({AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.ALERT5}) Squadron_One:AddMissionCapability({AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.PATROLRACETRACK, AUFTRAG.Type.ALERT5})
--Squadron_One:SetFuelLowRefuel(true) --Squadron_One:SetFuelLowRefuel(true)
Squadron_One:SetFuelLowThreshold(0.3) Squadron_One:SetFuelLowThreshold(0.3)
Squadron_One:SetTurnoverTime(10,20) Squadron_One:SetTurnoverTime(10,20)
@ -900,7 +920,7 @@ function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames
local wing = self.wings[AirbaseName][1] -- Ops.AirWing#AIRWING local wing = self.wings[AirbaseName][1] -- Ops.AirWing#AIRWING
wing:AddSquadron(Squadron_One) wing:AddSquadron(Squadron_One)
wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.ALERT5},75) wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.PATROLRACETRACK, AUFTRAG.Type.ALERT5},75)
return self return self
end end
@ -1234,12 +1254,16 @@ function EASYGCICAP:onafterStatus(From,Event,To)
local capmission = 0 local capmission = 0
local interceptmission = 0 local interceptmission = 0
local reconmission = 0 local reconmission = 0
local awacsmission = 0
local tankermission = 0
for _,_wing in pairs(self.wings) do for _,_wing in pairs(self.wings) do
local count = _wing[1]:CountAssetsOnMission(MissionTypes,Cohort) local count = _wing[1]:CountAssetsOnMission(MissionTypes,Cohort)
local count2 = _wing[1]:CountAssets(true,MissionTypes,Attributes) local count2 = _wing[1]:CountAssets(true,MissionTypes,Attributes)
capmission = capmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.GCICAP}) capmission = capmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.GCICAP,AUFTRAG.Type.PATROLRACETRACK})
interceptmission = interceptmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.INTERCEPT}) interceptmission = interceptmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.INTERCEPT})
reconmission = reconmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.RECON}) reconmission = reconmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.RECON})
awacsmission = awacsmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.AWACS})
tankermission = tankermission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.TANKER})
assets = assets + count assets = assets + count
instock = instock + count2 instock = instock + count2
end end
@ -1251,6 +1275,8 @@ function EASYGCICAP:onafterStatus(From,Event,To)
text = text.."\nMissions: "..capmission+interceptmission text = text.."\nMissions: "..capmission+interceptmission
text = text.."\n - CAP: "..capmission text = text.."\n - CAP: "..capmission
text = text.."\n - Intercept: "..interceptmission text = text.."\n - Intercept: "..interceptmission
text = text.."\n - AWACS: "..awacsmission
text = text.."\n - TANKER: "..tankermission
text = text.."\n - Recon: "..reconmission text = text.."\n - Recon: "..reconmission
MESSAGE:New(text,15,"GCICAP"):ToAll():ToLogIf(self.debug) MESSAGE:New(text,15,"GCICAP"):ToAll():ToLogIf(self.debug)
end end

View File

@ -4,7 +4,7 @@
-- --
-- * Manage aircraft departure and arrival -- * Manage aircraft departure and arrival
-- * Handles AI and human players -- * Handles AI and human players
-- * Limit number of AI groups taxiing, taking off and landing simultaniously -- * Limit number of AI groups taxiing, taking off and landing simultaneously
-- * Immersive voice overs via SRS text-to-speech -- * Immersive voice overs via SRS text-to-speech
-- * Define holding patterns for airdromes -- * Define holding patterns for airdromes
-- --
@ -61,6 +61,7 @@
-- @field #number runwaydestroyed Time stamp (abs), when runway was destroyed. If `nil`, runway is operational. -- @field #number runwaydestroyed Time stamp (abs), when runway was destroyed. If `nil`, runway is operational.
-- @field #number runwayrepairtime Time in seconds until runway will be repaired after it was destroyed. Default is 3600 sec (one hour). -- @field #number runwayrepairtime Time in seconds until runway will be repaired after it was destroyed. Default is 3600 sec (one hour).
-- @field #boolean markerParking If `true`, occupied parking spots are marked. -- @field #boolean markerParking If `true`, occupied parking spots are marked.
-- @field #boolean nosubs If `true`, SRS TTS is without subtitles.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- **Ground Control**: Airliner X, Good news, you are clear to taxi to the active. --- **Ground Control**: Airliner X, Good news, you are clear to taxi to the active.
@ -122,7 +123,7 @@
-- * `Length` is the length of the pattern. -- * `Length` is the length of the pattern.
-- * `FlightLevelMin` is the lowest altitude at which aircraft can hold. -- * `FlightLevelMin` is the lowest altitude at which aircraft can hold.
-- * `FlightLevelMax` is the highest altitude at which aircraft can hold. -- * `FlightLevelMax` is the highest altitude at which aircraft can hold.
-- * `Prio` is the priority of this holdig stacks. If multiple patterns are defined, patterns with higher prio will be filled first. -- * `Prio` is the priority of this holding stacks. If multiple patterns are defined, patterns with higher prio will be filled first.
-- --
-- # Parking Guard -- # Parking Guard
-- --
@ -137,13 +138,13 @@
-- --
-- # Limits for Inbound and Outbound Flights -- # Limits for Inbound and Outbound Flights
-- --
-- You can define limits on how many aircraft are simultaniously landing and taking off. This avoids (DCS) problems where taxiing aircraft cause a "traffic jam" on the taxi way(s) -- You can define limits on how many aircraft are simultaneously landing and taking off. This avoids (DCS) problems where taxiing aircraft cause a "traffic jam" on the taxi way(s)
-- and bring the whole airbase effectively to a stand still. -- and bring the whole airbase effectively to a stand still.
-- --
-- ## Landing Limits -- ## Landing Limits
-- --
-- The number of groups getting landing clearance can be set with the @{#FLIGHTCONTROL.SetLimitLanding}(*Nlanding, Ntakeoff*) function. -- The number of groups getting landing clearance can be set with the @{#FLIGHTCONTROL.SetLimitLanding}(*Nlanding, Ntakeoff*) function.
-- The first parameter, `Nlanding`, defines how many groups get clearance simultaniously. -- The first parameter, `Nlanding`, defines how many groups get clearance simultaneously.
-- --
-- The second parameter, `Ntakeoff`, sets a limit on how many flights can take off whilst inbound flights still get clearance. By default, this is set to zero because the runway can only be used for takeoff *or* -- The second parameter, `Ntakeoff`, sets a limit on how many flights can take off whilst inbound flights still get clearance. By default, this is set to zero because the runway can only be used for takeoff *or*
-- landing. So if you have a flight taking off, inbound fights will have to wait until the runway is clear. -- landing. So if you have a flight taking off, inbound fights will have to wait until the runway is clear.
@ -155,7 +156,7 @@
-- ## Taxiing/Takeoff Limits -- ## Taxiing/Takeoff Limits
-- --
-- The number of AI flight groups getting clearance to taxi to the runway can be set with the @{#FLIGHTCONTROL.SetLimitTaxi}(*Nlanding, Ntakeoff*) function. -- The number of AI flight groups getting clearance to taxi to the runway can be set with the @{#FLIGHTCONTROL.SetLimitTaxi}(*Nlanding, Ntakeoff*) function.
-- The first parameter, `Ntaxi`, defines how many groups are allowed to taxi to the runway simultaniously. Note that once the AI starts to taxi, we loose complete control over it. -- The first parameter, `Ntaxi`, defines how many groups are allowed to taxi to the runway simultaneously. Note that once the AI starts to taxi, we loose complete control over it.
-- They will follow their internal logic to get the the runway and take off. Therefore, giving clearance to taxi is equivalent to giving them clearance for takeoff. -- They will follow their internal logic to get the the runway and take off. Therefore, giving clearance to taxi is equivalent to giving them clearance for takeoff.
-- --
-- By default, the parameter only counts the number of flights taxiing *to* the runway. If you set the second parameter, `IncludeInbound`, to `true`, this will also count the flights -- By default, the parameter only counts the number of flights taxiing *to* the runway. If you set the second parameter, `IncludeInbound`, to `true`, this will also count the flights
@ -237,9 +238,9 @@
-- atcNellis:SetParkingGuardStatic("Static Generator F Template") -- atcNellis:SetParkingGuardStatic("Static Generator F Template")
-- -- Set taxi speed limit to 25 knots. -- -- Set taxi speed limit to 25 knots.
-- atcNellis:SetSpeedLimitTaxi(25) -- atcNellis:SetSpeedLimitTaxi(25)
-- -- Set that max 3 groups are allowed to taxi simultaniously. -- -- Set that max 3 groups are allowed to taxi simultaneously.
-- atcNellis:SetLimitTaxi(3, false, 1) -- atcNellis:SetLimitTaxi(3, false, 1)
-- -- Set that max 2 groups are allowd to land simultaniously and unlimited number (99) groups can land, while other groups are taking off. -- -- Set that max 2 groups are allowd to land simultaneously and unlimited number (99) groups can land, while other groups are taking off.
-- atcNellis:SetLimitLanding(2, 99) -- atcNellis:SetLimitLanding(2, 99)
-- -- Use Google for text-to-speech. -- -- Use Google for text-to-speech.
-- atcNellis:SetSRSTower(nil, nil, "en-AU-Standard-A", nil, nil, "D:\\Path To Google\\GoogleCredentials.json") -- atcNellis:SetSRSTower(nil, nil, "en-AU-Standard-A", nil, nil, "D:\\Path To Google\\GoogleCredentials.json")
@ -270,6 +271,7 @@ FLIGHTCONTROL = {
Nparkingspots = nil, Nparkingspots = nil,
holdingpatterns = {}, holdingpatterns = {},
hpcounter = 0, hpcounter = 0,
nosubs = false,
} }
--- Holding point. Contains holding stacks. --- Holding point. Contains holding stacks.
@ -327,7 +329,7 @@ FLIGHTCONTROL.FlightStatus={
--- FlightControl class version. --- FlightControl class version.
-- @field #string version -- @field #string version
FLIGHTCONTROL.version="0.7.3" FLIGHTCONTROL.version="0.7.4"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -407,6 +409,7 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port,
self:SetFrequency(Frequency, Modulation) self:SetFrequency(Frequency, Modulation)
self:SetMarkHoldingPattern(true) self:SetMarkHoldingPattern(true)
self:SetRunwayRepairtime() self:SetRunwayRepairtime()
self.nosubs = false
-- Set SRS Port -- Set SRS Port
self:SetSRSPort(Port or 5002) self:SetSRSPort(Port or 5002)
@ -556,6 +559,22 @@ function FLIGHTCONTROL:SetVerbosity(VerbosityLevel)
return self return self
end end
--- Set subtitles to appear on SRS TTS messages.
-- @param #FLIGHTCONTROL self
-- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SwitchSubtitlesOn()
self.nosubs = false
return self
end
--- Set subtitles to appear on SRS TTS messages.
-- @param #FLIGHTCONTROL self
-- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SwitchSubtitlesOff()
self.nosubs = true
return self
end
--- Set the tower frequency. --- Set the tower frequency.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param #number Frequency Frequency in MHz. Default 305 MHz. -- @param #number Frequency Frequency in MHz. Default 305 MHz.
@ -595,7 +614,7 @@ end
-- @param #string Culture Culture, e.g. "en-GB" (default). -- @param #string Culture Culture, e.g. "en-GB" (default).
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`.
-- @param #number Volume Volume. Default 1.0. -- @param #number Volume Volume. Default 1.0.
-- @param #string Label Name under which SRS transmitts. -- @param #string Label Name under which SRS transmits.
-- @param #string PathToGoogleCredentials Path to google credentials json file. -- @param #string PathToGoogleCredentials Path to google credentials json file.
-- @param #number Port Server port for SRS -- @param #number Port Server port for SRS
-- @return #FLIGHTCONTROL self -- @return #FLIGHTCONTROL self
@ -626,7 +645,7 @@ end
-- @param #string Culture Culture, e.g. "en-GB" (default). -- @param #string Culture Culture, e.g. "en-GB" (default).
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. See [Google Voices](https://cloud.google.com/text-to-speech/docs/voices). -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. See [Google Voices](https://cloud.google.com/text-to-speech/docs/voices).
-- @param #number Volume Volume. Default 1.0. -- @param #number Volume Volume. Default 1.0.
-- @param #string Label Name under which SRS transmitts. Default `self.alias`. -- @param #string Label Name under which SRS transmits. Default `self.alias`.
-- @param #string PathToGoogleCredentials Path to google credentials json file. -- @param #string PathToGoogleCredentials Path to google credentials json file.
-- @return #FLIGHTCONTROL self -- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SetSRSTower(Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials) function FLIGHTCONTROL:SetSRSTower(Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials)
@ -644,7 +663,7 @@ end
-- @param #string Culture Culture, e.g. "en-US" (default). -- @param #string Culture Culture, e.g. "en-US" (default).
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`.
-- @param #number Volume Volume. Default 1.0. -- @param #number Volume Volume. Default 1.0.
-- @param #string Label Name under which SRS transmitts. Default "Pilot". -- @param #string Label Name under which SRS transmits. Default "Pilot".
-- @param #string PathToGoogleCredentials Path to google credentials json file. -- @param #string PathToGoogleCredentials Path to google credentials json file.
-- @return #FLIGHTCONTROL self -- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials) function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials)
@ -657,17 +676,17 @@ function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label, PathTo
end end
--- Set the number of aircraft groups, that are allowed to land simultaniously. --- Set the number of aircraft groups, that are allowed to land simultaneously.
-- Note that this restricts AI and human players. -- Note that this restricts AI and human players.
-- --
-- By default, up to two groups get landing clearance. They are spaced out in time, i.e. after the first one got cleared, the second has to wait a bit. -- By default, up to two groups get landing clearance. They are spaced out in time, i.e. after the first one got cleared, the second has to wait a bit.
-- This -- This
-- --
-- By default, landing clearance is only given when **no** other flight is taking off. You can adjust this for airports with more than one runway or -- By default, landing clearance is only given when **no** other flight is taking off. You can adjust this for airports with more than one runway or
-- in cases where simulatious takeoffs and landings are unproblematic. Note that only because there are multiple runways, it does not mean the AI uses them. -- in cases where simultaneous takeoffs and landings are unproblematic. Note that only because there are multiple runways, it does not mean the AI uses them.
-- --
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param #number Nlanding Max number of aircraft landing simultaniously. Default 2. -- @param #number Nlanding Max number of aircraft landing simultaneously. Default 2.
-- @param #number Ntakeoff Allowed number of aircraft taking off for groups to get landing clearance. Default 0. -- @param #number Ntakeoff Allowed number of aircraft taking off for groups to get landing clearance. Default 0.
-- @return #FLIGHTCONTROL self -- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SetLimitLanding(Nlanding, Ntakeoff) function FLIGHTCONTROL:SetLimitLanding(Nlanding, Ntakeoff)
@ -691,7 +710,7 @@ function FLIGHTCONTROL:SetLandingInterval(dt)
end end
--- Set the number of **AI** aircraft groups, that are allowed to taxi simultaniously. --- Set the number of **AI** aircraft groups, that are allowed to taxi simultaneously.
-- If the limit is reached, other AI groups not get taxi clearance to taxi to the runway. -- If the limit is reached, other AI groups not get taxi clearance to taxi to the runway.
-- --
-- By default, this only counts the number of AI that taxi from their parking position to the runway. -- By default, this only counts the number of AI that taxi from their parking position to the runway.
@ -1010,7 +1029,7 @@ function FLIGHTCONTROL:onbeforeStatusUpdate()
if Tqueue>0 then if Tqueue>0 then
-- Debug info. -- Debug info.
local text=string.format("Still got %d messages in the radio queue. Will call status again in %.1f sec", #self.msrsqueue, Tqueue) local text=string.format("Still got %d messages in the radio queue. Will call status again in %.1f sec", #self.msrsqueue, Tqueue)
self:I(self.lid..text) self:T(self.lid..text)
-- Call status again in dt seconds. -- Call status again in dt seconds.
self:__StatusUpdate(-Tqueue) self:__StatusUpdate(-Tqueue)
@ -2753,9 +2772,10 @@ function FLIGHTCONTROL:_PlayerInfoATIS(groupname)
if flight then if flight then
local text=string.format("Airbase %s ATIS:", self.airbasename) local text=string.format("Airbase %s ATIS:", self.airbasename)
local srstxt = string.format("Airbase %s ", self.airbasename)
if self.atis then if self.atis then
text=text..string.format("\nATIS %.3f MHz %s", self.atis.frequency, UTILS.GetModulationName(self.atis.modulation)) text=text..string.format("\nATIS %.3f MHz %s", self.atis.frequency, UTILS.GetModulationName(self.atis.modulation))
srstxt=srstxt..string.format("ATIS %.3f Megahertz %s", self.atis.frequency, UTILS.GetModulationName(self.atis.modulation))
if self.atis.towerfrequency then if self.atis.towerfrequency then
local tower="" local tower=""
for _,freq in pairs(self.atis.towerfrequency) do for _,freq in pairs(self.atis.towerfrequency) do
@ -2779,7 +2799,17 @@ function FLIGHTCONTROL:_PlayerInfoATIS(groupname)
end end
-- Message to flight -- Message to flight
self:TextMessageToFlight(text, flight, 10, true)
--self:TextMessageToFlight(text, flight, 10, true)
-- Call sign.
local callsign=self:_GetCallsignName(flight)
-- Pilot calls inbound for landing.
local rtext=string.format("%s, %s, request ATIS frequency.", self.alias, callsign)
-- Radio message.
self:TransmissionPilot(rtext, flight)
self:TransmissionTower(srstxt,flight,10)
else else
self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname)))
@ -3390,7 +3420,7 @@ function FLIGHTCONTROL:_PlayerRequestDirectLanding(groupname)
if nTakeoff>self.NlandingTakeoff then if nTakeoff>self.NlandingTakeoff then
-- Message text. -- Message text.
local text=string.format("%s, negative! We have currently traffic taking off", callsign) local text=string.format("%s, negative! We have currently traffic taking off!", callsign)
-- Send message. -- Send message.
self:TransmissionTower(text, flight, 10) self:TransmissionTower(text, flight, 10)
@ -3854,7 +3884,7 @@ function FLIGHTCONTROL:_PlayerArrived(groupname)
else else
-- Message text. -- Message text.
local text=string.format("%s, %s, arrived at parking position", self.alias, callsign) local text=string.format("%s, %s, arrived at parking position.", self.alias, callsign)
-- Transmit message. -- Transmit message.
self:TransmissionPilot(text, flight) self:TransmissionPilot(text, flight)
@ -4277,7 +4307,7 @@ function FLIGHTCONTROL:TransmissionTower(Text, Flight, Delay)
local subgroups=nil local subgroups=nil
if Flight and not Flight.isAI then if Flight and not Flight.isAI then
local playerData=Flight:_GetPlayerData() local playerData=Flight:_GetPlayerData()
if playerData.subtitles then if playerData.subtitles and (not self.nosubs) then
subgroups=subgroups or {} subgroups=subgroups or {}
table.insert(subgroups, Flight.group) table.insert(subgroups, Flight.group)
end end
@ -4324,7 +4354,7 @@ function FLIGHTCONTROL:TransmissionPilot(Text, Flight, Delay)
local subgroups=nil local subgroups=nil
if Flight and not Flight.isAI then if Flight and not Flight.isAI then
local playerData=Flight:_GetPlayerData() local playerData=Flight:_GetPlayerData()
if playerData.subtitles then if playerData.subtitles and (not self.nosubs) then
subgroups=subgroups or {} subgroups=subgroups or {}
table.insert(subgroups, Flight.group) table.insert(subgroups, Flight.group)
end end

View File

@ -2605,6 +2605,9 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N)
elseif task.dcstask.id==AUFTRAG.SpecialTask.RECON then elseif task.dcstask.id==AUFTRAG.SpecialTask.RECON then
-- For recon missions, we need to allow the update as we insert new waypoints. -- For recon missions, we need to allow the update as we insert new waypoints.
self:T2(self.lid.."Allowing update route for Task: ReconMission") self:T2(self.lid.."Allowing update route for Task: ReconMission")
elseif task.dcstask.id==AUFTRAG.SpecialTask.PATROLRACETRACK then
-- For recon missions, we need to allow the update as we insert new waypoints.
self:T2(self.lid.."Allowing update route for Task: Patrol Race Track")
elseif task.dcstask.id==AUFTRAG.SpecialTask.HOVER then elseif task.dcstask.id==AUFTRAG.SpecialTask.HOVER then
-- For recon missions, we need to allow the update as we insert new waypoints. -- For recon missions, we need to allow the update as we insert new waypoints.
self:T2(self.lid.."Allowing update route for Task: Hover") self:T2(self.lid.."Allowing update route for Task: Hover")

View File

@ -965,7 +965,7 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission, Assets)
local pause=false local pause=false
-- Check if mission is INTERCEPT and asset is currently on GCI mission. If so, GCI is paused. -- Check if mission is INTERCEPT and asset is currently on GCI mission. If so, GCI is paused.
if currM.type==AUFTRAG.Type.GCICAP and Mission.type==AUFTRAG.Type.INTERCEPT then if (currM.type==AUFTRAG.Type.GCICAP or currM.type==AUFTRAG.Type.PATROLRACETRACK) and Mission.type==AUFTRAG.Type.INTERCEPT then
pause=true pause=true
elseif (currM.type==AUFTRAG.Type.ONGUARD or currM.type==AUFTRAG.Type.PATROLZONE) and (Mission.type==AUFTRAG.Type.ARTY or Mission.type==AUFTRAG.Type.GROUNDATTACK) then elseif (currM.type==AUFTRAG.Type.ONGUARD or currM.type==AUFTRAG.Type.PATROLZONE) and (Mission.type==AUFTRAG.Type.ARTY or Mission.type==AUFTRAG.Type.GROUNDATTACK) then
pause=true pause=true
@ -1445,7 +1445,7 @@ end
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned. -- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned.
function LEGION:onafterLegionAssetReturned(From, Event, To, Cohort, Asset) function LEGION:onafterLegionAssetReturned(From, Event, To, Cohort, Asset)
-- Debug message. -- Debug message.
self:I(self.lid..string.format("Asset %s from Cohort %s returned! asset.assignment=\"%s\"", Asset.spawngroupname, Cohort.name, tostring(Asset.assignment))) self:T(self.lid..string.format("Asset %s from Cohort %s returned! asset.assignment=\"%s\"", Asset.spawngroupname, Cohort.name, tostring(Asset.assignment)))
-- Stop flightgroup. -- Stop flightgroup.
if Asset.flightgroup and not Asset.flightgroup:IsStopped() then if Asset.flightgroup and not Asset.flightgroup:IsStopped() then
@ -2560,6 +2560,7 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
-- Is in range? -- Is in range?
local Rmax=cohort:GetMissionRange(WeaponTypes) local Rmax=cohort:GetMissionRange(WeaponTypes)
local RangeMax = RangeMax or 0
local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance
return InRange return InRange
@ -2610,6 +2611,7 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
-- Is capable of the mission type? -- Is capable of the mission type?
local can=AUFTRAG.CheckMissionCapability(MissionType, Cohort.missiontypes) local can=AUFTRAG.CheckMissionCapability(MissionType, Cohort.missiontypes)
if can then if can then
can=CheckCategory(Cohort) can=CheckCategory(Cohort)
else else
@ -2687,7 +2689,7 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
return nil return nil
end end
--- Recruit assets from Cohorts for the given parameters. **NOTE** that we set the `asset.isReserved=true` flag so it cant be recruited by anyone else. --- Recruit assets from Cohorts for the given parameters. **NOTE** that we set the `asset.isReserved=true` flag so it cannot be recruited by anyone else.
-- @param #table Cohorts Cohorts included. -- @param #table Cohorts Cohorts included.
-- @param #string MissionTypeRecruit Mission type for recruiting the cohort assets. -- @param #string MissionTypeRecruit Mission type for recruiting the cohort assets.
-- @param #string MissionTypeOpt Mission type for which the assets are optimized. Default is the same as `MissionTypeRecruit`. -- @param #string MissionTypeOpt Mission type for which the assets are optimized. Default is the same as `MissionTypeRecruit`.
@ -3181,7 +3183,7 @@ function LEGION.CalculateAssetMissionScore(asset, MissionType, TargetVec2, Inclu
if currmission.type==AUFTRAG.Type.ALERT5 and currmission.alert5MissionType==MissionType then if currmission.type==AUFTRAG.Type.ALERT5 and currmission.alert5MissionType==MissionType then
-- Prefer assets that are on ALERT5 for this mission type. -- Prefer assets that are on ALERT5 for this mission type.
score=score+25 score=score+25
elseif currmission.type==AUFTRAG.Type.GCICAP and MissionType==AUFTRAG.Type.INTERCEPT then elseif (currmission.type==AUFTRAG.Type.GCICAP or currmission.type==AUFTRAG.Type.PATROLRACETRACK) and MissionType==AUFTRAG.Type.INTERCEPT then
-- Prefer assets that are on GCICAP to perform INTERCEPTS. We set this even higher than alert5 because they are already in the air. -- Prefer assets that are on GCICAP to perform INTERCEPTS. We set this even higher than alert5 because they are already in the air.
score=score+35 score=score+35
elseif (currmission.type==AUFTRAG.Type.ONGUARD or currmission.type==AUFTRAG.Type.PATROLZONE) and (MissionType==AUFTRAG.Type.ARTY or MissionType==AUFTRAG.Type.GROUNDATTACK) then elseif (currmission.type==AUFTRAG.Type.ONGUARD or currmission.type==AUFTRAG.Type.PATROLZONE) and (MissionType==AUFTRAG.Type.ARTY or MissionType==AUFTRAG.Type.GROUNDATTACK) then

View File

@ -4468,6 +4468,26 @@ function OPSGROUP:_UpdateTask(Task, Mission)
self:EngageTarget(target, speed, Task.dcstask.params.formation) self:EngageTarget(target, speed, Task.dcstask.params.formation)
end end
elseif Task.dcstask.id==AUFTRAG.SpecialTask.PATROLRACETRACK then
---
-- Task "Patrol Race Track" Mission.
---
if self.isFlightgroup then
self:T("We are Special Auftrag Patrol Race Track, starting now ...")
--self:I({Task.dcstask.params})
--[[
Task.dcstask.params.TrackAltitude = self.TrackAltitude
Task.dcstask.params.TrackSpeed = self.TrackSpeed
Task.dcstask.params.TrackPoint1 = self.TrackPoint1
Task.dcstask.params.TrackPoint2 = self.TrackPoint2
Task.dcstask.params.TrackFormation = self.TrackFormation
--]]
local aircraft = self:GetGroup()
aircraft:PatrolRaceTrack(Task.dcstask.params.TrackPoint1,Task.dcstask.params.TrackPoint2,Task.dcstask.params.TrackAltitude,Task.dcstask.params.TrackSpeed,Task.dcstask.params.TrackFormation,false,1)
end
elseif Task.dcstask.id==AUFTRAG.SpecialTask.HOVER then elseif Task.dcstask.id==AUFTRAG.SpecialTask.HOVER then
--- ---

View File

@ -21,7 +21,7 @@
-- === -- ===
-- @module Ops.PlayerTask -- @module Ops.PlayerTask
-- @image OPS_PlayerTask.jpg -- @image OPS_PlayerTask.jpg
-- @date Last Update Sept 2023 -- @date Last Update Oct 2023
do do
@ -98,7 +98,7 @@ PLAYERTASK = {
--- PLAYERTASK class version. --- PLAYERTASK class version.
-- @field #string version -- @field #string version
PLAYERTASK.version="0.1.20" PLAYERTASK.version="0.1.21"
--- Generic task condition. --- Generic task condition.
-- @type PLAYERTASK.Condition -- @type PLAYERTASK.Condition
@ -470,10 +470,11 @@ end
--- [User] Remove a client from this task --- [User] Remove a client from this task
-- @param #PLAYERTASK self -- @param #PLAYERTASK self
-- @param Wrapper.Client#CLIENT Client -- @param Wrapper.Client#CLIENT Client
-- @param #string Name Name of the client
-- @return #PLAYERTASK self -- @return #PLAYERTASK self
function PLAYERTASK:RemoveClient(Client) function PLAYERTASK:RemoveClient(Client,Name)
self:T(self.lid.."RemoveClient") self:T(self.lid.."RemoveClient")
local name = Client:GetPlayerName() local name = Name or Client:GetPlayerName()
if self.Clients:HasUniqueID(name) then if self.Clients:HasUniqueID(name) then
self.Clients:PullByID(name) self.Clients:PullByID(name)
if self.verbose then if self.verbose then
@ -1551,7 +1552,7 @@ PLAYERTASKCONTROLLER.Messages = {
--- PLAYERTASK class version. --- PLAYERTASK class version.
-- @field #string version -- @field #string version
PLAYERTASKCONTROLLER.version="0.1.61" PLAYERTASKCONTROLLER.version="0.1.62"
--- Create and run a new TASKCONTROLLER instance. --- Create and run a new TASKCONTROLLER instance.
-- @param #PLAYERTASKCONTROLLER self -- @param #PLAYERTASKCONTROLLER self
@ -2186,6 +2187,10 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData)
task:RemoveClient(Client) task:RemoveClient(Client)
--text = "Task aborted!" --text = "Task aborted!"
text = self.gettext:GetEntry("TASKABORT",self.locale) text = self.gettext:GetEntry("TASKABORT",self.locale)
else
task:RemoveClient(nil,EventData.IniPlayerName)
--text = "Task aborted!"
text = self.gettext:GetEntry("TASKABORT",self.locale)
end end
else else
--text = "No active task!" --text = "No active task!"

View File

@ -5329,3 +5329,54 @@ function CONTROLLABLE:TaskAerobaticsBarrelRoll(TaskAerobatics,Repeats,InitAltitu
return TaskAerobatics return TaskAerobatics
end end
--- [Air] Make an airplane or helicopter patrol between two points in a racetrack - resulting in a much tighter track around the start and end points.
-- @param #CONTROLLABLE self
-- @param Core.Point#COORDINATE Point1 Start point.
-- @param Core.Point#COORDINATE Point2 End point.
-- @param #number Altitude (Optional) Altitude in meters. Defaults to the altitude of the coordinate.
-- @param #number Speed (Optional) Speed in kph. Defaults to 500 kph.
-- @param #number Formation (Optional) Formation to take, e.g. ENUMS.Formation.FixedWing.Trail.Close, also see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_option_formation).
-- @param #boolean AGL (Optional) If true, set altitude to above ground level (AGL), not above sea level (ASL).
-- @param #number Delay (Optional) Set the task after delay seconds only.
-- @return #CONTROLLABLE self
function CONTROLLABLE:PatrolRaceTrack(Point1, Point2, Altitude, Speed, Formation, AGL, Delay)
local PatrolGroup = self -- Wrapper.Group#GROUP
if not self:IsInstanceOf( "GROUP" ) then
PatrolGroup = self:GetGroup() -- Wrapper.Group#GROUP
end
local delay = Delay or 1
self:F( { PatrolGroup = PatrolGroup:GetName() } )
if PatrolGroup:IsAir() then
if Formation then
PatrolGroup:SetOption(AI.Option.Air.id.FORMATION,Formation) -- https://wiki.hoggitworld.com/view/DCS_option_formation
end
local FromCoord = PatrolGroup:GetCoordinate()
local ToCoord = Point1:GetCoordinate()
-- Calculate the new Route
if Altitude then
local asl = true
if AGL then asl = false end
FromCoord:SetAltitude(Altitude, asl)
ToCoord:SetAltitude(Altitude, asl)
end
-- Create a "air waypoint", which is a "point" structure that can be given as a parameter to a Task
local Route = {}
Route[#Route + 1] = FromCoord:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description, timeReFuAr )
Route[#Route + 1] = ToCoord:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description, timeReFuAr )
local TaskRouteToZone = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolRaceTrack", Point2, Point1, Altitude, Speed, Formation, Delay )
PatrolGroup:SetTaskWaypoint( Route[#Route], TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone.
PatrolGroup:Route( Route, Delay ) -- Move after delay seconds to the Route. See the Route method for details.
end
return self
end

View File

@ -20,8 +20,8 @@
-- @module Wrapper.Unit -- @module Wrapper.Unit
-- @image Wrapper_Unit.JPG -- @image Wrapper_Unit.JPG
---
--- @type UNIT -- @type UNIT
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #string UnitName Name of the unit. -- @field #string UnitName Name of the unit.
-- @field #string GroupName Name of the group the unit belongs to. -- @field #string GroupName Name of the group the unit belongs to.
@ -561,7 +561,7 @@ end
--- Check if the unit is a tanker. Also retrieves the refuelling system (boom or probe) if applicable. --- Check if the unit is a tanker. Also retrieves the refuelling system (boom or probe) if applicable.
-- @param #UNIT self -- @param #UNIT self
-- @return #boolean If true, unit is refuelable (checks for the attribute "Refuelable"). -- @return #boolean If true, unit is a tanker (checks for the attribute "Tankers").
-- @return #number Refueling system (if any): 0=boom, 1=probe. -- @return #number Refueling system (if any): 0=boom, 1=probe.
function UNIT:IsTanker() function UNIT:IsTanker()
self:F2( self.UnitName ) self:F2( self.UnitName )
@ -582,7 +582,7 @@ function UNIT:IsTanker()
-- Some hard coded data as this is not in the descriptors... -- Some hard coded data as this is not in the descriptors...
if typename=="IL-78M" then if typename=="IL-78M" then
system=1 --probe system=1 --probe
elseif typename=="KC130" then elseif typename=="KC130" or typename=="KC130J" then
system=1 --probe system=1 --probe
elseif typename=="KC135BDA" then elseif typename=="KC135BDA" then
system=1 --probe system=1 --probe
@ -590,6 +590,10 @@ function UNIT:IsTanker()
system=1 --probe system=1 --probe
elseif typename=="S-3B Tanker" then elseif typename=="S-3B Tanker" then
system=1 --probe system=1 --probe
elseif typename=="KC_10_Extender" then
system=1 --probe
elseif typename=="KC_10_Extender_D" then
system=0 --boom
end end
end end

View File

@ -1,3 +1,5 @@
baseurl: ""
url: "https://flightcontrol-master.github.io"
repository: FlightControl-Master/MOOSE repository: FlightControl-Master/MOOSE
title: MOOSE title: MOOSE
description: MOOSE is a Mission Object Oriented Scripting Environment for mission designers in DCS World description: MOOSE is a Mission Object Oriented Scripting Environment for mission designers in DCS World

View File

@ -0,0 +1,73 @@
---
parent: Build system
nav_order: 2
---
# Build class documentation
The documentation of all classes are included in the code as comments.
This kind of documentation process is called [LuaDoc]. But we build the
html files for the documentation with [LuaDocumentor]. It is a tool
similar to [LuaDoc], but with some additional features the Moose team
decided to use.
{: .important }
> The team created also some modifications, which are not part of the
> official [LuaDocumentor] tool. So we use the code in the git repository
> [Applevangelist/luadocumentor] in the branch `patch-1`.
There are two git repositories which are used to save the generated
documentation:
- [MOOSE_DOCS] is the repository for the `master` branch of [MOOSE]
- A configured GitHub Pages job will deploy the result to:<br/>
<https://flightcontrol-master.github.io/MOOSE_DOCS/>
- [MOOSE_DOCS_DEVELOP] is the repository for the `develop` branch of [MOOSE]
- A configured GitHub Pages job will deploy the result to:<br/>
<https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/>
Main build steps to create the class documentation are defined in [.github/workflows/build-docs.yml]:
- Checkout of the git repository [MOOSE].
- Create output folders.
- Checkout of the git repository [Applevangelist/luadocumentor] with
branch `patch-1` into a subdirectory.
- Update the Linux system software.
- Install needed tools:
- [tree] - A tool to output a tree view of a folder structure.
- [lua] - Package to run [Lua] scripts. This time [Lua] 5.1,
because it matches the DCS environment.
- [LuaRocks] - This is the package manager for Lua modules.
- [markdown] - Dependency for [LuaDocumentor]
- [penlight] - Dependency for [LuaDocumentor]
- [metalua-compiler] - Dependency for [LuaDocumentor]
- [metalua-parser] - Dependency for [metalua-compiler]
- [checks] - Dependency for [metalua-parser]
- Run the build steps:
- Run `luadocumentor.lua` to create the html files.
- Deploy build results:
- Checkout [MOOSE_DOCS] or [MOOSE_DOCS_DEVELOP] git repository in a subdirectory.
- Use the matching git repository for the branch of [MOOSE].
- `master` -> [MOOSE_DOCS].
- `develop` -> [MOOSE_DOCS_DEVELOP].
- Use a `TOKEN` for checkout, so a `push` is possible later on.
- Copy build result to `MOOSE_DOCS` folder.
- Push results to the target repository.
[tree]: https://wiki.ubuntuusers.de/tree/
[LuaDoc]: https://keplerproject.github.io/luadoc/
[LuaDocumentor]: https://luarocks.org/modules/luarocks/luadocumentor
[Applevangelist/luadocumentor]: https://github.com/Applevangelist/luadocumentor/tree/patch-1
[markdown]: https://luarocks.org/modules/mpeterv/markdown
[penlight]: https://luarocks.org/modules/tieske/penlight
[metalua-compiler]: https://luarocks.org/modules/luarocks/metalua-compiler
[metalua-parser]: https://luarocks.org/modules/luarocks/metalua-parser
[checks]: https://luarocks.org/modules/fab13n/checks
[MOOSE]: https://github.com/FlightControl-Master/MOOSE
[MOOSE_DOCS]: https://github.com/FlightControl-Master/MOOSE_DOCS
[MOOSE_DOCS_DEVELOP]: https://github.com/FlightControl-Master/MOOSE_DOCS_DEVELOP
[Lua]: https://www.lua.org/
[LuaRocks]: https://luarocks.org/
[.github/workflows/build-docs.yml]: https://github.com/FlightControl-Master/MOOSE/blob/master/.github/workflows/build-docs.yml

View File

@ -0,0 +1,45 @@
---
parent: Build system
nav_order: 1
---
# Build include files
Main build steps to create the include files are defined in [.github/workflows/build-includes.yml]:
- Checkout of the git repository [MOOSE].
- Create output folders.
- Update the Linux system software.
- Install needed tools:
- [tree] - A tool to output a tree view of a folder structure.
- [lua5.3] - Package to run [Lua] scripts. Version 5.3 is needed, because we
need liblua5.3-dev for [LuaSrcDiet].
- [LuaRocks] - LuaRocks is the package manager for Lua modules.
- liblua5.3-dev - Header file of [Lua] needed for [LuaSrcDiet] to work.
- [LuaSrcDiet] - To compress the [Lua] code and create `Moose_.lua`.
- [LuaCheck] - This is a static code analyzer and a linter for [Lua].
- Run the build steps:
- Run `./Moose Setup/Moose_Create.lua` to create `Moose.lua`.
- Run `./Moose Setup/Moose_Create.lua` to create dynamic `Moose.lua` to
load individual Lua class files used by Moose developers.
- Run [LuaSrcDiet] to compress the [Lua] code and create `Moose_.lua`
- Run [LuaCheck] to find errors in the code. Warnings are ignored, because
there are a lot of warnings, which cannot be resolved by the Moose team.
- Deploy build results:
- Checkout [MOOSE_INCLUDE] git repository in a subdirectory.
- Use the same branch used to checkout [MOOSE] git repository.
- Use a `TOKEN` for checkout, so a `push` is possible later on.
- Copy build result to `MOOSE_INCLUDE` folder
- Push results to [MOOSE_INCLUDE] repository
[.github/workflows/build-includes.yml]: https://github.com/FlightControl-Master/MOOSE/blob/master/.github/workflows/build-includes.yml
[tree]: https://wiki.ubuntuusers.de/tree/
[lua5.3]: https://www.lua.org/manual/5.3/
[LuaRocks]: https://luarocks.org/
[LuaCheck]: https://github.com/mpeterv/luacheck
[MOOSE]: https://github.com/FlightControl-Master/MOOSE
[MOOSE_INCLUDE]: https://github.com/FlightControl-Master/MOOSE_INCLUDE
[LuaSrcDiet]: https://github.com/jirutka/luasrcdiet
[Lua]: https://www.lua.org/

View File

@ -0,0 +1,51 @@
---
parent: Build system
nav_order: 3
---
# Build GitHub Pages
This documentation is created by [GitHub Pages]. The source files are
stored in the repository [MOOSE] in the subfolder `docs`.
We use [Just the Docs], which is a modern, highly customizable, and responsive
[Jekyll] theme for documentation.
{: .note }
> The class documentation is created by its own [build] and is not the scope for this page!
The build steps to create this documentation are defined in [.github/workflows/gh-pages.yml].
It is divided into two jobs:
- build:
- Only changes to in the subfolder `docs` or `gh-pages.yml` will trigger a build.
- Checkout of the git repository [MOOSE].
- Setup [Ruby] version 3.1, which is needed by [Jekyll].
- Run action [configure-pages].
- Build with [Jekyll].
- Run action [upload-pages-artifact].
- deploy:
- Run action [deploy-pages].
# Preview of this documentation
When enhancing this documentation it is very useful to see a 1on1 preview of the pages.
This can be displayed as follows:
- You need a working installation of [Docker].
- Go to the `docs` subfolder.
- Run `docker compose up`.
- Open a browser with the following URL: `http://127.0.0.1:4000/`.
- After a change of the [Markdown] files, wait some seconds and press F5 in the browser.
[GitHub Pages]: https://pages.github.com/
[MOOSE]: https://github.com/FlightControl-Master/MOOSE
[Just the Docs]: https://github.com/just-the-docs/just-the-docs
[Jekyll]: https://jekyllrb.com/
[Ruby]: https://www.ruby-lang.org/en/
[build]: build-docs.md
[.github/workflows/gh-pages.yml]: https://github.com/FlightControl-Master/MOOSE/blob/master/.github/workflows/gh-pages.yml
[configure-pages]: https://github.com/actions/configure-pages/
[upload-pages-artifact]: https://github.com/actions/upload-pages-artifact
[deploy-pages]: https://github.com/actions/deploy-pages/
[Docker]: https://www.docker.com/
[Markdown]: https://www.markdownguide.org/

58
docs/buildsystem/index.md Normal file
View File

@ -0,0 +1,58 @@
---
has_children: true
nav_order: 3
---
# Build system
{: .note }
> This documentation is not needed for end users. Only the people of the
> development team, who must maintain the build system need to read this.
In this document we want to describe our build system for MOOSE.
MOOSE consists of multiple [Lua] files. Each class is stored in its own file.
This is needed for MOOSE developers to maintain clarity.
For users this is not practical, because they want to include the whole framework
as a single file into their missions.
Because of this the build will collect all needed files and merge them together
in one file with the name `Moose.lua`. It includes also all comments and the
class documentation. Because of this its size is about 6-7 MB.
To reduce the size of the file and make mission files smaller, the Moose team
decided to create a version without all comments and documentation. This file
is named `Moose_.lua`. It is created by a tool with the name [LuaSrcDiet].
Both files will be called static includes. In other programming languages includes
are dependencies. For Moose it is easier to memorize, that these files must be
included in your mission to use Moose. It is an static approach because you need
to add it once and it is only read from inside of the mission file after that.
A dynamic approach is to load all the single class files on each mission start
from the hard disk. But this is more for advanced Moose users and Moose developers.
## Details
In the past [AppVeyor] was used to run the build on a Windows system.
We decided to migrate this build to [GitHub Actions]. Installation of
dependencies was not stable on Windows with [GitHub Actions]. So we switched
to Ubuntu Linux.
### GitHub Actions yml files
The build configuration is stored in the folder `.github/workflows`. You will find
multiple files in this directory:
- [build-docs.yml] - Job definition to generate the class documentation
- [build-includes.yml] - Job definition to build the static includes
- [gh-pages.yml] - Job to build this documentation page
We decided to use different files for each job for separation of duties and easier
maintenance.
[Lua]: https://www.lua.org/
[LuaSrcDiet]: https://github.com/jirutka/luasrcdiet
[AppVeyor]: https://www.appveyor.com/
[GitHub Actions]: https://docs.github.com/en/actions
[build-docs.yml]: build-docs.md
[build-includes.yml]: build-includes.md
[gh-pages.yml]: gh-pages.md

View File

@ -0,0 +1,49 @@
---
parent: Build system
nav_order: 4
---
# Run builds locally
When creating or enhancing [GitHub Actions] builds it is a problem to test the
build. After each change you need to commit and check the build result. This
leads to a lot of unnecessary commits.
Therefor it is needed to run the build locally on the developer PC. The tool
which enabled this is [act]. It uses [Docker] to create a build runner and
executes the [GitHub Actions] build with it.
[act] can by installed by [Chocolatey] by this single command: `choco install act-cli`.
We use the `Medium Docker Image` for our MOOSE builds to work properly.
Unfortunately the docker images used by [act] are not as up to date as the
images used by [GitHub Actions]. So we needed to add a build step with
`sudo apt-get -qq update`.
The build jobs needs `TOKENS` to run properly. So you have to create a PAT
([Personal Access Token]). A classic Token with read rights is enough to run
the build, as long as don't want to push the results.
{: .important }
> The push step is only executed if the variable `FORCE_PUSH` with value `true` is set.
> - This is only needed if the push step itself must be change and tested!
> - Add parameter `--var FORCE_PUSH=true` to your [act] commando.
> - You and your PAT needs write access to the target repos, too.
Save your PAT in the file `.secrets` in the main folder
of the MOOSE repository. This file is added to `.gitignore`, so it is not
recognized by git for commits. Add the following line to `.secrets`:
```
BOT_TOKEN=<your PAT>
```
To run the builds use these commands:
- `act push -W .github/workflows/build-includes.yml`
- `act push -W .github/workflows/build-docs.yml`
[GitHub Actions]: https://docs.github.com/en/actions
[act]: https://github.com/nektos/act
[Docker]: https://www.docker.com/
[Chocolatey]: https://community.chocolatey.org/
[Personal Access Token]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens