PseudoATC v0.7.0

Pseudo ATC improvements.
Minor changes in RAT and Suppression.
This commit is contained in:
funkyfranky 2018-05-09 00:11:53 +02:00
parent 95d7b8250d
commit 191fcb25be
3 changed files with 320 additions and 139 deletions

View File

@ -7,7 +7,7 @@
--
-- The pseudo ATC enhances the standard DCS ATC functions.
--
-- In particular, a menu entry "Pseudo ATC" is created in the special F10 menu.
-- In particular, a menu entry "Pseudo ATC" is created in the "F10 Other..." radiomenu.
--
-- ## Features
--
@ -17,18 +17,17 @@
-- * Report absolute bearing and range to nearest airports.
-- * Report current altitude AGL of own aircraft.
-- * Upon request, ATC reports altitude until touchdown.
-- * Pressure temperature, wind data and BR for mission waypoints.
-- * Report weather (pressure temperature, wind) and BR at players mission waypoints.
-- * Works with static and dynamic weather.
-- * All maps supported (Caucasus, NTTR, Normandy, and all future maps).
-- * Multiplayer ready (?) (I suppose yes, but I don't have a server to test or debug. Jumping from client to client works.)
-- * Player can select the unit system (metric or imperial) in which data is reported.
-- * All maps supported (Caucasus, NTTR, Normandy, Persion Gulf and all future maps).
--
-- Pressure units: hPa (european aircraft), mmHg (russian aircraft), inHg (american aircraft).
--
-- ====
--
-- # Demo Missions
--
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
-- ### [ALL Demo Missions of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master)
-- ### [ALL Demo Missions of the latest deveopment branch](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop)
--
-- ====
--
@ -40,7 +39,7 @@
--
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
--
-- ### Contributions: **Sven van de Velde ([FlightControl](https://forums.eagle.ru/member.php?u=89536))**
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536)**
--
-- ====
-- @module PseudoATC
@ -49,9 +48,10 @@
--- PSEUDOATC class
-- @type PSEUDOATC
-- @field #string ClassName Name of the Class.
-- @field #table player Table comprising each player info.
-- @field #boolean Debug If true, print debug info to dcs.log file.
-- @field #table player Table comprising the player info.
-- @field #number mdur Duration in seconds how low messages to the player are displayed.
-- @field #number mrefresh Interval in seconds after which the F10 menu is refreshed. E.g. by the closest airports.
-- @field #boolean eventsmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler.
-- @extends Core.Base#BASE
@ -60,19 +60,19 @@
--
-- ## Scripting:
--
-- Scripting is almost trivial. Just add the following line to your script:
-- Scripting is almost trivial. Just add the following two lines to your script:
--
-- PSEUDOATC:Start()
-- pseudoATC=PSEUDOATC:New()
-- pseudoATC:Start()
--
--
-- @field #PSEUDOATC
PSEUDOATC={
ClassName = "PSEUDOATC",
Debug=true,
player={},
maxairport=10,
Debug=false,
mdur=30,
mrefresh=120,
mrefresh=60,
eventsmoose=true,
}
@ -92,38 +92,93 @@ PSEUDOATC.unit={
PSEUDOATC.id="PseudoATC | "
--- PSEUDOATC version.
-- @field #list
PSEUDOATC.version={
version = "0.6.0",
print = true,
}
-- @field #number version
PSEUDOATC.version="0.7.0"
-----------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-- TODO: Add takeoff event.
-- TODO: Add user functions.
-----------------------------------------------------------------------------------------------------------------------------------------
--- PSEUDOATC contructor. Starts the PseudoATC.
-- @param #PSEUDOATC self
-- @return #PSEUDOATC Returns a PSEUDOATC object.
function PSEUDOATC:Start()
function PSEUDOATC:New()
-- Inherit BASE.
local self=BASE:Inherit(self, BASE:New()) -- #PSEUDOATC
-- Debug info
self:E(PSEUDOATC.id..string.format("Creating PseudoATC object. PseudoATC version %s", PSEUDOATC.version.version))
self:E(PSEUDOATC.id..string.format("PseudoATC version %s", PSEUDOATC.version))
-- Return object.
return self
end
--- PSEUDOATC contructor. Starts the PseudoATC.
-- @param #PSEUDOATC self
-- @return #PSEUDOATC Returns a PSEUDOATC object.
function PSEUDOATC:Start()
self:F()
-- Debug info
self:E(PSEUDOATC.id.."Starting PseudoATC")
-- Handle events.
if self.eventsmoose then
self:HandleEvent(EVENTS.Birth, self._OnBirth)
self:T(PSEUDOATC.id.."Events are handled by MOOSE.")
self:HandleEvent(EVENTS.Birth, self._OnBirth)
self:HandleEvent(EVENTS.Land, self._PlayerLanded)
self:HandleEvent(EVENTS.Takeoff, self._PlayerTakeOff)
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft)
--self:HandleEvent(EVENTS.PilotDead, self._PlayerLeft)
self:HandleEvent(EVENTS.Land, self._PlayerLanded)
--self:HandleEvent(EVENTS.Takeoff, self._PlayerTakeoff)
self:HandleEvent(EVENTS.Crash, self._PlayerLeft)
self:HandleEvent(EVENTS.Ejection, self._PlayerLeft)
--self:HandleEvent(EVENTS.PilotDead, self._PlayerLeft)
else
self:T(PSEUDOATC.id.."Events are handled by DCS.")
-- Events are handled directly by DCS.
world.addEventHandler(self)
end
-- Return object.
return self
end
-----------------------------------------------------------------------------------------------------------------------------------------
-- User Functions
--- Debug mode on. Send messages to everone.
-- @param #PSEUDOATC self
function PSEUDOATC:DebugOn()
self.Debug=true
end
--- Debug mode off. This is the default setting.
-- @param #PSEUDOATC self
function PSEUDOATC:DebugOff()
self.Debug=false
end
--- Set message duration how long messages are displayed.
-- @param #PSEUDOATC self
-- @param #number duration Time in seconds. Default is 30 sec.
function PSEUDOATC:SetMessageDuration(duration)
self.mdur=duration or 30
end
--- Set time interval after which the F10 radio menu is refreshed.
-- @param #PSEUDOATC self
-- @param #number interval Interval in seconds. Default is every 60 sec.
function PSEUDOATC:SetMessageDuration(interval)
self.mrefresh=interval or 60
end
--- Enable/disable event handling by MOOSE or DCS.
-- @param #PSEUDOATC self
-- @param #boolean switch If true, events are handled by MOOSE (default). If fase, events are handled directly by DCS.
function PSEUDOATC:SetMessageDuration(switch)
self.eventsmoose=switch
end
-----------------------------------------------------------------------------------------------------------------------------------------
@ -163,20 +218,23 @@ function PSEUDOATC:onEvent(Event)
end
-- Event info.
if self.Debug then
env.info(PSEUDOATC.id..string.format("EVENT: Event in onEvent with ID = %s", tostring(Event.id)))
env.info(PSEUDOATC.id..string.format("EVENT: Ini unit = %s" , tostring(EventData.IniUnitName)))
env.info(PSEUDOATC.id..string.format("EVENT: Ini group = %s" , tostring(EventData.IniGroupName)))
env.info(PSEUDOATC.id..string.format("EVENT: Ini player = %s" , tostring(_playername)))
env.info(PSEUDOATC.id..string.format("EVENT: Place = %s" , tostring(EventData.PlaceName)))
env.info(PSEUDOATC.id..string.format("EVENT: SubPlace = %s" , tostring(EventData.SubPlaceName)))
end
self:T3(PSEUDOATC.id..string.format("EVENT: Event in onEvent with ID = %s", tostring(Event.id)))
self:T3(PSEUDOATC.id..string.format("EVENT: Ini unit = %s" , tostring(EventData.IniUnitName)))
self:T3(PSEUDOATC.id..string.format("EVENT: Ini group = %s" , tostring(EventData.IniGroupName)))
self:T3(PSEUDOATC.id..string.format("EVENT: Ini player = %s" , tostring(_playername)))
self:T3(PSEUDOATC.id..string.format("EVENT: Place = %s" , tostring(EventData.PlaceName)))
self:T3(PSEUDOATC.id..string.format("EVENT: SubPlace = %s" , tostring(EventData.SubPlaceName)))
-- Event birth.
if Event.id == world.event.S_EVENT_BIRTH and _playername then
self:_OnBirth(EventData)
end
-- Event takeoff.
if Event.id == world.event.S_EVENT_TAKEOFF and _playername then
self:_PlayerTakeOff(EventData)
end
-- Event land.
if Event.id == world.event.S_EVENT_LAND and _playername and EventData.Place then
self:_PlayerLanded(EventData)
@ -186,6 +244,26 @@ function PSEUDOATC:onEvent(Event)
if Event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT and _playername then
self:_PlayerLeft(EventData)
end
-- Event crash ==> player left unit
if Event.id == world.event.S_EVENT_CRASH and _playername then
self:_PlayerLeft(EventData)
end
-- Event eject ==> player left unit
if Event.id == world.event.S_EVENT_EJECTION and _playername then
self:_PlayerLeft(EventData)
end
-- Event pilot dead ==> player left unit
if Event.id == world.event.S_EVENT_PILOT_DEAD and _playername then
self:_PlayerLeft(EventData)
end
-- Event pilot dead ==> player left unit
if Event.id == world.event.S_EVENT_PILOT_DEAD and _playername then
self:_PlayerLeft(EventData)
end
end
@ -248,6 +326,28 @@ function PSEUDOATC:_PlayerLanded(EventData)
end
end
--- Function called by MOOSE/DCS event handler when a player took off.
-- @param #PSEUDOATC self
-- @param Core.Event#EVENTDATA EventData
function PSEUDOATC:_PlayerTakeOff(EventData)
self:F({EventData=EventData})
-- Get unit, player and place.
local _unitName=EventData.IniUnitName
local _unit,_playername=self:_GetPlayerUnitAndName(_unitName)
local _base=nil
local _baseName=nil
if EventData.place then
_base=EventData.place
_baseName=EventData.place:getName()
end
-- Call take-off function.
if _unit and _playername and _base then
self:PlayerTakeOff(_unit, _baseName)
end
end
-----------------------------------------------------------------------------------------------------------------------------------------
-- Event Functions
@ -283,15 +383,15 @@ function PSEUDOATC:PlayerEntered(unit)
-- Create main F10 menu, i.e. "F10/Pseudo ATC"
self.player[GID].menu_main=missionCommands.addSubMenuForGroup(GID, "Pseudo ATC")
-- Create list of nearby airports.
-- Create/update list of nearby airports.
self:LocalAirports(GID)
-- Create submenu My Positon.
self:MenuAircraft(GID)
-- Create submenu airports.
-- Create submenu of local airports.
self:MenuAirports(GID)
-- Create submenu Waypoints.
self:MenuWaypoints(GID)
-- Start scheduler to refresh the F10 menues.
self.player[GID].scheduler, self.player[GID].schedulerid=SCHEDULER:New(nil, self.MenuRefresh, {self, GID}, self.mrefresh, self.mrefresh)
@ -319,7 +419,7 @@ function PSEUDOATC:PlayerLanded(unit, place)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
-- Stop altitude reporting timer if its activated.
self:AltidudeStopTimer(id)
self:AltitudeTimerStop(id)
-- Welcome message.
if place then
@ -329,11 +429,40 @@ function PSEUDOATC:PlayerLanded(unit, place)
end
--- Function called when a player took off.
-- @param #PSEUDOATC self
-- @param Wrapper.Unit#UNIT unit Unit of player which has landed.
-- @param #string place Name of the place the player landed at.
function PSEUDOATC:PlayerTakeOff(unit, place)
self:F2({unit=unit, place=place})
-- Gather some information.
local group=unit:GetGroup()
local id=group:GetID()
local PlayerName=self.player[id].playername
local Callsign=self.player[id].callsign
local UnitName=self.player[id].unitname
local GroupName=self.player[id].groupname
local CallSign=self.player[id].callsign
-- Debug message.
local text=string.format("Player %s (%s) from group %s (ID %d) took off at %s", PlayerName, UnitName, GroupName, id, place)
self:T(PSEUDOATC.id..text)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
-- Bye-Bye message.
if place then
local text=string.format("%s, %s, your are airborn. Have a save trip!", place, CallSign)
MESSAGE:New(text, self.mdur):ToGroup(group)
end
end
--- Function called when a player leaves a unit or dies.
-- @param #PSEUDOATC self
-- @param Wrapper.Unit#UNIT unit Player unit which was left.
function PSEUDOATC:PlayerLeft(unit)
self:F2({unit=unit})
self:F({unit=unit})
-- Get id.
local group=unit:GetGroup()
@ -348,10 +477,15 @@ function PSEUDOATC:PlayerLeft(unit)
if self.player[id].schedulerid then
self.player[id].scheduler:Stop(self.player[id].schedulerid)
end
-- Remove main menu.
missionCommands.removeItem(self.player[id].menu_main)
-- Stop scheduler for reporting alt if it runs.
self:AltitudeTimerStop(id)
-- Remove main menu.
if self.player[id].menu_main then
missionCommands.removeItem(self.player[id].menu_main)
end
-- Remove player array.
self.player[id]=nil
end
@ -375,12 +509,13 @@ function PSEUDOATC:MenuRefresh(id)
-- Create list of nearby airports.
self:LocalAirports(id)
-- Create submenu My Positon.
--self:MenuAircraft(id)
-- Create submenu airports.
-- Create submenu Local Airports.
self:MenuAirports(id)
-- Create submenu Waypoints etc.
self:MenuWaypoints(id)
end
@ -395,47 +530,49 @@ function PSEUDOATC:MenuClear(id)
self:T(PSEUDOATC.id..text)
MESSAGE:New(text,30):ToAllIf(self.Debug)
-- Delete Airports menu.
if self.player[id].menu_airports then
missionCommands.removeItemForGroup(id, self.player[id].menu_airports)
--[[
for name,item in pairs(self.player[id].menu_airports) do
-- Debug message.
self:E(PSEUDOATC.id..string.format("Deleting menu item %s for ID %d", name, id))
-- Remove menu item.
missionCommands.removeItemForGroup(id, self.player[id].menu_airports[name])
end
]]
self.player[id].menu_airports=nil
else
self:T2(PSEUDOATC.id.."No airports to clear menus.")
end
-- Remove
if self.player[id].menu_aircraft then
missionCommands.removeItemForGroup(id, self.player[id].menu_aircraft.main)
-- Delete waypoints menu.
if self.player[id].menu_waypoints then
missionCommands.removeItemForGroup(id, self.player[id].menu_waypoints)
self.player[id].menu_waypoints=nil
end
self.player[id].menu_airports=nil
--self.player[id].menu_aircraft=nil
-- Delete report alt until touchdown menu command.
if self.player[id].menu_reportalt then
missionCommands.removeItemForGroup(id, self.player[id].menu_reportalt)
self.player[id].menu_reportalt=nil
end
-- Delete request current alt menu command.
if self.player[id].menu_requesttalt then
missionCommands.removeItemForGroup(id, self.player[id].menu_requestalt)
self.player[id].menu_requestalt=nil
end
end
--- Create "F10/Pseudo ATC" menu items "Airport Data".
--- Create "F10/Pseudo ATC/Local Airports" menu item.
-- @param #PSEUDOATC self
-- @param #number id Group id of player unit for which menues are created.
function PSEUDOATC:MenuAirports(id)
self:F(id)
-- Table for menu entries.
self.player[id].menu_airports=missionCommands.addSubMenuForGroup(id, "Airports", self.player[id].menu_main)
self.player[id].menu_airports=missionCommands.addSubMenuForGroup(id, "Local Airports", self.player[id].menu_main)
local i=0
for _,airport in pairs(self.player[id].airports) do
i=i+1
if i>self.maxairport then
break -- Max X<10 airports due to 10 menu items restriction.
if i > 10 then
break -- Max 10 airports due to 10 menu items restriction.
end
local name=airport.name
@ -444,14 +581,9 @@ function PSEUDOATC:MenuAirports(id)
--F10menu_ATC_airports[ID][name] = missionCommands.addSubMenuForGroup(ID, name, F10menu_ATC)
local submenu=missionCommands.addSubMenuForGroup(id, name, self.player[id].menu_airports)
--self.player[id].menu_airports[name]=submenu
-- Create menu reporting commands
missionCommands.addCommandForGroup(id, "Weather Report", submenu, self.ReportWeather, self, id, pos, name)
--missionCommands.addCommandForGroup(id, "Request QFE", submenu, self.ReportPressure, self, id, "QFE", pos, name)
--missionCommands.addCommandForGroup(id, "Request QNH", submenu, self.ReportPressure, self, id, "QNH", pos, name)
--missionCommands.addCommandForGroup(id, "Request Wind", submenu, self.ReportWind, self, id, pos, name)
--missionCommands.addCommandForGroup(id, "Request Temperature", submenu, self.ReportTemperature, self, id, pos, name)
missionCommands.addCommandForGroup(id, "Request BR", submenu, self.ReportBR, self, id, pos, name)
-- Debug message.
@ -459,32 +591,28 @@ function PSEUDOATC:MenuAirports(id)
end
end
--- Create F10/Pseudo ATC menu item "My Plane".
--- Create F10/Pseudo ATC/Waypoints menu items and misc items.
-- @param #PSEUDOATC self
-- @param #number id Group id of player unit for which menues are created.
function PSEUDOATC:MenuAircraft(id)
function PSEUDOATC:MenuWaypoints(id)
self:F(id)
-- Table for menu entries.
--self.player[id].menu_aircraft={}
-- Player unit and callsign.
local unit=self.player[id].unit --Wrapper.Unit#UNIT
local callsign=self.player[id].callsign
local name=string.format("My Aircraft (%s)", callsign)
-- Debug info.
self:T(PSEUDOATC.id..string.format("Creating menu item %s for ID %d", name,id))
-- F10/PseudoATC/My Aircraft (callsign)
--self.player[id].menu_aircraft.main = missionCommands.addSubMenuForGroup(id, name, self.player[id].menu_main)
self:T(PSEUDOATC.id..string.format("Creating waypoint menu for %s (ID %d).", name, id))
if #self.player[id].waypoints>0 then
-- F10/PseudoATC/Waypoints
-- F10/PseudoATC/Waypoints
self.player[id].menu_waypoints=missionCommands.addSubMenuForGroup(id, "Waypoints", self.player[id].menu_main)
local j=0
for i, wp in pairs(self.player[id].waypoints) do
-- Increase counter
j=j+1
@ -501,23 +629,18 @@ function PSEUDOATC:MenuAircraft(id)
-- Menu commands for each waypoint "F10/PseudoATC/My Aircraft (callsign)/Waypoints/Waypoint X/<Commands>"
missionCommands.addCommandForGroup(id, "Weather Report", submenu, self.ReportWeather, self, id, pos, name)
--missionCommands.addCommandForGroup(id, "Request QFE", submenu, self.ReportPressure, self, id, "QFE", pos, pname)
--missionCommands.addCommandForGroup(id, "Request QNH", submenu, self.ReportPressure, self, id, "QNH", pos, pname)
--missionCommands.addCommandForGroup(id, "Request Wind", submenu, self.ReportWind, self, id, pos, pname)
--missionCommands.addCommandForGroup(id, "Request Temperature", submenu, self.ReportTemperature, self, id, pos, pname)
missionCommands.addCommandForGroup(id, "Request BR", submenu, self.ReportBR, self, id, pos, name)
end
end
missionCommands.addCommandForGroup(id, "Request current altitude AGL", self.player[id].menu_main, self.ReportHeight, self, id)
missionCommands.addCommandForGroup(id, "Report altitude until touchdown", self.player[id].menu_main, self.AltidudeStartTimer, self, id)
missionCommands.addCommandForGroup(id, "Quit reporting altitude", self.player[id].menu_main, self.AltidudeStopTimer, self, id)
self.player[id].menu_reportalt = missionCommands.addCommandForGroup(id, "Report alt until touchdown", self.player[id].menu_main, self.AltidudeTimerToggle, self, id)
self.player[id].menu_requestalt = missionCommands.addCommandForGroup(id, "Request altitude AGL", self.player[id].menu_main, self.ReportHeight, self, id)
end
-----------------------------------------------------------------------------------------------------------------------------------------
-- Reporting Functions
--- Weather Report. Report pressure QFE/QNH, temperature, wind at certain location
--- Weather Report. Report pressure QFE/QNH, temperature, wind at certain location.
-- @param #PSEUDOATC self
-- @param #number id Group id to which the report is delivered.
-- @param Core.Point#COORDINATE position Coordinates at which the pressure is measured.
@ -533,7 +656,7 @@ function PSEUDOATC:ReportWeather(id, position, location)
-- Get pressure in hPa.
local Pqnh=position:GetPressure(0) -- Get pressure at sea level.
local Pqfe=position:GetPressure() -- Get pressure at (land) height of position.
-- Unit conversion.
local _Pqnh=string.format("%.2f inHg", Pqnh * PSEUDOATC.unit.hPa2inHg)
local _Pqfe=string.format("%.2f inHg", Pqfe * PSEUDOATC.unit.hPa2inHg)
@ -675,7 +798,7 @@ function PSEUDOATC:ReportWind(id, position, location)
-- Formatted wind direction.
local Ds = string.format('%03d°', Dir)
-- Settings.
-- Player settings.
local settings=_DATABASE:GetPlayerSettings(self.player[id].playername) or _SETTINGS --Core.Settings#SETTINGS
-- Velocity in player units.
@ -732,7 +855,7 @@ end
-- @param #number id Group id to the report is delivered.
-- @param #number dt (Optional) Duration the message is displayed.
-- @param #boolean _clear (Optional) Clear previouse messages.
-- @return #number Altuitude above ground.
-- @return #number Altitude above ground.
function PSEUDOATC:ReportHeight(id, dt, _clear)
self:F({id=id, dt=dt})
@ -743,43 +866,67 @@ function PSEUDOATC:ReportHeight(id, dt, _clear)
-- Return height [m] above ground level.
local function get_AGL(p)
local vec2={x=p.x,y=p.z}
local ground=land.getHeight(vec2)
local agl=p.y-ground
local agl=0
if p then
local vec2={x=p.x,y=p.z}
local ground=land.getHeight(vec2)
local agl=p.y-ground
end
return agl
end
-- Get height AGL.
local unit=self.player[id].unit --Wrapper.Unit#UNIT
local position=unit:GetCoordinate()
local height=get_AGL(position)
local callsign=unit:GetCallsign()
-- Settings.
local settings=_DATABASE:GetPlayerSettings(self.player[id].playername) or _SETTINGS --Core.Settings#SETTINGS
if unit and unit:IsAlive() then
local Hs=string.format("%d m", height)
if settings:IsMetric() then
Hs=string.format("%d ft", height*PSEUDOATC.unit.meter2feet)
local position=unit:GetCoordinate()
local height=get_AGL(position)
local callsign=unit:GetCallsign()
-- Settings.
local settings=_DATABASE:GetPlayerSettings(self.player[id].playername) or _SETTINGS --Core.Settings#SETTINGS
local Hs=string.format("%d m", height)
if settings:IsMetric() then
Hs=string.format("%d ft", height*PSEUDOATC.unit.meter2feet)
end
-- Message text.
local _text=string.format("%s: Your altitude is %s AGL.", callsign, Hs)
-- Send message to player group.
--MESSAGE:New(text, dt):ToGroup(self.player[id].group)
self:_DisplayMessageToGroup(self.player[id].unit,_text, dt,_clear)
-- Return height
return height
end
-- Message text.
local _text=string.format("%s: Your altitude is %s AGL.", callsign, Hs)
-- Send message to player group.
--MESSAGE:New(text, dt):ToGroup(self.player[id].group)
self:_DisplayMessageToGroup(self.player[id].unit,_text, dt,_clear)
-- Return height
return height
return 0
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Toggle report altitude reporting on/of.
-- @param #PSEUDOATC self.
-- @param #number id Group id of player unit.
function PSEUDOATC:AltidudeTimerToggle(id)
self:F(id)
if self.player[id].altimerid then
-- If the timer is on, we turn it off.
self:AltitudeTimerStop(id)
else
-- If the timer is off, we turn it on.
self:AltitudeTimeStart(id)
end
end
--- Start altitude reporting scheduler.
-- @param #PSEUDOATC self.
-- @param #number id Group id of player unit.
function PSEUDOATC:AltidudeStartTimer(id)
function PSEUDOATC:AltitudeTimeStart(id)
self:F(id)
-- Debug info.
@ -787,13 +934,13 @@ function PSEUDOATC:AltidudeStartTimer(id)
-- Start timer.
--self.player[id].altimer=timer.scheduleFunction(self.ReportAltTouchdown, self, id, Tnow+2)
self.player[id].altimer, self.player[id].altimerid=SCHEDULER:New(nil, self.ReportHeight, {self, id, 0.1, true}, 1, 5)
self.player[id].altimer, self.player[id].altimerid=SCHEDULER:New(nil, self.ReportHeight, {self, id, 0.1, true}, 1, 3)
end
--- Stop/destroy DCS scheduler function for reporting altitude.
-- @param #PSEUDOATC self.
-- @param #number id Group id of player unit.
function PSEUDOATC:AltidudeStopTimer(id)
function PSEUDOATC:AltitudeTimerStop(id)
-- Debug info.
self:T(PSEUDOATC.id..string.format("Stopping altitude report timer for player ID %d.", id))
@ -863,14 +1010,24 @@ function PSEUDOATC:_GetPlayerUnitAndName(_unitName)
self:F(_unitName)
if _unitName ~= nil then
-- Get DCS unit from its name.
local DCSunit=Unit.getByName(_unitName)
local playername=DCSunit:getPlayerName()
if DCSunit then
if DCSunit and playername then
-- Get the player name to make sure a player entered.
local playername=DCSunit:getPlayerName()
local unit=UNIT:Find(DCSunit)
return unit, playername
end
-- Debug output.
self:T2({DCSunit=DCSunit, unit=unit, playername=playername})
if unit and playername then
-- Return MOOSE unit and player name
return unit, playername
end
end
end
return nil,nil

