mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Merge branch 'develop' into FF/Ops
This commit is contained in:
commit
6a26f62ca1
@ -16,20 +16,20 @@
|
|||||||
--- *In order for the light to shine so brightly, the darkness must be present.* -- Francis Bacon
|
--- *In order for the light to shine so brightly, the darkness must be present.* -- Francis Bacon
|
||||||
--
|
--
|
||||||
-- After attaching a @{#BEACON} to your @{Wrapper.Positionable#POSITIONABLE}, you need to select the right function to activate the kind of beacon you want.
|
-- After attaching a @{#BEACON} to your @{Wrapper.Positionable#POSITIONABLE}, you need to select the right function to activate the kind of beacon you want.
|
||||||
-- There are two types of BEACONs available : the AA TACAN Beacon and the general purpose Radio Beacon.
|
-- There are two types of BEACONs available : the (aircraft) TACAN Beacon and the general purpose Radio Beacon.
|
||||||
-- Note that in both case, you can set an optional parameter : the `BeaconDuration`. This can be very usefull to simulate the battery time if your BEACON is
|
-- Note that in both case, you can set an optional parameter : the `BeaconDuration`. This can be very usefull to simulate the battery time if your BEACON is
|
||||||
-- attach to a cargo crate, for exemple.
|
-- attach to a cargo crate, for exemple.
|
||||||
--
|
--
|
||||||
-- ## AA TACAN Beacon usage
|
-- ## Aircraft TACAN Beacon usage
|
||||||
--
|
--
|
||||||
-- This beacon only works with airborne @{Wrapper.Unit#UNIT} or a @{Wrapper.Group#GROUP}. Use @{#BEACON:AATACAN}() to set the beacon parameters and start the beacon.
|
-- This beacon only works with airborne @{Wrapper.Unit#UNIT} or a @{Wrapper.Group#GROUP}. Use @{#BEACON.ActivateTACAN}() to set the beacon parameters and start the beacon.
|
||||||
-- Use @#BEACON:StopAATACAN}() to stop it.
|
-- Use @{#BEACON.StopRadioBeacon}() to stop it.
|
||||||
--
|
--
|
||||||
-- ## General Purpose Radio Beacon usage
|
-- ## General Purpose Radio Beacon usage
|
||||||
--
|
--
|
||||||
-- This beacon will work with any @{Wrapper.Positionable#POSITIONABLE}, but **it won't follow the @{Wrapper.Positionable#POSITIONABLE}** ! This means that you should only use it with
|
-- This beacon will work with any @{Wrapper.Positionable#POSITIONABLE}, but **it won't follow the @{Wrapper.Positionable#POSITIONABLE}** ! This means that you should only use it with
|
||||||
-- @{Wrapper.Positionable#POSITIONABLE} that don't move, or move very slowly. Use @{#BEACON:RadioBeacon}() to set the beacon parameters and start the beacon.
|
-- @{Wrapper.Positionable#POSITIONABLE} that don't move, or move very slowly. Use @{#BEACON.RadioBeacon}() to set the beacon parameters and start the beacon.
|
||||||
-- Use @{#BEACON:StopRadioBeacon}() to stop it.
|
-- Use @{#BEACON.StopRadioBeacon}() to stop it.
|
||||||
--
|
--
|
||||||
-- @type BEACON
|
-- @type BEACON
|
||||||
-- @field #string ClassName Name of the class "BEACON".
|
-- @field #string ClassName Name of the class "BEACON".
|
||||||
@ -245,7 +245,8 @@ function BEACON:ActivateICLS(Channel, Callsign, Duration)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Activates a TACAN BEACON on an Aircraft.
|
--- DEPRECATED: Please use @{BEACON:ActivateTACAN}() instead.
|
||||||
|
-- Activates a TACAN BEACON on an Aircraft.
|
||||||
-- @param #BEACON self
|
-- @param #BEACON self
|
||||||
-- @param #number TACANChannel (the "10" part in "10Y"). Note that AA TACAN are only available on Y Channels
|
-- @param #number TACANChannel (the "10" part in "10Y"). Note that AA TACAN are only available on Y Channels
|
||||||
-- @param #string Message The Message that is going to be coded in Morse and broadcasted by the beacon
|
-- @param #string Message The Message that is going to be coded in Morse and broadcasted by the beacon
|
||||||
@ -325,7 +326,7 @@ function BEACON:StopAATACAN()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Activates a general pupose Radio Beacon
|
--- Activates a general purpose Radio Beacon
|
||||||
-- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency.
|
-- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency.
|
||||||
-- Although any frequency could be used, only 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8.
|
-- Although any frequency could be used, only 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8.
|
||||||
-- They can home in on these specific frequencies :
|
-- They can home in on these specific frequencies :
|
||||||
@ -402,7 +403,7 @@ function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDurati
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stops the AA TACAN BEACON
|
--- Stops the Radio Beacon
|
||||||
-- @param #BEACON self
|
-- @param #BEACON self
|
||||||
-- @return #BEACON self
|
-- @return #BEACON self
|
||||||
function BEACON:StopRadioBeacon()
|
function BEACON:StopRadioBeacon()
|
||||||
|
|||||||
@ -2777,8 +2777,10 @@ do -- COORDINATE
|
|||||||
-- @param #boolean Bogey Add "Bogey" at the end if true (not yet declared hostile or friendly)
|
-- @param #boolean Bogey Add "Bogey" at the end if true (not yet declared hostile or friendly)
|
||||||
-- @param #boolean Spades Add "Spades" at the end if true (no IFF/VID ID yet known)
|
-- @param #boolean Spades Add "Spades" at the end if true (no IFF/VID ID yet known)
|
||||||
-- @param #boolean SSML Add SSML tags speaking aspect as 0 1 2 and "brah" instead of BRAA
|
-- @param #boolean SSML Add SSML tags speaking aspect as 0 1 2 and "brah" instead of BRAA
|
||||||
|
-- @param #boolean Angels If true, altitude is e.g. "Angels 25" (i.e., a friendly plane), else "25 thousand"
|
||||||
|
-- @param #boolean Zeros If using SSML, be aware that Google TTS will say "oh" and not "zero" for "0"; if Zeros is set to true, "0" will be replaced with "zero"
|
||||||
-- @return #string The BRAA text.
|
-- @return #string The BRAA text.
|
||||||
function COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades,SSML)
|
function COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades,SSML,Angels,Zeros)
|
||||||
|
|
||||||
-- Thanks to @Pikey
|
-- Thanks to @Pikey
|
||||||
local BRAANATO = "Merged."
|
local BRAANATO = "Merged."
|
||||||
@ -2796,14 +2798,36 @@ do -- COORDINATE
|
|||||||
|
|
||||||
local alt = UTILS.Round(UTILS.MetersToFeet(self.y)/1000,0)--*1000
|
local alt = UTILS.Round(UTILS.MetersToFeet(self.y)/1000,0)--*1000
|
||||||
|
|
||||||
|
local alttext = string.format("%d thousand",alt)
|
||||||
|
|
||||||
|
if Angels then
|
||||||
|
alttext = string.format("Angels %d",alt)
|
||||||
|
end
|
||||||
|
|
||||||
|
if alt < 1 then
|
||||||
|
alttext = "very low"
|
||||||
|
end
|
||||||
|
|
||||||
local track = UTILS.BearingToCardinal(bearing) or "North"
|
local track = UTILS.BearingToCardinal(bearing) or "North"
|
||||||
|
|
||||||
if rangeNM > 3 then
|
if rangeNM > 3 then
|
||||||
if SSML then
|
if SSML then -- google says "oh" instead of zero, be aware
|
||||||
|
if Zeros then
|
||||||
|
bearing = string.format("%03d",bearing)
|
||||||
|
local AngleDegText = string.gsub(bearing,"%d","%1 ") -- "0 5 1 "
|
||||||
|
AngleDegText = string.gsub(AngleDegText," $","") -- "0 5 1"
|
||||||
|
AngleDegText = string.gsub(AngleDegText,"0","zero")
|
||||||
if aspect == "" then
|
if aspect == "" then
|
||||||
BRAANATO = string.format("brah <say-as interpret-as='characters'>%03d</say-as>, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
|
BRAANATO = string.format("brah %s, %d miles, %s, Track %s", AngleDegText, rangeNM, alttext, track)
|
||||||
else
|
else
|
||||||
BRAANATO = string.format("brah <say-as interpret-as='characters'>%03d</say-as>, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
|
BRAANATO = string.format("brah %s, %d miles, %s, %s, Track %s", AngleDegText, rangeNM, alttext, aspect, track)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if aspect == "" then
|
||||||
|
BRAANATO = string.format("brah <say-as interpret-as='characters'>%03d</say-as>, %d miles, %s, Track %s", bearing, rangeNM, alttext, track)
|
||||||
|
else
|
||||||
|
BRAANATO = string.format("brah <say-as interpret-as='characters'>%03d</say-as>, %d miles, %s, %s, Track %s", bearing, rangeNM, alttext, aspect, track)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if Bogey and Spades then
|
if Bogey and Spades then
|
||||||
BRAANATO = BRAANATO..", Bogey, Spades."
|
BRAANATO = BRAANATO..", Bogey, Spades."
|
||||||
@ -2816,9 +2840,9 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
if aspect == "" then
|
if aspect == "" then
|
||||||
BRAANATO = string.format("BRA %03d, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
|
BRAANATO = string.format("BRA %03d, %d miles, %s, Track %s",bearing, rangeNM, alttext, track)
|
||||||
else
|
else
|
||||||
BRAANATO = string.format("BRAA %03d, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
|
BRAANATO = string.format("BRAA %03d, %d miles, %s, %s, Track %s",bearing, rangeNM, alttext, aspect, track)
|
||||||
end
|
end
|
||||||
if Bogey and Spades then
|
if Bogey and Spades then
|
||||||
BRAANATO = BRAANATO..", Bogey, Spades."
|
BRAANATO = BRAANATO..", Bogey, Spades."
|
||||||
|
|||||||
@ -4180,6 +4180,26 @@ do -- SET_CLIENT
|
|||||||
return CountU
|
return CountU
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Gets the alive set.
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @return #table Table of SET objects
|
||||||
|
function SET_CLIENT:GetAliveSet()
|
||||||
|
|
||||||
|
local AliveSet = SET_CLIENT:New()
|
||||||
|
|
||||||
|
-- Clean the Set before returning with only the alive Groups.
|
||||||
|
for GroupName, GroupObject in pairs(self.Set) do
|
||||||
|
local GroupObject=GroupObject --Wrapper.Client#CLIENT
|
||||||
|
|
||||||
|
if GroupObject and GroupObject:IsAlive() then
|
||||||
|
AliveSet:Add(GroupName, GroupObject)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return AliveSet.Set or {}
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #SET_CLIENT self
|
-- @param #SET_CLIENT self
|
||||||
-- @param Wrapper.Client#CLIENT MClient
|
-- @param Wrapper.Client#CLIENT MClient
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
|||||||
-- @module Ops.CSAR
|
-- @module Ops.CSAR
|
||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
-- Date: Feb 2022
|
-- Date: June 2022
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
@ -76,65 +76,69 @@
|
|||||||
--
|
--
|
||||||
-- The following options are available (with their defaults). Only set the ones you want changed:
|
-- The following options are available (with their defaults). Only set the ones you want changed:
|
||||||
--
|
--
|
||||||
-- self.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined Arms.
|
-- mycsar.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined Arms.
|
||||||
-- self.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only!
|
-- mycsar.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only!
|
||||||
-- self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued.
|
-- mycsar.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued.
|
||||||
-- self.autosmoke = false -- automatically smoke a downed pilot\'s location when a heli is near.
|
-- mycsar.autosmoke = false -- automatically smoke a downed pilot\'s location when a heli is near.
|
||||||
-- self.autosmokedistance = 1000 -- distance for autosmoke
|
-- mycsar.autosmokedistance = 1000 -- distance for autosmoke
|
||||||
-- self.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates.
|
-- mycsar.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates.
|
||||||
-- self.csarOncrash = false -- (WIP) If set to true, will generate a downed pilot when a plane crashes as well.
|
-- mycsar.csarOncrash = false -- (WIP) If set to true, will generate a downed pilot when a plane crashes as well.
|
||||||
-- self.enableForAI = false -- set to false to disable AI pilots from being rescued.
|
-- mycsar.enableForAI = false -- set to false to disable AI pilots from being rescued.
|
||||||
-- self.pilotRuntoExtractPoint = true -- Downed pilot will run to the rescue helicopter up to self.extractDistance in meters.
|
-- mycsar.pilotRuntoExtractPoint = true -- Downed pilot will run to the rescue helicopter up to mycsar.extractDistance in meters.
|
||||||
-- self.extractDistance = 500 -- Distance the downed pilot will start to run to the rescue helicopter.
|
-- mycsar.extractDistance = 500 -- Distance the downed pilot will start to run to the rescue helicopter.
|
||||||
-- self.immortalcrew = true -- Set to true to make wounded crew immortal.
|
-- mycsar.immortalcrew = true -- Set to true to make wounded crew immortal.
|
||||||
-- self.invisiblecrew = false -- Set to true to make wounded crew insvisible.
|
-- mycsar.invisiblecrew = false -- Set to true to make wounded crew insvisible.
|
||||||
-- self.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters.
|
-- mycsar.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters.
|
||||||
-- self.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes.
|
-- mycsar.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes.
|
||||||
-- self.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined.
|
-- mycsar.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined.
|
||||||
-- self.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages.
|
-- mycsar.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages.
|
||||||
-- self.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons.
|
-- mycsar.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons.
|
||||||
-- self.smokecolor = 4 -- Color of smokemarker, 0 is green, 1 is red, 2 is white, 3 is orange and 4 is blue.
|
-- mycsar.smokecolor = 4 -- Color of smokemarker, 0 is green, 1 is red, 2 is white, 3 is orange and 4 is blue.
|
||||||
-- self.useprefix = true -- Requires CSAR helicopter #GROUP names to have the prefix(es) defined below.
|
-- mycsar.useprefix = true -- Requires CSAR helicopter #GROUP names to have the prefix(es) defined below.
|
||||||
-- self.csarPrefix = { "helicargo", "MEDEVAC"} -- #GROUP name prefixes used for useprefix=true - DO NOT use # in helicopter names in the Mission Editor!
|
-- mycsar.csarPrefix = { "helicargo", "MEDEVAC"} -- #GROUP name prefixes used for useprefix=true - DO NOT use # in helicopter names in the Mission Editor!
|
||||||
-- self.verbose = 0 -- set to > 1 for stats output for debugging.
|
-- mycsar.verbose = 0 -- set to > 1 for stats output for debugging.
|
||||||
-- -- (added 0.1.4) limit amount of downed pilots spawned by **ejection** events
|
-- -- (added 0.1.4) limit amount of downed pilots spawned by **ejection** events
|
||||||
-- self.limitmaxdownedpilots = true
|
-- mycsar.limitmaxdownedpilots = true
|
||||||
-- self.maxdownedpilots = 10
|
-- mycsar.maxdownedpilots = 10
|
||||||
-- -- (added 0.1.8) - allow to set far/near distance for approach and optionally pilot must open doors
|
-- -- (added 0.1.8) - allow to set far/near distance for approach and optionally pilot must open doors
|
||||||
-- self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
|
-- mycsar.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
|
||||||
-- self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
-- mycsar.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
||||||
-- self.pilotmustopendoors = false -- switch to true to enable check of open doors
|
-- mycsar.pilotmustopendoors = false -- switch to true to enable check of open doors
|
||||||
-- -- (added 0.1.9)
|
-- -- (added 0.1.9)
|
||||||
-- self.suppressmessages = false -- switch off all messaging if you want to do your own
|
-- mycsar.suppressmessages = false -- switch off all messaging if you want to do your own
|
||||||
-- -- (added 0.1.11)
|
-- -- (added 0.1.11)
|
||||||
-- self.rescuehoverheight = 20 -- max height for a hovering rescue in meters
|
-- mycsar.rescuehoverheight = 20 -- max height for a hovering rescue in meters
|
||||||
-- self.rescuehoverdistance = 10 -- max distance for a hovering rescue in meters
|
-- mycsar.rescuehoverdistance = 10 -- max distance for a hovering rescue in meters
|
||||||
-- -- (added 0.1.12)
|
-- -- (added 0.1.12)
|
||||||
-- -- Country codes for spawned pilots
|
-- -- Country codes for spawned pilots
|
||||||
-- self.countryblue= country.id.USA
|
-- mycsar.countryblue= country.id.USA
|
||||||
-- self.countryred = country.id.RUSSIA
|
-- mycsar.countryred = country.id.RUSSIA
|
||||||
-- self.countryneutral = country.id.UN_PEACEKEEPERS
|
-- mycsar.countryneutral = country.id.UN_PEACEKEEPERS
|
||||||
--
|
--
|
||||||
-- ## 2.1 Experimental Features
|
-- ## 2.1 Experimental Features
|
||||||
--
|
--
|
||||||
-- WARNING - Here\'ll be dragons!
|
-- WARNING - Here\'ll be dragons!
|
||||||
-- DANGER - For this to work you need to de-sanitize your mission environment (all three entries) in <DCS root>\Scripts\MissionScripting.lua
|
-- DANGER - For this to work you need to de-sanitize your mission environment (all three entries) in <DCS root>\Scripts\MissionScripting.lua
|
||||||
-- Needs SRS => 1.9.6 to work (works on the **server** side of SRS)
|
-- Needs SRS => 1.9.6 to work (works on the **server** side of SRS)
|
||||||
-- self.useSRS = false -- Set true to use FF\'s SRS integration
|
-- mycsar.useSRS = false -- Set true to use FF\'s SRS integration
|
||||||
-- self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!)
|
-- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!)
|
||||||
-- self.SRSchannel = 300 -- radio channel
|
-- mycsar.SRSchannel = 300 -- radio channel
|
||||||
-- self.SRSModulation = radio.modulation.AM -- modulation
|
-- mycsar.SRSModulation = radio.modulation.AM -- modulation
|
||||||
-- self.SRSport = 5002 -- and SRS port
|
-- mycsar.SRSport = 5002 -- and SRS Server port
|
||||||
|
-- mycsar.SRSCulture = "en-GB" -- SRS voice culture
|
||||||
|
-- mycsar.SRSVoice = nil -- SRS voice, relevant for Google TTS
|
||||||
|
-- mycsar.SRSGPathToCredentials = nil -- Path to your Google credentials json file, set this if you want to use Google TTS
|
||||||
|
-- mycsar.SRSVolume = 1 -- Volume, between 0 and 1
|
||||||
-- --
|
-- --
|
||||||
-- self.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection --shagrat
|
-- mycsar.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection. Requires mycsar.enableForAI to be set to true. --shagrat
|
||||||
-- self.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases.
|
-- mycsar.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases.
|
||||||
--
|
--
|
||||||
-- ## 3. Results
|
-- ## 3. Results
|
||||||
--
|
--
|
||||||
-- Number of successful landings with save pilots and aggregated number of saved pilots is stored in these variables in the object:
|
-- Number of successful landings with save pilots and aggregated number of saved pilots is stored in these variables in the object:
|
||||||
--
|
--
|
||||||
-- self.rescues -- number of successful landings *with* saved pilots
|
-- mycsar.rescues -- number of successful landings *with* saved pilots
|
||||||
-- self.rescuedpilots -- aggregated number of pilots rescued from the field (of *all* players)
|
-- mycsar.rescuedpilots -- aggregated number of pilots rescued from the field (of *all* players)
|
||||||
--
|
--
|
||||||
-- ## 4. Events
|
-- ## 4. Events
|
||||||
--
|
--
|
||||||
@ -260,7 +264,7 @@ CSAR.AircraftType["AH-64D_BLK_II"] = 2
|
|||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CSAR.version="1.0.4e"
|
CSAR.version="1.0.6"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@ -329,6 +333,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
self:AddTransition("*", "Status", "*") -- CSAR status update.
|
self:AddTransition("*", "Status", "*") -- CSAR status update.
|
||||||
self:AddTransition("*", "PilotDown", "*") -- Downed Pilot added
|
self:AddTransition("*", "PilotDown", "*") -- Downed Pilot added
|
||||||
self:AddTransition("*", "Approach", "*") -- CSAR heli closing in.
|
self:AddTransition("*", "Approach", "*") -- CSAR heli closing in.
|
||||||
|
self:AddTransition("*", "Landed", "*") -- CSAR heli landed
|
||||||
self:AddTransition("*", "Boarded", "*") -- Pilot boarded.
|
self:AddTransition("*", "Boarded", "*") -- Pilot boarded.
|
||||||
self:AddTransition("*", "Returning", "*") -- CSAR able to return to base.
|
self:AddTransition("*", "Returning", "*") -- CSAR able to return to base.
|
||||||
self:AddTransition("*", "Rescued", "*") -- Pilot at MASH.
|
self:AddTransition("*", "Rescued", "*") -- Pilot at MASH.
|
||||||
@ -415,6 +420,10 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
self.SRSchannel = 300 -- radio channel
|
self.SRSchannel = 300 -- radio channel
|
||||||
self.SRSModulation = radio.modulation.AM -- modulation
|
self.SRSModulation = radio.modulation.AM -- modulation
|
||||||
self.SRSport = 5002 -- port
|
self.SRSport = 5002 -- port
|
||||||
|
self.SRSCulture = "en-GB"
|
||||||
|
self.SRSVoice = nil
|
||||||
|
self.SRSGPathToCredentials = nil
|
||||||
|
self.SRSVolume = 1
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
--- Pseudo Functions ---
|
--- Pseudo Functions ---
|
||||||
@ -466,6 +475,15 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
-- @param #string Heliname Name of the helicopter group.
|
-- @param #string Heliname Name of the helicopter group.
|
||||||
-- @param #string Woundedgroupname Name of the downed pilot\'s group.
|
-- @param #string Woundedgroupname Name of the downed pilot\'s group.
|
||||||
|
|
||||||
|
--- On After "Landed" event. Heli landed at an airbase.
|
||||||
|
-- @function [parent=#CSAR] OnAfterLanded
|
||||||
|
-- @param #CSAR self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #string HeliName Name of the #UNIT which has landed.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where the heli landed.
|
||||||
|
|
||||||
--- On After "Boarded" event. Downed pilot boarded heli.
|
--- On After "Boarded" event. Downed pilot boarded heli.
|
||||||
-- @function [parent=#CSAR] OnAfterBoarded
|
-- @function [parent=#CSAR] OnAfterBoarded
|
||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
@ -861,12 +879,12 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
-- no Player
|
-- no Player
|
||||||
if self.enableForAI == false and _event.IniPlayerName == nil then
|
if self.enableForAI == false and _event.IniPlayerName == nil then
|
||||||
return
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- no event
|
-- no event
|
||||||
if _event == nil or _event.initiator == nil then
|
if _event == nil or _event.initiator == nil then
|
||||||
return false
|
return self
|
||||||
|
|
||||||
-- take off
|
-- take off
|
||||||
elseif _event.id == EVENTS.Takeoff then -- taken off
|
elseif _event.id == EVENTS.Takeoff then -- taken off
|
||||||
@ -874,35 +892,43 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
local _coalition = _event.IniCoalition
|
local _coalition = _event.IniCoalition
|
||||||
if _coalition ~= self.coalition then
|
if _coalition ~= self.coalition then
|
||||||
return --ignore!
|
return self --ignore!
|
||||||
end
|
end
|
||||||
|
|
||||||
if _event.IniGroupName then
|
if _event.IniGroupName then
|
||||||
self.takenOff[_event.IniUnitName] = true
|
self.takenOff[_event.IniUnitName] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return self
|
||||||
|
|
||||||
-- player enter unit
|
-- player enter unit
|
||||||
elseif _event.id == EVENTS.PlayerEnterAircraft or _event.id == EVENTS.PlayerEnterUnit then --player entered unit
|
elseif _event.id == EVENTS.PlayerEnterAircraft or _event.id == EVENTS.PlayerEnterUnit then --player entered unit
|
||||||
self:T(self.lid .. " Event unit - Player Enter")
|
self:T(self.lid .. " Event unit - Player Enter")
|
||||||
|
|
||||||
local _coalition = _event.IniCoalition
|
local _coalition = _event.IniCoalition
|
||||||
|
self:T("Coalition = "..UTILS.GetCoalitionName(_coalition))
|
||||||
if _coalition ~= self.coalition then
|
if _coalition ~= self.coalition then
|
||||||
return --ignore!
|
return self --ignore!
|
||||||
end
|
end
|
||||||
|
|
||||||
if _event.IniPlayerName then
|
if _event.IniPlayerName then
|
||||||
self.takenOff[_event.IniPlayerName] = nil
|
self.takenOff[_event.IniPlayerName] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- jumped into flying plane?
|
||||||
|
self:T("Taken Off: "..tostring(_event.IniUnit:InAir(true)))
|
||||||
|
|
||||||
|
if _event.IniUnit:InAir(true) then
|
||||||
|
self.takenOff[_event.IniPlayerName] = true
|
||||||
|
end
|
||||||
|
|
||||||
local _unit = _event.IniUnit
|
local _unit = _event.IniUnit
|
||||||
local _group = _event.IniGroup
|
local _group = _event.IniGroup
|
||||||
if _unit:IsHelicopter() or _group:IsHelicopter() then
|
if _unit:IsHelicopter() or _group:IsHelicopter() then
|
||||||
self:_AddMedevacMenuItem()
|
self:_AddMedevacMenuItem()
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return self
|
||||||
|
|
||||||
elseif (_event.id == EVENTS.PilotDead and self.csarOncrash == false) then
|
elseif (_event.id == EVENTS.PilotDead and self.csarOncrash == false) then
|
||||||
-- Pilot dead
|
-- Pilot dead
|
||||||
@ -914,29 +940,29 @@ function CSAR:_EventHandler(EventData)
|
|||||||
local _group = _event.IniGroup
|
local _group = _event.IniGroup
|
||||||
|
|
||||||
if _unit == nil then
|
if _unit == nil then
|
||||||
return -- error!
|
return self -- error!
|
||||||
end
|
end
|
||||||
|
|
||||||
local _coalition = _event.IniCoalition
|
local _coalition = _event.IniCoalition
|
||||||
if _coalition ~= self.coalition then
|
if _coalition ~= self.coalition then
|
||||||
return --ignore!
|
return self --ignore!
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Catch multiple events here?
|
-- Catch multiple events here?
|
||||||
if self.takenOff[_event.IniUnitName] == true or _group:IsAirborne() then
|
if self.takenOff[_event.IniUnitName] == true or _group:IsAirborne() then
|
||||||
if self:_DoubleEjection(_unitname) then
|
if self:_DoubleEjection(_unitname) then
|
||||||
return
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
self:T(self.lid .. " Pilot has not taken off, ignore")
|
self:T(self.lid .. " Pilot has not taken off, ignore")
|
||||||
end
|
end
|
||||||
|
|
||||||
return
|
return self
|
||||||
|
|
||||||
elseif _event.id == EVENTS.PilotDead or _event.id == EVENTS.Ejection then
|
elseif _event.id == EVENTS.PilotDead or _event.id == EVENTS.Ejection then
|
||||||
if _event.id == EVENTS.PilotDead and self.csarOncrash == false then
|
if _event.id == EVENTS.PilotDead and self.csarOncrash == false then
|
||||||
return
|
return self
|
||||||
end
|
end
|
||||||
self:T(self.lid .. " Event unit - Pilot Ejected")
|
self:T(self.lid .. " Event unit - Pilot Ejected")
|
||||||
|
|
||||||
@ -944,27 +970,38 @@ function CSAR:_EventHandler(EventData)
|
|||||||
local _unitname = _event.IniUnitName
|
local _unitname = _event.IniUnitName
|
||||||
local _group = _event.IniGroup
|
local _group = _event.IniGroup
|
||||||
|
|
||||||
|
self:T({_unit.UnitName, _unitname, _group.GroupName})
|
||||||
|
|
||||||
if _unit == nil then
|
if _unit == nil then
|
||||||
return -- error!
|
self:T("Unit NIL!")
|
||||||
|
return self -- error!
|
||||||
end
|
end
|
||||||
|
|
||||||
local _coalition = _unit:GetCoalition()
|
--local _coalition = _unit:GetCoalition() -- nil now for some reason
|
||||||
|
local _coalition = _group:GetCoalition()
|
||||||
if _coalition ~= self.coalition then
|
if _coalition ~= self.coalition then
|
||||||
return --ignore!
|
self:T("Wrong coalition! Coalition = "..UTILS.GetCoalitionName(_coalition))
|
||||||
|
return self --ignore!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
self:T("Airborne: "..tostring(_group:IsAirborne()))
|
||||||
|
self:T("Taken Off: "..tostring(self.takenOff[_event.IniUnitName]))
|
||||||
|
|
||||||
if not self.takenOff[_event.IniUnitName] and not _group:IsAirborne() then
|
if not self.takenOff[_event.IniUnitName] and not _group:IsAirborne() then
|
||||||
self:T(self.lid .. " Pilot has not taken off, ignore")
|
self:T(self.lid .. " Pilot has not taken off, ignore")
|
||||||
return -- give up, pilot hasnt taken off
|
-- return self -- give up, pilot hasnt taken off
|
||||||
end
|
end
|
||||||
|
|
||||||
if self:_DoubleEjection(_unitname) then
|
if self:_DoubleEjection(_unitname) then
|
||||||
return
|
self:T("Double Ejection!")
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- limit no of pilots in the field.
|
-- limit no of pilots in the field.
|
||||||
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
||||||
return
|
self:T("Maxed Downed Pilot!")
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -973,34 +1010,32 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
local wetfeet = false
|
local wetfeet = false
|
||||||
|
|
||||||
local surface = _unit:GetCoordinate():GetSurfaceType()
|
local initdcscoord = nil
|
||||||
|
local initcoord = nil
|
||||||
|
if _event.id == EVENTS.Ejection then
|
||||||
|
initdcscoord = _event.TgtDCSUnit:getPoint()
|
||||||
|
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||||
|
self:T({initdcscoord})
|
||||||
|
else
|
||||||
|
initdcscoord = _event.IniDCSUnit:getPoint()
|
||||||
|
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||||
|
self:T({initdcscoord})
|
||||||
|
end
|
||||||
|
|
||||||
|
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
||||||
|
local surface = initcoord:GetSurfaceType()
|
||||||
|
|
||||||
if surface == land.SurfaceType.WATER then
|
if surface == land.SurfaceType.WATER then
|
||||||
|
self:T("Wet feet!")
|
||||||
wetfeet = true
|
wetfeet = true
|
||||||
end
|
end
|
||||||
-- all checks passed, get going.
|
-- all checks passed, get going.
|
||||||
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
|
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
|
||||||
local _freq = self:_GenerateADFFrequency()
|
local _freq = self:_GenerateADFFrequency()
|
||||||
self:_AddCsar(_coalition, _unit:GetCountry(), _unit:GetCoordinate() , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none")
|
self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none")
|
||||||
return true
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
---- shagrat on event LANDING_AFTER_EJECTION spawn pilot at parachute location
|
|
||||||
elseif (_event.id == EVENTS.LandingAfterEjection and self.csarUsePara == true) then
|
|
||||||
self:I({EVENT=_event})
|
|
||||||
local _LandingPos = COORDINATE:NewFromVec3(_event.initiator:getPosition().p)
|
|
||||||
local _unitname = "Aircraft" --_event.initiator:getName() or "Aircraft" --shagrat Optional use of Object name which is unfortunately 'f15_Pilot_Parachute'
|
|
||||||
local _typename = "Ejected Pilot" --_event.Initiator.getTypeName() or "Ejected Pilot"
|
|
||||||
local _country = _event.initiator:getCountry()
|
|
||||||
local _coalition = coalition.getCountryCoalition( _country )
|
|
||||||
if _coalition == self.coalition then
|
|
||||||
local _freq = self:_GenerateADFFrequency()
|
|
||||||
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
|
|
||||||
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, false, "none")--shagrat add CSAR at Parachute location.
|
|
||||||
|
|
||||||
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
|
|
||||||
elseif _event.id == EVENTS.Land then
|
elseif _event.id == EVENTS.Land then
|
||||||
self:T(self.lid .. " Landing")
|
self:T(self.lid .. " Landing")
|
||||||
|
|
||||||
@ -1014,12 +1049,14 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
if _unit == nil then
|
if _unit == nil then
|
||||||
self:T(self.lid .. " Unit nil on landing")
|
self:T(self.lid .. " Unit nil on landing")
|
||||||
return -- error!
|
return self -- error!
|
||||||
end
|
end
|
||||||
|
|
||||||
local _coalition = _event.IniCoalition
|
--local _coalition = _event.IniCoalition
|
||||||
|
local _coalition = _event.IniGroup:GetCoalition()
|
||||||
if _coalition ~= self.coalition then
|
if _coalition ~= self.coalition then
|
||||||
return --ignore!
|
self:T(self.lid .. " Wrong coalition")
|
||||||
|
return self --ignore!
|
||||||
end
|
end
|
||||||
|
|
||||||
self.takenOff[_event.IniUnitName] = nil
|
self.takenOff[_event.IniUnitName] = nil
|
||||||
@ -1028,24 +1065,44 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
if _place == nil then
|
if _place == nil then
|
||||||
self:T(self.lid .. " Landing Place Nil")
|
self:T(self.lid .. " Landing Place Nil")
|
||||||
return -- error!
|
return self -- error!
|
||||||
end
|
end
|
||||||
|
|
||||||
-- anyone on board?
|
-- anyone on board?
|
||||||
if self.inTransitGroups[_event.IniUnitName] == nil then
|
if self.inTransitGroups[_event.IniUnitName] == nil then
|
||||||
-- ignore
|
-- ignore
|
||||||
return
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
||||||
|
self:__Landed(2,_event.IniUnitName, _place)
|
||||||
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true)
|
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true)
|
||||||
else
|
else
|
||||||
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
|
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---- shagrat on event LANDING_AFTER_EJECTION spawn pilot at parachute location
|
||||||
|
if (_event.id == EVENTS.LandingAfterEjection and self.csarUsePara == true) then
|
||||||
|
self:T("LANDING_AFTER_EJECTION")
|
||||||
|
local _LandingPos = COORDINATE:NewFromVec3(_event.initiator:getPosition().p)
|
||||||
|
local _unitname = "Aircraft" --_event.initiator:getName() or "Aircraft" --shagrat Optional use of Object name which is unfortunately 'f15_Pilot_Parachute'
|
||||||
|
local _typename = "Ejected Pilot" --_event.Initiator.getTypeName() or "Ejected Pilot"
|
||||||
|
local _country = _event.initiator:getCountry()
|
||||||
|
local _coalition = coalition.getCountryCoalition( _country )
|
||||||
|
self:T("Country = ".._country.." Coalition = ".._coalition)
|
||||||
|
if _coalition == self.coalition then
|
||||||
|
local _freq = self:_GenerateADFFrequency()
|
||||||
|
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
|
||||||
|
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, false, "none")--shagrat add CSAR at Parachute location.
|
||||||
|
|
||||||
|
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1145,7 +1202,7 @@ function CSAR:_CheckWoundedGroupStatus(heliname,woundedgroupname)
|
|||||||
self.heliVisibleMessage[_lookupKeyHeli] = nil
|
self.heliVisibleMessage[_lookupKeyHeli] = nil
|
||||||
self.heliCloseMessage[_lookupKeyHeli] = nil
|
self.heliCloseMessage[_lookupKeyHeli] = nil
|
||||||
self.landedStatus[_lookupKeyHeli] = nil
|
self.landedStatus[_lookupKeyHeli] = nil
|
||||||
self:T("...helinunit nil!")
|
self:T("...heliunit nil!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1240,8 +1297,8 @@ function CSAR:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupNam
|
|||||||
_maxUnits = self.max_units
|
_maxUnits = self.max_units
|
||||||
end
|
end
|
||||||
if _unitsInHelicopter + 1 > _maxUnits then
|
if _unitsInHelicopter + 1 > _maxUnits then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, string.format("%s, %s. We\'re already crammed with %d guys! Sorry!", _pilotName, _heliName, _unitsInHelicopter, _unitsInHelicopter), self.messageTime)
|
self:_DisplayMessageToSAR(_heliUnit, string.format("%s, %s. We\'re already crammed with %d guys! Sorry!", _pilotName, _heliName, _unitsInHelicopter, _unitsInHelicopter), self.messageTime,false,false,true)
|
||||||
return true
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
local found,downedgrouptable = self:_CheckNameInDownedPilots(_woundedGroupName)
|
local found,downedgrouptable = self:_CheckNameInDownedPilots(_woundedGroupName)
|
||||||
@ -1262,7 +1319,7 @@ function CSAR:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupNam
|
|||||||
|
|
||||||
self:__Boarded(5,_heliName,_woundedGroupName)
|
self:__Boarded(5,_heliName,_woundedGroupName)
|
||||||
|
|
||||||
return true
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Move group to destination.
|
--- (Internal) Move group to destination.
|
||||||
@ -1329,6 +1386,7 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
|
|||||||
if _time == nil then
|
if _time == nil then
|
||||||
self.landedStatus[_lookupKeyHeli] = math.floor( (_distance - self.loadDistance) / 3.6 )
|
self.landedStatus[_lookupKeyHeli] = math.floor( (_distance - self.loadDistance) / 3.6 )
|
||||||
_time = self.landedStatus[_lookupKeyHeli]
|
_time = self.landedStatus[_lookupKeyHeli]
|
||||||
|
_woundedGroup:OptionAlarmStateGreen()
|
||||||
self:_OrderGroupToMoveToPoint(_woundedGroup, _heliUnit:GetCoordinate())
|
self:_OrderGroupToMoveToPoint(_woundedGroup, _heliUnit:GetCoordinate())
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Wait till " .. _pilotName .. " gets in. \nETA " .. _time .. " more seconds.", self.messageTime, false)
|
self:_DisplayMessageToSAR(_heliUnit, "Wait till " .. _pilotName .. " gets in. \nETA " .. _time .. " more seconds.", self.messageTime, false)
|
||||||
else
|
else
|
||||||
@ -1337,24 +1395,24 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
|
|||||||
end
|
end
|
||||||
--if _time <= 0 or _distance < self.loadDistance then
|
--if _time <= 0 or _distance < self.loadDistance then
|
||||||
if _distance < self.loadDistance + 5 or _distance <= 13 then
|
if _distance < self.loadDistance + 5 or _distance <= 13 then
|
||||||
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then
|
if self.pilotmustopendoors and (self:_IsLoadingDoorOpen(_heliName) == false) then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true, true)
|
||||||
return true
|
return false
|
||||||
else
|
else
|
||||||
self.landedStatus[_lookupKeyHeli] = nil
|
self.landedStatus[_lookupKeyHeli] = nil
|
||||||
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
|
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
|
||||||
return false
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (_distance < self.loadDistance) then
|
if (_distance < self.loadDistance) then
|
||||||
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then
|
if self.pilotmustopendoors and (self:_IsLoadingDoorOpen(_heliName) == false) then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true, true)
|
||||||
return true
|
return false
|
||||||
else
|
else
|
||||||
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
|
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
|
||||||
return false
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1391,18 +1449,19 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
|
|||||||
if _time > 0 then
|
if _time > 0 then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Hovering above " .. _pilotName .. ". \n\nHold hover for " .. _time .. " seconds to winch them up. \n\nIf the countdown stops you\'re too far away!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Hovering above " .. _pilotName .. ". \n\nHold hover for " .. _time .. " seconds to winch them up. \n\nIf the countdown stops you\'re too far away!", self.messageTime, true)
|
||||||
else
|
else
|
||||||
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then
|
if self.pilotmustopendoors and (self:_IsLoadingDoorOpen(_heliName) == false) then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true, true)
|
||||||
return true
|
return false
|
||||||
else
|
else
|
||||||
self.hoverStatus[_lookupKeyHeli] = nil
|
self.hoverStatus[_lookupKeyHeli] = nil
|
||||||
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
|
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
|
||||||
return false
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
_reset = false
|
_reset = false
|
||||||
else
|
else
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Too high to winch " .. _pilotName .. " \nReduce height and hover for 10 seconds!", self.messageTime, true,true)
|
self:_DisplayMessageToSAR(_heliUnit, "Too high to winch " .. _pilotName .. " \nReduce height and hover for 10 seconds!", self.messageTime, true,true)
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1451,7 +1510,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport)
|
|||||||
|
|
||||||
if ( _dist < self.FARPRescueDistance or isairport ) and _heliUnit:InAir() == false then
|
if ( _dist < self.FARPRescueDistance or isairport ) and _heliUnit:InAir() == false then
|
||||||
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then
|
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true, true)
|
||||||
else
|
else
|
||||||
self:_RescuePilots(_heliUnit)
|
self:_RescuePilots(_heliUnit)
|
||||||
return
|
return
|
||||||
@ -1526,6 +1585,14 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid
|
|||||||
local channel = self.SRSchannel
|
local channel = self.SRSchannel
|
||||||
local msrs = MSRS:New(path,channel,modulation)
|
local msrs = MSRS:New(path,channel,modulation)
|
||||||
msrs:SetPort(self.SRSport)
|
msrs:SetPort(self.SRSport)
|
||||||
|
msrs:SetLabel("CSAR")
|
||||||
|
msrs:SetCulture(self.SRSCulture)
|
||||||
|
msrs:SetCoalition(self.coalition)
|
||||||
|
msrs:SetVoice(self.SRSVoice)
|
||||||
|
if self.SRSGPathToCredentials then
|
||||||
|
msrs:SetGoogle(self.SRSGPathToCredentials)
|
||||||
|
end
|
||||||
|
msrs:SetVolume(self.SRSVolume)
|
||||||
msrs:PlaySoundText(srstext, 2)
|
msrs:PlaySoundText(srstext, 2)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@ -2026,7 +2093,7 @@ end
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function CSAR:onafterStart(From, Event, To)
|
function CSAR:onafterStart(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
self:I(self.lid .. "Started.")
|
self:I(self.lid .. "Started ("..self.version..")")
|
||||||
-- event handler
|
-- event handler
|
||||||
self:HandleEvent(EVENTS.Takeoff, self._EventHandler)
|
self:HandleEvent(EVENTS.Takeoff, self._EventHandler)
|
||||||
self:HandleEvent(EVENTS.Land, self._EventHandler)
|
self:HandleEvent(EVENTS.Land, self._EventHandler)
|
||||||
@ -2226,6 +2293,18 @@ function CSAR:onbeforePilotDown(From, Event, To, Group, Frequency, Leadername, C
|
|||||||
self:T({From, Event, To, Group, Frequency, Leadername, CoordinatesText})
|
self:T({From, Event, To, Group, Frequency, Leadername, CoordinatesText})
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function called before Landed() event.
|
||||||
|
-- @param #CSAR self.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event triggered.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #string HeliName Name of the #UNIT which has landed.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where the heli landed.
|
||||||
|
function CSAR:onbeforeLanded(From, Event, To, HeliName, Airbase)
|
||||||
|
self:T({From, Event, To, HeliName, Airbase})
|
||||||
|
return self
|
||||||
|
end
|
||||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- End Ops.CSAR
|
-- End Ops.CSAR
|
||||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -723,6 +723,7 @@ do
|
|||||||
-- ["Mi-24V"] = {type="Mi-24V", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18, cargoweightlimit = 700},
|
-- ["Mi-24V"] = {type="Mi-24V", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18, cargoweightlimit = 700},
|
||||||
-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25, cargoweightlimit = 19000},
|
-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25, cargoweightlimit = 19000},
|
||||||
-- ["UH-60L"] = {type="UH-60L", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500},
|
-- ["UH-60L"] = {type="UH-60L", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500},
|
||||||
|
-- ["AH-64D_BLK_II"] = {type="AH-64D_BLK_II", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 17, cargoweightlimit = 200},
|
||||||
--
|
--
|
||||||
-- ### 2.1.2 Activate and deactivate zones
|
-- ### 2.1.2 Activate and deactivate zones
|
||||||
--
|
--
|
||||||
@ -870,12 +871,13 @@ do
|
|||||||
--
|
--
|
||||||
-- ## 5. Support for Hercules mod by Anubis
|
-- ## 5. Support for Hercules mod by Anubis
|
||||||
--
|
--
|
||||||
-- 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.
|
-- Basic support for the Hercules mod By Anubis has been build into CTLD - that is you can load/drop/build the same way and for the same objects as
|
||||||
-- 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
|
-- the helicopters (main method).
|
||||||
-- 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
|
-- To cover objects and troops which can be loaded from the groud crew Rearm/Refuel menu (F8), you need to use @{#CTLD_HERCULES.New}() and link
|
||||||
|
-- this object to your CTLD setup (alternative method). In this case, do **not** use the `Hercules_Cargo.lua` or `Hercules_Cargo_CTLD.lua` which are part of the mod
|
||||||
-- in your mission!
|
-- in your mission!
|
||||||
--
|
--
|
||||||
-- ### 5.1 Create an own CTLD instance and allow the usage of the Hercules mod:
|
-- ### 5.1 Create an own CTLD instance and allow the usage of the Hercules mod (main method)
|
||||||
--
|
--
|
||||||
-- local my_ctld = CTLD:New(coalition.side.BLUE,{"Helicargo", "Hercules"},"Lufttransportbrigade I")
|
-- local my_ctld = CTLD:New(coalition.side.BLUE,{"Helicargo", "Hercules"},"Lufttransportbrigade I")
|
||||||
--
|
--
|
||||||
@ -893,10 +895,11 @@ do
|
|||||||
--
|
--
|
||||||
-- my_ctld.useprefix = true -- this is true by default and MUST BE ON.
|
-- my_ctld.useprefix = true -- this is true by default and MUST BE ON.
|
||||||
--
|
--
|
||||||
-- ### 5.2 Integrate Hercules ground crew loadable objects
|
-- ### 5.2 Integrate Hercules ground crew (F8 Menu) loadable objects (alternative method)
|
||||||
--
|
--
|
||||||
-- Add ground crew loadable objects to your CTLD instance like so, where `my_ctld` is the previously created CTLD instance:
|
-- Integrate to your CTLD instance like so, where `my_ctld` is a previously created CTLD instance:
|
||||||
--
|
--
|
||||||
|
-- my_ctld.enableHercules = false -- avoid dual loading via CTLD F10 and F8 ground crew
|
||||||
-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld)
|
-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld)
|
||||||
--
|
--
|
||||||
-- You also need:
|
-- You also need:
|
||||||
@ -906,6 +909,7 @@ do
|
|||||||
--
|
--
|
||||||
-- There's a **quick check output in the `dcs.log`** which tells you what's there and what not.
|
-- There's a **quick check output in the `dcs.log`** which tells you what's there and what not.
|
||||||
-- E.g.:
|
-- E.g.:
|
||||||
|
--
|
||||||
-- ...Checking template for APC BTR-82A Air [24998lb] (BTR-82A) ... MISSING)
|
-- ...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 ART 2S9 NONA Skid [19030lb] (SAU 2-C9) ... MISSING)
|
||||||
-- ...Checking template for EWR SBORKA Air [21624lb] (Dog Ear radar) ... MISSING)
|
-- ...Checking template for EWR SBORKA Air [21624lb] (Dog Ear radar) ... MISSING)
|
||||||
@ -913,6 +917,16 @@ do
|
|||||||
--
|
--
|
||||||
-- Expected template names are the ones in the rounded brackets.
|
-- Expected template names are the ones in the rounded brackets.
|
||||||
--
|
--
|
||||||
|
-- ### 5.2.1 Hints
|
||||||
|
--
|
||||||
|
-- The script works on the EVENTS.Shot trigger, which is used by the mod when you **drop cargo from the Hercules while flying**. Unloading on the ground does
|
||||||
|
-- not achieve anything here. If you just want to unload on the ground, use the normal Moose CTLD (see 5.1).
|
||||||
|
--
|
||||||
|
-- There are two ways of airdropping:
|
||||||
|
--
|
||||||
|
-- 1) Very low and very slow (>5m and <10m AGL) - here you can drop stuff which has "Skid" at the end of the cargo name (loaded via F8 Ground Crew menu)
|
||||||
|
-- 2) Higher up and slow (>100m AGL) - here you can drop paratroopers and cargo which has "Air" at the end of the cargo name (loaded via F8 Ground Crew menu)
|
||||||
|
--
|
||||||
-- Standard transport capabilities as per the real Hercules are:
|
-- Standard transport capabilities as per the real Hercules are:
|
||||||
--
|
--
|
||||||
-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers
|
-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers
|
||||||
@ -4792,10 +4806,11 @@ end
|
|||||||
end -- end do
|
end -- end do
|
||||||
|
|
||||||
do
|
do
|
||||||
--- Hercules Cargo Drop Events by Anubis Yinepu
|
--- **Hercules Cargo AIR Drop Events** by Anubis Yinepu
|
||||||
-- Moose CTLD OO refactoring by Applevangelist
|
-- Moose CTLD OO refactoring by Applevangelist
|
||||||
--
|
--
|
||||||
-- This script will only work for the Herculus mod by Anubis
|
-- This script will only work for the Herculus mod by Anubis, and only for **Air Dropping** cargo from the Hercules.
|
||||||
|
-- Use the standard Moose CTLD if you want to unload on the ground.
|
||||||
-- Payloads carried by pylons 11, 12 and 13 need to be declared in the Herculus_Loadout.lua file
|
-- Payloads carried by pylons 11, 12 and 13 need to be declared in the Herculus_Loadout.lua file
|
||||||
-- Except for Ammo pallets, this script will spawn whatever payload gets launched from pylons 11, 12 and 13
|
-- Except for Ammo pallets, this script will spawn whatever payload gets launched from pylons 11, 12 and 13
|
||||||
-- Pylons 11, 12 and 13 are moveable within the Herculus cargobay area
|
-- Pylons 11, 12 and 13 are moveable within the Herculus cargobay area
|
||||||
@ -4883,7 +4898,7 @@ CTLD_HERCULES.Types = {
|
|||||||
["ART GVOZDIKA [34720lb]"] = {['name'] = "SAU Gvozdika", ['container'] = false},
|
["ART GVOZDIKA [34720lb]"] = {['name'] = "SAU Gvozdika", ['container'] = false},
|
||||||
["APC MTLB Air [26400lb]"] = {['name'] = "MTLB", ['container'] = true},
|
["APC MTLB Air [26400lb]"] = {['name'] = "MTLB", ['container'] = true},
|
||||||
["APC MTLB Skid [26290lb]"] = {['name'] = "MTLB", ['container'] = false},
|
["APC MTLB Skid [26290lb]"] = {['name'] = "MTLB", ['container'] = false},
|
||||||
["Generic Crate [20000lb]"] = {['name'] = "Hercules_Container_Parachute", ['container'] = true} --nothing generic in Moose CTLD
|
--["Generic Crate [20000lb]"] = {['name'] = "Hercules_Container_Parachute", ['container'] = true} --nothing generic in Moose CTLD
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Cargo Object
|
--- Cargo Object
|
||||||
@ -4909,6 +4924,7 @@ CTLD_HERCULES.Types = {
|
|||||||
-- @usage
|
-- @usage
|
||||||
-- Integrate to your CTLD instance like so, where `my_ctld` is a previously created CTLD instance:
|
-- Integrate to your CTLD instance like so, where `my_ctld` is a previously created CTLD instance:
|
||||||
--
|
--
|
||||||
|
-- my_ctld.enableHercules = false -- avoid dual loading via CTLD F10 and F8 ground crew
|
||||||
-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld)
|
-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld)
|
||||||
--
|
--
|
||||||
-- You also need:
|
-- You also need:
|
||||||
@ -4922,6 +4938,14 @@ CTLD_HERCULES.Types = {
|
|||||||
-- ...Checking template for Transport Tigr Air [15900lb] (Tigr_233036) ... OK)
|
-- ...Checking template for Transport Tigr Air [15900lb] (Tigr_233036) ... OK)
|
||||||
--
|
--
|
||||||
-- Expected template names are the ones in the rounded brackets.
|
-- Expected template names are the ones in the rounded brackets.
|
||||||
|
--
|
||||||
|
-- HINTS
|
||||||
|
--
|
||||||
|
-- The script works on the EVENTS.Shot trigger, which is used by the mod when you **drop cargo from the Hercules while flying**. Unloading on the ground does
|
||||||
|
-- not achieve anything here. If you just want to unload on the ground, use the normal Moose CTLD.
|
||||||
|
-- There are two ways of airdropping:
|
||||||
|
-- 1) Very low and very slow (>5m and <10m AGL) - here you can drop stuff which has "Skid" at the end of the cargo name (loaded via F8 Ground Crew menu)
|
||||||
|
-- 2) Higher up and slow (>100m AGL) - here you can drop paratroopers and cargo which has "Air" at the end of the cargo name (loaded via F8 Ground Crew menu)
|
||||||
function CTLD_HERCULES:New(Coalition, Alias, CtldObject)
|
function CTLD_HERCULES:New(Coalition, Alias, CtldObject)
|
||||||
-- Inherit everything from FSM class.
|
-- Inherit everything from FSM class.
|
||||||
local self=BASE:Inherit(self, FSM:New()) -- #CTLD_HERCULES
|
local self=BASE:Inherit(self, FSM:New()) -- #CTLD_HERCULES
|
||||||
|
|||||||
@ -52,6 +52,7 @@ BIGSMOKEPRESET = {
|
|||||||
-- @field #string TheChannel The Channel map.
|
-- @field #string TheChannel The Channel map.
|
||||||
-- @field #string Syria Syria map.
|
-- @field #string Syria Syria map.
|
||||||
-- @field #string MarianaIslands Mariana Islands map.
|
-- @field #string MarianaIslands Mariana Islands map.
|
||||||
|
-- @field #string Falklands South Atlantic map.
|
||||||
DCSMAP = {
|
DCSMAP = {
|
||||||
Caucasus="Caucasus",
|
Caucasus="Caucasus",
|
||||||
NTTR="Nevada",
|
NTTR="Nevada",
|
||||||
@ -59,7 +60,8 @@ DCSMAP = {
|
|||||||
PersianGulf="PersianGulf",
|
PersianGulf="PersianGulf",
|
||||||
TheChannel="TheChannel",
|
TheChannel="TheChannel",
|
||||||
Syria="Syria",
|
Syria="Syria",
|
||||||
MarianaIslands="MarianaIslands"
|
MarianaIslands="MarianaIslands",
|
||||||
|
Falklands="Falklands",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1347,6 +1349,7 @@ end
|
|||||||
-- * The Cannel Map -10 (West)
|
-- * The Cannel Map -10 (West)
|
||||||
-- * Syria +5 (East)
|
-- * Syria +5 (East)
|
||||||
-- * Mariana Islands +2 (East)
|
-- * Mariana Islands +2 (East)
|
||||||
|
-- * Falklands +12 (East) - note there's a LOT of deviation across the map, as we're closer to the South Pole
|
||||||
-- @param #string map (Optional) Map for which the declination is returned. Default is from env.mission.theatre
|
-- @param #string map (Optional) Map for which the declination is returned. Default is from env.mission.theatre
|
||||||
-- @return #number Declination in degrees.
|
-- @return #number Declination in degrees.
|
||||||
function UTILS.GetMagneticDeclination(map)
|
function UTILS.GetMagneticDeclination(map)
|
||||||
@ -1369,6 +1372,8 @@ function UTILS.GetMagneticDeclination(map)
|
|||||||
declination=5
|
declination=5
|
||||||
elseif map==DCSMAP.MarianaIslands then
|
elseif map==DCSMAP.MarianaIslands then
|
||||||
declination=2
|
declination=2
|
||||||
|
elseif map==DCSMAP.Falklands then
|
||||||
|
declination=12
|
||||||
else
|
else
|
||||||
declination=0
|
declination=0
|
||||||
end
|
end
|
||||||
|
|||||||
@ -487,6 +487,28 @@ AIRBASE.MarianaIslands={
|
|||||||
["Olf_Orote"]="Olf Orote",
|
["Olf_Orote"]="Olf Orote",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Airbases of the South Atlantic map:
|
||||||
|
--
|
||||||
|
-- * AIRBASE.SouthAtlantic.Port_Stanley
|
||||||
|
-- * AIRBASE.SouthAtlantic.Mount_Pleasant
|
||||||
|
-- * AIRBASE.SouthAtlantic.San_Carlos_FOB
|
||||||
|
-- * AIRBASE.SouthAtlantic.Rio_Grande
|
||||||
|
-- * AIRBASE.SouthAtlantic.Rio_Gallegos
|
||||||
|
-- * AIRBASE.SouthAtlantic.Ushuaia
|
||||||
|
-- * AIRBASE.SouthAtlantic.Ushuaia_Helo_Port
|
||||||
|
-- * AIRBASE.SouthAtlantic.Punta_Arenas
|
||||||
|
--
|
||||||
|
--@field MarianaIslands
|
||||||
|
AIRBASE.SouthAtlantic={
|
||||||
|
["Port_Stanley"]="Port Stanley",
|
||||||
|
["Mount_Pleasant"]="Mount Pleasant",
|
||||||
|
["San_Carlos_FOB"]="San Carlos FOB",
|
||||||
|
["Rio_Grande"]="Rio Grande",
|
||||||
|
["Rio_Gallegos"]="Rio Gallegos",
|
||||||
|
["Ushuaia"]="Ushuaia",
|
||||||
|
["Ushuaia_Helo_Port"]="Ushuaia Helo Port",
|
||||||
|
["Punta_Arenas"]="Punta Arenas",
|
||||||
|
}
|
||||||
|
|
||||||
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
||||||
-- @type AIRBASE.ParkingSpot
|
-- @type AIRBASE.ParkingSpot
|
||||||
|
|||||||
@ -61,9 +61,10 @@ Documentation on the MOOSE class hierarchy, usage guides and background informat
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [MOOSE Youtube Channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg)
|
## [MOOSE Youtube Tutorials](https://youtube.com/playlist?list=PLLkY2GByvtC2ME0Q9wrKRDE6qnXJYV3iT)
|
||||||
|
|
||||||
MOOSE has a [broadcast and training channel on YouTube](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg) with various channels that you can watch.
|
Pene has kindly created a [tutorial series for MOOSE](https://youtube.com/playlist?list=PLLkY2GByvtC2ME0Q9wrKRDE6qnXJYV3iT)
|
||||||
|
with various videos that you can watch.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user