View File

@ -1280,7 +1280,7 @@ end
--- Check if aircraft have accidentally been spawned on the runway. If so they will be removed immediatly.
-- @param #RAT self
-- @param #booblen switch If true, check is performed. If false, this check is omitted.
-- @param #boolean switch If true, check is performed. If false, this check is omitted.
function RAT:CheckOnRunway(switch)
self:F2(switch)
if switch==nil then
@ -1291,7 +1291,7 @@ end
--- Check if aircraft have accidentally been spawned on top of each other. If yes, they will be removed immediately.
-- @param #RAT self
-- @param #booblen switch If true, check is performed. If false, this check is omitted.
-- @param #boolean switch If true, check is performed. If false, this check is omitted.
function RAT:CheckOnTop(switch)
self:F2(switch)
if switch==nil then
@ -1302,7 +1302,7 @@ end
--- Put parking spot coordinates in a data base for future use of aircraft.
-- @param #RAT self
-- @param #booblen switch If true, parking spots are memorized. This is also the default setting.
-- @param #boolean switch If true, parking spots are memorized. This is also the default setting.
function RAT:ParkingSpotDB(switch)
self:F2(switch)
if switch==nil then

View File

@ -28,7 +28,7 @@
--
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
--
-- ### Contributions: **Sven van de Velde ([FlightControl](https://forums.eagle.ru/member.php?u=89536))**
-- ### Contributions: **[FlightControl](https://forums.eagle.ru/member.php?u=89536)**
--
-- ====
-- @module Suppression
@ -45,7 +45,7 @@
-- @field #string Type Type of the group.
-- @field #number SpeedMax Maximum speed of group in km/h.
-- @field #boolean IsInfantry True if group has attribute Infantry.
-- @field Core.Controllable#CONTROLLABLE Controllable Controllable of the FSM. Must be a ground group.
-- @field Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the FSM. Must be a ground group.
-- @field #number Tsuppress_ave Average time in seconds a group gets suppressed. Actual value is sampled randomly from a Gaussian distribution.
-- @field #number Tsuppress_min Minimum time in seconds the group gets suppressed.
-- @field #number Tsuppress_max Maximum time in seconds the group gets suppressed.
@ -283,11 +283,16 @@ SUPPRESSION.MenuF10=nil
-- @field #string id
SUPPRESSION.id="SFX | "
--- PSEUDOATC version.
-- @field #number version
SUPPRESSION.version="0.7.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--TODO: Figure out who was shooting and move away from him.
--TODO: Move behind a scenery building if there is one nearby.
--TODO: Retreat to a given zone or point.
--TODO list
--DONE: Figure out who was shooting and move away from him.
--DONE: Move behind a scenery building if there is one nearby.
--DONE: Retreat to a given zone or point.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -304,7 +309,7 @@ function SUPPRESSION:New(group)
-- Check that group is present.
if group then
self:T(SUPPRESSION.id.."Suppressive fire for group "..group:GetName())
self:T(SUPPRESSION.id..string.format("SUPPRESSION version %s. Activating suppressive fire for group %s", SUPPRESSION.version, group:GetName()))
else
self:E(SUPPRESSION.id.."Suppressive fire: Requested group does not exist! (Has to be a MOOSE group.)")
return nil
@ -312,7 +317,7 @@ function SUPPRESSION:New(group)
-- Check that we actually have a GROUND group.
if group:IsGround()==false then
self:E(SUPPRESSION.id.."SUPPRESSION fire group "..group:GetName().." has to be a GROUND group!")
self:E(SUPPRESSION.id..string.format("SUPPRESSION fire group %s has to be a GROUND group!", group:GetName()))
return nil
end
@ -326,7 +331,6 @@ function SUPPRESSION:New(group)
-- Get max speed the group can do and convert to km/h.
self.SpeedMax=self.DCSdesc.speedMaxOffRoad*3.6
--self.SpeedMaxOffRoad=DCSdesc.speedMaxOffRoad
-- Set speed to maximum.
self.Speed=self.SpeedMax
@ -503,6 +507,7 @@ end
-- @param #number Tmin (Optional) Minimum time [seconds] a group will be suppressed. Default is 5 seconds.
-- @param #number Tmax (Optional) Maximum time a group will be suppressed. Default is 25 seconds.
function SUPPRESSION:SetSuppressionTime(Tave, Tmin, Tmax)
self:F({Tave=Tave, Tmin=Tmin, Tmax=Tmax})
-- Minimum suppression time is input or default but at least 1 second.
self.Tsuppress_min=Tmin or self.Tsuppress_min
@ -526,24 +531,28 @@ end
-- @param #SUPPRESSION self
-- @param Core.Zone#ZONE zone MOOSE zone object.
function SUPPRESSION:SetRetreatZone(zone)
self:F({zone=zone})
self.RetreatZone=zone
end
--- Turn Debug mode on. Enables messages and more output to DCS log file.
-- @param #SUPPRESSION self
function SUPPRESSION:DebugOn()
self:F()
self.Debug=true
end
--- Flare units when they are hit, die or recover from suppression.
-- @param #SUPPRESSION self
function SUPPRESSION:FlareOn()
self:F()
self.flare=true
end
--- Smoke positions where units fall back to, hide or retreat.
-- @param #SUPPRESSION self
function SUPPRESSION:SmokeOn()
self:F()
self.smoke=true
end
@ -551,6 +560,7 @@ end
-- @param #SUPPRESSION self
-- @param #string formation Formation of the group. Default "Vee".
function SUPPRESSION:SetFormation(formation)
self:F(formation)
self.Formation=formation or "Vee"
end
@ -558,6 +568,7 @@ end
-- @param #SUPPRESSION self
-- @param #number speed Speed in km/h of group. Default max speed the group can do.
function SUPPRESSION:SetSpeed(speed)
self:F(speed)
self.Speed=speed or self.SpeedMax
self.Speed=math.min(self.Speed, self.SpeedMax)
end
@ -566,6 +577,7 @@ end
-- @param #SUPPRESSION self
-- @param #boolean switch Enable=true or disable=false fall back of group.
function SUPPRESSION:Fallback(switch)
self:F(switch)
if switch==nil then
switch=true
end
@ -576,6 +588,7 @@ end
-- @param #SUPPRESSION self
-- @param #number distance Distance in meters.
function SUPPRESSION:SetFallbackDistance(distance)
self:F(distance)
self.FallbackDist=distance
end
@ -583,6 +596,7 @@ end
-- @param #SUPPRESSION self
-- @param #number time Time in seconds.
function SUPPRESSION:SetFallbackWait(time)
self:F(time)
self.FallbackWait=time
end
@ -590,6 +604,7 @@ end
-- @param #SUPPRESSION self
-- @param #boolean switch Enable=true or disable=false fall back of group.
function SUPPRESSION:Takecover(switch)
self:F(switch)
if switch==nil then
switch=true
end
@ -600,6 +615,7 @@ end
-- @param #SUPPRESSION self
-- @param #number time Time in seconds.
function SUPPRESSION:SetTakecoverWait(time)
self:F(time)
self.TakecoverWait=time
end
@ -607,6 +623,7 @@ end
-- @param #SUPPRESSION self
-- @param #number range Search range in meters.
function SUPPRESSION:SetTakecoverRange(range)
self:F(range)
self.TakecoverRange=range
end
@ -621,6 +638,7 @@ end
-- @param #SUPPRESSION self
-- @param #number probability Probability in percent.
function SUPPRESSION:SetMinimumFleeProbability(probability)
self:F(probability)
self.PminFlee=probability or 10
end
@ -628,6 +646,7 @@ end
-- @param #SUPPRESSION self
-- @param #number probability Probability in percent.
function SUPPRESSION:SetMaximumFleeProbability(probability)
self:F(probability)
self.PmaxFlee=probability or 90
end
@ -637,6 +656,7 @@ end
-- @param #SUPPRESSION self
-- @param #number damage Damage in percent. If group gets damaged above this value, the group will retreat. Default 50 %.
function SUPPRESSION:SetRetreatDamage(damage)
self:F(damage)
self.RetreatDamage=damage or 50
end
@ -644,6 +664,7 @@ end
-- @param #SUPPRESSION self
-- @param #number time Time in seconds. Default 7200 seconds = 2 hours.
function SUPPRESSION:SetRetreatWait(time)
self:F(time)
self.RetreatWait=time or 7200
end
@ -651,6 +672,7 @@ end
-- @param #SUPPRESSION self
-- @param #string alarmstate Alarm state. Possible "Auto", "Green", "Red". Default is "Auto".
function SUPPRESSION:SetDefaultAlarmState(alarmstate)
self:F(alarmstate)
if alarmstate:lower()=="auto" then
self.DefaultAlarmState=SUPPRESSION.AlarmState.Auto
elseif alarmstate:lower()=="green" then
@ -666,6 +688,7 @@ end
-- @param #SUPPRESSION self
-- @param #string roe ROE after suppression. Possible "Free", "Hold" or "Return". Default "Free".
function SUPPRESSION:SetDefaultROE(roe)
self:F(roe)
if roe:lower()=="free" then
self.DefaultROE=SUPPRESSION.ROE.Free
elseif roe:lower()=="hold" then
@ -681,6 +704,7 @@ end
-- @param #SUPPRESSION self
-- @param #boolean switch Enable=true or disable=false menu group. Default is true.
function SUPPRESSION:MenuOn(switch)
self:F(switch)
if switch==nil then
switch=true
end
@ -1298,7 +1322,7 @@ function SUPPRESSION:onEvent(Event)
self:_OnEventHit(EventData)
end
-- Event HIT
-- Event DEAD
if Event.id == world.event.S_EVENT_DEAD then
self:_OnEventDead(EventData)
end
@ -1441,12 +1465,12 @@ end
--- Make group run/drive to a certain point. We put in several intermediate waypoints because sometimes the group stops before it arrived at the desired point.
--@param #SUPPRESSION self
--@param Core.Point#COORDINATE fin Coordinate where we want to go.
--@param #number speed Speed of group. Default is 999.
--@param #number speed Speed of group. Default is 20.
--@param #string formation Formation of group. Default is "Vee".
--@param #number wait Time the group will wait/hold at final waypoint. Default is 30 seconds.
function SUPPRESSION:_Run(fin, speed, formation, wait)
speed=speed or 999
speed=speed or 20
formation=formation or "Vee"
wait=wait or 30