mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Ops
This commit is contained in:
parent
fb6ebc42a5
commit
cf65c2af15
@ -21,7 +21,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- # The ARMYGROUP Concept
|
-- # The ARMYGROUP Concept
|
||||||
--
|
--
|
||||||
@ -33,12 +33,12 @@ ARMYGROUP = {
|
|||||||
formationPerma = nil,
|
formationPerma = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Navy group element.
|
--- Army group element.
|
||||||
-- @type ARMYGROUP.Element
|
-- @type ARMYGROUP.Element
|
||||||
-- @field #string name Name of the element, i.e. the unit.
|
-- @field #string name Name of the element, i.e. the unit.
|
||||||
-- @field #string typename Type name.
|
-- @field #string typename Type name.
|
||||||
|
|
||||||
--- NavyGroup version.
|
--- Army Group version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
ARMYGROUP.version="0.0.1"
|
ARMYGROUP.version="0.0.1"
|
||||||
|
|
||||||
@ -151,8 +151,7 @@ end
|
|||||||
|
|
||||||
--- Get coordinate of the closest road.
|
--- Get coordinate of the closest road.
|
||||||
-- @param #ARMYGROUP self
|
-- @param #ARMYGROUP self
|
||||||
-- @param #boolean switch If true or nil, patrol until the end of time. If false, go along the waypoints once and stop.
|
-- @return Core.Point#COORDINATE Coordinate of a road closest to the group.
|
||||||
-- @return #ARMYGROUP self
|
|
||||||
function ARMYGROUP:GetClosestRoad()
|
function ARMYGROUP:GetClosestRoad()
|
||||||
return self:GetCoordinate():GetClosestPointToRoad()
|
return self:GetCoordinate():GetClosestPointToRoad()
|
||||||
end
|
end
|
||||||
@ -174,6 +173,24 @@ function ARMYGROUP:AddTaskFireAtPoint(Coordinate, Radius, Nshots, WeaponType, Cl
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a *waypoint* task.
|
||||||
|
-- @param #ARMYGROUP self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the target.
|
||||||
|
-- @param Ops.OpsGroup#OPSGROUP.Waypoint Waypoint Where the task is executed. Default is next waypoint.
|
||||||
|
-- @param #number Radius Radius in meters. Default 100 m.
|
||||||
|
-- @param #number Nshots Number of shots to fire. Default 3.
|
||||||
|
-- @param #number WeaponType Type of weapon. Default auto.
|
||||||
|
-- @param #number Prio Priority of the task.
|
||||||
|
function ARMYGROUP:AddTaskWaypointFireAtPoint(Coordinate, Waypoint, Radius, Nshots, WeaponType, Prio)
|
||||||
|
|
||||||
|
Waypoint=Waypoint or self:GetWaypointNext()
|
||||||
|
|
||||||
|
local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, Coordinate:GetVec2(), Radius, Nshots, WeaponType)
|
||||||
|
|
||||||
|
self:AddTaskWaypoint(DCStask, Waypoint, nil, Prio)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Add a *scheduled* task.
|
--- Add a *scheduled* task.
|
||||||
-- @param #ARMYGROUP self
|
-- @param #ARMYGROUP self
|
||||||
-- @param Wrapper.Group#GROUP TargetGroup Target group.
|
-- @param Wrapper.Group#GROUP TargetGroup Target group.
|
||||||
@ -189,6 +206,8 @@ function ARMYGROUP:AddTaskAttackGroup(TargetGroup, WeaponExpend, WeaponType, Clo
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Status
|
-- Status
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -251,60 +270,11 @@ function ARMYGROUP:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Tasks
|
-- Tasks & Missions
|
||||||
---
|
---
|
||||||
|
|
||||||
-- Task queue.
|
self:_PrintTaskAndMissionStatus()
|
||||||
if #self.taskqueue>0 and self.verbose>1 then
|
|
||||||
local text=string.format("Tasks #%d", #self.taskqueue)
|
|
||||||
for i,_task in pairs(self.taskqueue) do
|
|
||||||
local task=_task --Ops.OpsGroup#OPSGROUP.Task
|
|
||||||
local name=task.description
|
|
||||||
local taskid=task.dcstask.id or "unknown"
|
|
||||||
local status=task.status
|
|
||||||
local clock=UTILS.SecondsToClock(task.time, true)
|
|
||||||
local eta=task.time-timer.getAbsTime()
|
|
||||||
local started=task.timestamp and UTILS.SecondsToClock(task.timestamp, true) or "N/A"
|
|
||||||
local duration=-1
|
|
||||||
if task.duration then
|
|
||||||
duration=task.duration
|
|
||||||
if task.timestamp then
|
|
||||||
-- Time the task is running.
|
|
||||||
duration=task.duration-(timer.getAbsTime()-task.timestamp)
|
|
||||||
else
|
|
||||||
-- Time the task is supposed to run.
|
|
||||||
duration=task.duration
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Output text for element.
|
|
||||||
if task.type==OPSGROUP.TaskType.SCHEDULED then
|
|
||||||
text=text..string.format("\n[%d] %s (%s): status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
|
|
||||||
elseif task.type==OPSGROUP.TaskType.WAYPOINT then
|
|
||||||
text=text..string.format("\n[%d] %s (%s): status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
|
||||||
|
|
||||||
---
|
|
||||||
-- Missions
|
|
||||||
---
|
|
||||||
|
|
||||||
-- Current mission name.
|
|
||||||
if self.verbose>0 then
|
|
||||||
local Mission=self:GetMissionByID(self.currentmission)
|
|
||||||
|
|
||||||
-- Current status.
|
|
||||||
local text=string.format("Missions %d, Current: %s", self:CountRemainingMissison(), Mission and Mission.name or "none")
|
|
||||||
for i,_mission in pairs(self.missionqueue) do
|
|
||||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
|
||||||
local Cstart= UTILS.SecondsToClock(mission.Tstart, true)
|
|
||||||
local Cstop = mission.Tstop and UTILS.SecondsToClock(mission.Tstop, true) or "INF"
|
|
||||||
text=text..string.format("\n[%d] %s (%s) status=%s (%s), Time=%s-%s, prio=%d wp=%s targets=%d",
|
|
||||||
i, tostring(mission.name), mission.type, mission:GetGroupStatus(self), tostring(mission.status), Cstart, Cstop, mission.prio, tostring(mission:GetGroupWaypointIndex(self)), mission:CountMissionTargets())
|
|
||||||
end
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
|
||||||
|
|
||||||
self:__Status(-30)
|
self:__Status(-30)
|
||||||
end
|
end
|
||||||
@ -350,11 +320,29 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
|
|||||||
|
|
||||||
if self.ai then
|
if self.ai then
|
||||||
|
|
||||||
-- Set default ROE option.
|
-- Set default ROE.
|
||||||
self:SwitchROE(self.option.ROE)
|
if self.option.ROE then
|
||||||
|
self:SwitchROE(self.option.ROE)
|
||||||
|
else
|
||||||
|
self:SwitchROE(ENUMS.ROE.ReturnFire)
|
||||||
|
end
|
||||||
|
|
||||||
-- Set default Alarm State option.
|
-- Set default Alarm State.
|
||||||
self:SwitchAlarmstate(self.option.Alarm)
|
if self.option.Alarm then
|
||||||
|
self:SwitchAlarmstate(self.option.Alarm)
|
||||||
|
else
|
||||||
|
self:SwitchAlarmstate(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Turn TACAN beacon on.
|
||||||
|
if self.tacan.On then
|
||||||
|
self:_SwitchTACAN(self.tacan)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Turn on the radio.
|
||||||
|
if self.radio.On then
|
||||||
|
self:SwitchRadio(self.radio.Freq, self.radio.Modu)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -384,9 +372,12 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Formation)
|
|||||||
|
|
||||||
-- Waypoints.
|
-- Waypoints.
|
||||||
local waypoints={}
|
local waypoints={}
|
||||||
|
|
||||||
|
-- Total number of waypoints
|
||||||
|
local N=#self.waypoints
|
||||||
|
|
||||||
-- Add remaining waypoints to route.
|
-- Add remaining waypoints to route.
|
||||||
for i=n, #self.waypoints do
|
for i=n, N do
|
||||||
|
|
||||||
-- Copy waypoint.
|
-- Copy waypoint.
|
||||||
local wp=UTILS.DeepCopy(self.waypoints[i]) --Ops.OpsGroup#OPSGROUP.Waypoint
|
local wp=UTILS.DeepCopy(self.waypoints[i]) --Ops.OpsGroup#OPSGROUP.Waypoint
|
||||||
@ -404,7 +395,9 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Formation)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.formationPerma then
|
if self.formationPerma then
|
||||||
wp.action=self.formationPerma
|
--if self.formationPerma==ENUMS.Formation.Vehicle.OnRoad then
|
||||||
|
wp.action=self.formationPerma
|
||||||
|
--end
|
||||||
elseif Formation then
|
elseif Formation then
|
||||||
wp.action=Formation
|
wp.action=Formation
|
||||||
end
|
end
|
||||||
@ -428,17 +421,27 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Formation)
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if formation==ENUMS.Formation.Vehicle.OnRoad then
|
|
||||||
|
|
||||||
local wpnext=self:GetWaypointNext()
|
if wp.roaddist>100 and wp.action==ENUMS.Formation.Vehicle.OnRoad then
|
||||||
|
env.info("FF Adding ON road waypoint")
|
||||||
if wpnext.action~=ENUMS.Formation.Vehicle.OnRoad then
|
--wp.roadcoord:MarkToAll("Added Road waypoint")
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- Waypoint is actually off road!
|
||||||
|
wp.action=ENUMS.Formation.Vehicle.OffRoad
|
||||||
|
|
||||||
|
-- Add "On Road" waypoint in between.
|
||||||
|
local wproad=wp.roadcoord:WaypointGround(wp.speed, ENUMS.Formation.Vehicle.OnRoad)
|
||||||
|
table.insert(waypoints, wproad)
|
||||||
|
end
|
||||||
|
|
||||||
|
--if wp.formation==ENUMS.Formation.Vehicle.OnRoad and wp.action~=ENUMS.Formation.Vehicle.OnRoad then --and not self.formationPerma~=ENUMS.Formation.Vehicle.OnRoad then
|
||||||
|
--[[
|
||||||
|
if wp.action==ENUMS.Formation.Vehicle.OnRoad and wp.roaddist>100 then
|
||||||
|
env.info("FF Adding ON road waypoint")
|
||||||
|
local wproad=wp.roadcoord:WaypointGround(wp.speed, ENUMS.Formation.Vehicle.OnRoad)
|
||||||
|
table.insert(waypoints, wproad)
|
||||||
end
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:I(string.format("WP %d %s: Speed=%d m/s, alt=%d m, Action=%s", i, wp.type, wp.speed, wp.alt, wp.action))
|
self:I(string.format("WP %d %s: Speed=%d m/s, alt=%d m, Action=%s", i, wp.type, wp.speed, wp.alt, wp.action))
|
||||||
@ -716,10 +719,24 @@ function ARMYGROUP:AddWaypoint(Coordinate, Speed, AfterWaypointWithID, Formation
|
|||||||
|
|
||||||
-- Get closest point to road.
|
-- Get closest point to road.
|
||||||
waypoint.roadcoord=Coordinate:GetClosestPointToRoad(false)
|
waypoint.roadcoord=Coordinate:GetClosestPointToRoad(false)
|
||||||
waypoint.roadist=Coordinate:Get2DDistance(waypoint.roadcoord)
|
if waypoint.roadcoord then
|
||||||
|
waypoint.roaddist=Coordinate:Get2DDistance(waypoint.roadcoord)
|
||||||
|
else
|
||||||
|
waypoint.roaddist=1000*1000 --1000 km.
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
if waypoint.roaddist>100 and waypoint.action==ENUMS.Formation.Vehicle.OnRoad then
|
||||||
|
waypoint.formation=ENUMS.Formation.Vehicle.OnRoad
|
||||||
|
waypoint.action=ENUMS.Formation.Vehicle.OffRoad
|
||||||
|
else
|
||||||
|
waypoint.formation=waypoint.action
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Adding GROUND waypoint #%d, speed=%.1f knots. Last waypoint passed was #%s. Total waypoints #%d", wpnumber, Speed, self.currentwp, #self.waypoints))
|
self:I(self.lid..string.format("Adding waypoint UID=%d (index=%d), Speed=%.1f knots, Dist2Road=%d m, Action=%s", waypoint.uid, wpnumber, Speed, waypoint.roaddist, waypoint.action))
|
||||||
|
|
||||||
-- Update route.
|
-- Update route.
|
||||||
if Updateroute==nil or Updateroute==true then
|
if Updateroute==nil or Updateroute==true then
|
||||||
@ -771,7 +788,7 @@ function ARMYGROUP:_InitGroup()
|
|||||||
self.position=self:GetCoordinate()
|
self.position=self:GetCoordinate()
|
||||||
|
|
||||||
-- Radio parameters from template.
|
-- Radio parameters from template.
|
||||||
self.radioOn=false -- Radio is always OFF for ground.
|
self.radio.On=false -- Radio is always OFF for ground.
|
||||||
self.radio.Freq=133
|
self.radio.Freq=133
|
||||||
self.radio.Modu=radio.modulation.AM
|
self.radio.Modu=radio.modulation.AM
|
||||||
|
|
||||||
@ -810,13 +827,13 @@ function ARMYGROUP:_InitGroup()
|
|||||||
self.actype=unit:GetTypeName()
|
self.actype=unit:GetTypeName()
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
local text=string.format("Initialized Navy Group %s:\n", self.groupname)
|
local text=string.format("Initialized Army Group %s:\n", self.groupname)
|
||||||
text=text..string.format("AC type = %s\n", self.actype)
|
text=text..string.format("AC type = %s\n", self.actype)
|
||||||
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedmax))
|
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedmax))
|
||||||
text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise))
|
text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise))
|
||||||
text=text..string.format("Elements = %d\n", #self.elements)
|
text=text..string.format("Elements = %d\n", #self.elements)
|
||||||
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
||||||
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu), tostring(self.radioOn))
|
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu), tostring(self.radio.On))
|
||||||
text=text..string.format("Ammo = %d (G=%d/R=%d/M=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Missiles)
|
text=text..string.format("Ammo = %d (G=%d/R=%d/M=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Missiles)
|
||||||
text=text..string.format("FSM state = %s\n", self:GetState())
|
text=text..string.format("FSM state = %s\n", self:GetState())
|
||||||
text=text..string.format("Is alive = %s\n", tostring(self:IsAlive()))
|
text=text..string.format("Is alive = %s\n", tostring(self:IsAlive()))
|
||||||
|
|||||||
@ -824,60 +824,10 @@ function FLIGHTGROUP:onafterStatus(From, Event, To)
|
|||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Tasks
|
-- Tasks & Missions
|
||||||
---
|
---
|
||||||
|
|
||||||
-- Task queue.
|
self:_PrintTaskAndMissionStatus()
|
||||||
if self.verbose>1 and #self.taskqueue>0 then
|
|
||||||
local text=string.format("Tasks #%d", #self.taskqueue)
|
|
||||||
for i,_task in pairs(self.taskqueue) do
|
|
||||||
local task=_task --Ops.OpsGroup#OPSGROUP.Task
|
|
||||||
local name=task.description
|
|
||||||
local taskid=task.dcstask.id or "unknown"
|
|
||||||
local status=task.status
|
|
||||||
local clock=UTILS.SecondsToClock(task.time, true)
|
|
||||||
local eta=task.time-timer.getAbsTime()
|
|
||||||
local started=task.timestamp and UTILS.SecondsToClock(task.timestamp, true) or "N/A"
|
|
||||||
local duration=-1
|
|
||||||
if task.duration then
|
|
||||||
duration=task.duration
|
|
||||||
if task.timestamp then
|
|
||||||
-- Time the task is running.
|
|
||||||
duration=task.duration-(timer.getAbsTime()-task.timestamp)
|
|
||||||
else
|
|
||||||
-- Time the task is supposed to run.
|
|
||||||
duration=task.duration
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Output text for element.
|
|
||||||
if task.type==OPSGROUP.TaskType.SCHEDULED then
|
|
||||||
text=text..string.format("\n[%d] %s (%s): status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
|
|
||||||
elseif task.type==OPSGROUP.TaskType.WAYPOINT then
|
|
||||||
text=text..string.format("\n[%d] %s (%s): status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
|
||||||
|
|
||||||
---
|
|
||||||
-- Missions
|
|
||||||
---
|
|
||||||
|
|
||||||
-- Current mission name.
|
|
||||||
if self.verbose>0 then
|
|
||||||
local Mission=self:GetMissionByID(self.currentmission)
|
|
||||||
|
|
||||||
-- Current status.
|
|
||||||
local text=string.format("Missions %d, Current: %s", self:CountRemainingMissison(), Mission and Mission.name or "none")
|
|
||||||
for i,_mission in pairs(self.missionqueue) do
|
|
||||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
|
||||||
local Cstart= UTILS.SecondsToClock(mission.Tstart, true)
|
|
||||||
local Cstop = mission.Tstop and UTILS.SecondsToClock(mission.Tstop, true) or "INF"
|
|
||||||
text=text..string.format("\n[%d] %s (%s) status=%s (%s), Time=%s-%s, prio=%d wp=%s targets=%d",
|
|
||||||
i, tostring(mission.name), mission.type, mission:GetGroupStatus(self), tostring(mission.status), Cstart, Cstop, mission.prio, tostring(mission:GetGroupWaypointIndex(self)), mission:CountMissionTargets())
|
|
||||||
end
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Fuel State
|
-- Fuel State
|
||||||
@ -1415,35 +1365,35 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
|
|||||||
|
|
||||||
if self.ai then
|
if self.ai then
|
||||||
|
|
||||||
-- Set default ROE and ROT options.
|
-- Set default ROE.
|
||||||
self:SwitchROE(self.option.ROE)
|
if self.option.ROE then
|
||||||
self:SwitchROT(self.option.ROT)
|
self:SwitchROE(self.option.ROE)
|
||||||
|
else
|
||||||
-- Turn TACAN beacon on.
|
self:SwitchROE(ENUMS.ROE.ReturnFire)
|
||||||
if self.tacanDefault then
|
|
||||||
self:SwitchTACAN(self.tacanDefault.Channel, self.tacanDefault.Morse, self.tacanDefault.BeaconName, self.tacanDefault.Band)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Turn on the radio.
|
-- Set default ROT.
|
||||||
if self.radioDefault then
|
if self.option.ROT then
|
||||||
self:SwitchRadio(self.radioDefault.Freq, self.radioDefault.Modu)
|
self:SwitchROT(self.option.ROT)
|
||||||
else
|
else
|
||||||
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu)
|
self:SwitchROE(ENUMS.ROT.PassiveDefense)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Turn TACAN beacon on.
|
||||||
|
if self.tacan.On then
|
||||||
|
self:_SwitchTACAN(self.tacan)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set callsign.
|
-- Turn on the radio.
|
||||||
if self.callsignDefault then
|
if self.radio.On then
|
||||||
self:SwitchCallsign(self.callsignDefault.NumberSquad, self.callsignDefault.NumberGroup)
|
self:SwitchRadio(self.radio.Freq, self.radio.Modu)
|
||||||
else
|
|
||||||
self:SetDefaultCallsign(self.callsign.NumberSquad, self.callsign.NumberGroup)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: make this input.
|
-- TODO: make this input.
|
||||||
self.group:SetOption(AI.Option.Air.id.PROHIBIT_JETT, true)
|
self.group:SetOption(AI.Option.Air.id.PROHIBIT_JETT, true)
|
||||||
self.group:SetOption(AI.Option.Air.id.PROHIBIT_AB, true) -- Does not seem to work. AI still used the after burner.
|
self.group:SetOption(AI.Option.Air.id.PROHIBIT_AB, true) -- Does not seem to work. AI still used the after burner.
|
||||||
self.group:SetOption(AI.Option.Air.id.RTB_ON_BINGO, false)
|
self.group:SetOption(AI.Option.Air.id.RTB_ON_BINGO, false)
|
||||||
--self.group:SetOption(AI.Option.Air.id.RADAR_USING, AI.Option.Air.val.RADAR_USING.FOR_CONTINUOUS_SEARCH)
|
--self.group:SetOption(AI.Option.Air.id.RADAR_USING, AI.Option.Air.val.RADAR_USING.FOR_CONTINUOUS_SEARCH)
|
||||||
|
|
||||||
|
|
||||||
-- Update route.
|
-- Update route.
|
||||||
self:__UpdateRoute(-0.5)
|
self:__UpdateRoute(-0.5)
|
||||||
@ -2554,7 +2504,7 @@ function FLIGHTGROUP:_InitGroup()
|
|||||||
self.position=self:GetCoordinate()
|
self.position=self:GetCoordinate()
|
||||||
|
|
||||||
-- Radio parameters from template.
|
-- Radio parameters from template.
|
||||||
self.radioOn=self.template.communication
|
self.radio.On=self.template.communication
|
||||||
self.radio.Freq=self.template.frequency
|
self.radio.Freq=self.template.frequency
|
||||||
self.radio.Modu=self.template.modulation
|
self.radio.Modu=self.template.modulation
|
||||||
|
|
||||||
@ -2614,7 +2564,7 @@ function FLIGHTGROUP:_InitGroup()
|
|||||||
text=text..string.format("Helicopter = %s\n", tostring(self.group:IsHelicopter()))
|
text=text..string.format("Helicopter = %s\n", tostring(self.group:IsHelicopter()))
|
||||||
text=text..string.format("Elements = %d\n", #self.elements)
|
text=text..string.format("Elements = %d\n", #self.elements)
|
||||||
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
||||||
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu), tostring(self.radioOn))
|
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu), tostring(self.radio.On))
|
||||||
text=text..string.format("Ammo = %d (G=%d/R=%d/B=%d/M=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Bombs, self.ammo.Missiles)
|
text=text..string.format("Ammo = %d (G=%d/R=%d/B=%d/M=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Bombs, self.ammo.Missiles)
|
||||||
text=text..string.format("FSM state = %s\n", self:GetState())
|
text=text..string.format("FSM state = %s\n", self:GetState())
|
||||||
text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive()))
|
text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive()))
|
||||||
|
|||||||
@ -95,8 +95,8 @@ function NAVYGROUP:New(GroupName)
|
|||||||
self.lid=string.format("NAVYGROUP %s | ", self.groupname)
|
self.lid=string.format("NAVYGROUP %s | ", self.groupname)
|
||||||
|
|
||||||
-- Defaults
|
-- Defaults
|
||||||
self:SetDefaultROE()
|
--self:SetDefaultROE()
|
||||||
self:SetDefaultAlarmstate()
|
--self:SetDefaultAlarmstate()
|
||||||
self:SetDetection()
|
self:SetDetection()
|
||||||
self:SetPatrolAdInfinitum(true)
|
self:SetPatrolAdInfinitum(true)
|
||||||
|
|
||||||
@ -205,6 +205,27 @@ function NAVYGROUP:AddTaskFireAtPoint(Coordinate, Radius, Nshots, WeaponType, Cl
|
|||||||
return task
|
return task
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a *waypoint* task.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the target.
|
||||||
|
-- @param Ops.OpsGroup#OPSGROUP.Waypoint Waypoint Where the task is executed. Default is next waypoint.
|
||||||
|
-- @param #number Radius Radius in meters. Default 100 m.
|
||||||
|
-- @param #number Nshots Number of shots to fire. Default 3.
|
||||||
|
-- @param #number WeaponType Type of weapon. Default auto.
|
||||||
|
-- @param #number Prio Priority of the task.
|
||||||
|
-- @return Ops.OpsGroup#OPSGROUP.Task The task table.
|
||||||
|
function NAVYGROUP:AddTaskWaypointFireAtPoint(Coordinate, Waypoint, Radius, Nshots, WeaponType, Prio)
|
||||||
|
|
||||||
|
Waypoint=Waypoint or self:GetWaypointNext()
|
||||||
|
|
||||||
|
local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, Coordinate:GetVec2(), Radius, Nshots, WeaponType)
|
||||||
|
|
||||||
|
local task=self:AddTaskWaypoint(DCStask, Waypoint, nil, Prio)
|
||||||
|
|
||||||
|
return task
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Add a *scheduled* task.
|
--- Add a *scheduled* task.
|
||||||
-- @param #NAVYGROUP self
|
-- @param #NAVYGROUP self
|
||||||
-- @param Wrapper.Group#GROUP TargetGroup Target group.
|
-- @param Wrapper.Group#GROUP TargetGroup Target group.
|
||||||
@ -408,14 +429,16 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
|||||||
-- Check free path ahead.
|
-- Check free path ahead.
|
||||||
freepath=self:_CheckFreePath(freepath, 100)
|
freepath=self:_CheckFreePath(freepath, 100)
|
||||||
|
|
||||||
if freepath<5000 then
|
if freepath<5000 and not self.collisionwarning then
|
||||||
|
|
||||||
|
-- Issue a collision warning event.
|
||||||
self:CollisionWarning()
|
self:CollisionWarning()
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.ispathfinding then
|
if not self.ispathfinding then
|
||||||
|
|
||||||
if freepath<5000 then
|
if freepath<5000 then
|
||||||
--self.ispathfinding=self:_FindPathToNextWaypoint()
|
self.ispathfinding=self:_FindPathToNextWaypoint()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -464,60 +487,10 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Tasks
|
-- Tasks & Missions
|
||||||
---
|
---
|
||||||
|
|
||||||
-- Task queue.
|
self:_PrintTaskAndMissionStatus()
|
||||||
if self.verbose>-1 and #self.taskqueue>0 then
|
|
||||||
local text=string.format("Tasks #%d", #self.taskqueue)
|
|
||||||
for i,_task in pairs(self.taskqueue) do
|
|
||||||
local task=_task --Ops.OpsGroup#OPSGROUP.Task
|
|
||||||
local name=task.description
|
|
||||||
local taskid=task.dcstask.id or "unknown"
|
|
||||||
local status=task.status
|
|
||||||
local clock=UTILS.SecondsToClock(task.time, true)
|
|
||||||
local eta=task.time-timer.getAbsTime()
|
|
||||||
local started=task.timestamp and UTILS.SecondsToClock(task.timestamp, true) or "N/A"
|
|
||||||
local duration=-1
|
|
||||||
if task.duration then
|
|
||||||
duration=task.duration
|
|
||||||
if task.timestamp then
|
|
||||||
-- Time the task is running.
|
|
||||||
duration=task.duration-(timer.getAbsTime()-task.timestamp)
|
|
||||||
else
|
|
||||||
-- Time the task is supposed to run.
|
|
||||||
duration=task.duration
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Output text for element.
|
|
||||||
if task.type==OPSGROUP.TaskType.SCHEDULED then
|
|
||||||
text=text..string.format("\n[%d] %s (%s): status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
|
|
||||||
elseif task.type==OPSGROUP.TaskType.WAYPOINT then
|
|
||||||
text=text..string.format("\n[%d] %s (%s): status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
|
||||||
|
|
||||||
---
|
|
||||||
-- Missions
|
|
||||||
---
|
|
||||||
|
|
||||||
-- Current mission name.
|
|
||||||
if self.verbose>0 then
|
|
||||||
local Mission=self:GetMissionByID(self.currentmission)
|
|
||||||
|
|
||||||
-- Current status.
|
|
||||||
local text=string.format("Missions %d, Current: %s", self:CountRemainingMissison(), Mission and Mission.name or "none")
|
|
||||||
for i,_mission in pairs(self.missionqueue) do
|
|
||||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
|
||||||
local Cstart= UTILS.SecondsToClock(mission.Tstart, true)
|
|
||||||
local Cstop = mission.Tstop and UTILS.SecondsToClock(mission.Tstop, true) or "INF"
|
|
||||||
text=text..string.format("\n[%d] %s (%s) status=%s (%s), Time=%s-%s, prio=%d wp=%s targets=%d",
|
|
||||||
i, tostring(mission.name), mission.type, mission:GetGroupStatus(self), tostring(mission.status), Cstart, Cstop, mission.prio, tostring(mission:GetGroupWaypointIndex(self)), mission:CountMissionTargets())
|
|
||||||
end
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Next status update in 30 seconds.
|
-- Next status update in 30 seconds.
|
||||||
@ -564,28 +537,36 @@ function NAVYGROUP:onafterSpawned(From, Event, To)
|
|||||||
self:I(self.lid..string.format("Group spawned!"))
|
self:I(self.lid..string.format("Group spawned!"))
|
||||||
|
|
||||||
if self.ai then
|
if self.ai then
|
||||||
|
|
||||||
-- Set default ROE.
|
-- Set default ROE.
|
||||||
self:SwitchROE(self.option.ROE)
|
if self.option.ROE then
|
||||||
|
self:SwitchROE(self.option.ROE)
|
||||||
|
else
|
||||||
|
self:SwitchROE(ENUMS.ROE.ReturnFire)
|
||||||
|
end
|
||||||
|
|
||||||
-- Set default Alarm State.
|
-- Set default Alarm State.
|
||||||
self:SwitchAlarmstate(self.option.Alarm)
|
if self.option.Alarm then
|
||||||
|
self:SwitchAlarmstate(self.option.Alarm)
|
||||||
|
else
|
||||||
|
self:SwitchAlarmstate(0)
|
||||||
|
end
|
||||||
|
|
||||||
-- Turn TACAN beacon on.
|
-- Turn TACAN beacon on.
|
||||||
if self.tacanDefault then
|
if self.tacan.On then
|
||||||
self:SwitchTACAN(self.tacanDefault.Channel, self.tacanDefault.Morse, self.tacanDefault.BeaconName, self.tacanDefault.Band)
|
self:_SwitchTACAN(self.tacan)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Turn ICLS on.
|
-- Turn ICLS on.
|
||||||
if self.iclsDefault then
|
if self.icls.On then
|
||||||
self:SwitchICLS(self.iclsDefault.Channel, self.iclsDefault.Morse, self.iclsDefault.BeaconName)
|
self:_SwitchICLS(self.icls)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Turn on the radio.
|
-- Turn on the radio.
|
||||||
if self.radioDefault then
|
if self.radio.On then
|
||||||
self:SwitchRadio(self.radioDefault.Freq, self.radioDefault.Modu)
|
self:SwitchRadio(self.radio.Freq, self.radio.Modu)
|
||||||
else
|
else
|
||||||
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu)
|
self.radio.On=true -- Radio is always on for ships. If not set, it is default.
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -776,7 +757,7 @@ function NAVYGROUP:onafterTurnIntoWind(From, Event, To, IntoWind)
|
|||||||
|
|
||||||
IntoWind.waypoint=wptiw
|
IntoWind.waypoint=wptiw
|
||||||
|
|
||||||
if IntoWind.Uturn then
|
if IntoWind.Uturn and self.Debug then
|
||||||
IntoWind.Coordinate:MarkToAll("Return coord")
|
IntoWind.Coordinate:MarkToAll("Return coord")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -880,6 +861,34 @@ function NAVYGROUP:onafterSurface(From, Event, To, Speed)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- On after "TurningStarted" event.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
function NAVYGROUP:onafterTurningStarted(From, Event, To)
|
||||||
|
self.turning=true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "TurningStarted" event.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
function NAVYGROUP:onafterTurningStopped(From, Event, To)
|
||||||
|
self.turning=false
|
||||||
|
self.collisionwarning=false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "CollisionWarning" event.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
function NAVYGROUP:onafterCollisionWarning(From, Event, To)
|
||||||
|
self.collisionwarning=true
|
||||||
|
end
|
||||||
|
|
||||||
--- On after "Dead" event.
|
--- On after "Dead" event.
|
||||||
-- @param #NAVYGROUP self
|
-- @param #NAVYGROUP self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@ -1029,6 +1038,16 @@ end
|
|||||||
-- @param #boolean Updateroute If true or nil, call UpdateRoute. If false, no call.
|
-- @param #boolean Updateroute If true or nil, call UpdateRoute. If false, no call.
|
||||||
-- @return Ops.OpsGroup#OPSGROUP.Waypoint Waypoint table.
|
-- @return Ops.OpsGroup#OPSGROUP.Waypoint Waypoint table.
|
||||||
function NAVYGROUP:AddWaypoint(Coordinate, Speed, AfterWaypointWithID, Depth, Updateroute)
|
function NAVYGROUP:AddWaypoint(Coordinate, Speed, AfterWaypointWithID, Depth, Updateroute)
|
||||||
|
|
||||||
|
if not Coordinate:IsInstanceOf("COORDINATE") then
|
||||||
|
if Coordinate:IsInstanceOf("POSITIONABLE") then
|
||||||
|
self:I(self.lid.."WARNING: Coordinate is not a COORDINATE but a POSITIONABLE. Trying to get coordinate")
|
||||||
|
Coordinate=Coordinate:GetCoordinate()
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: Coordinate is neither a COORDINATE nor any POSITIONABLE!")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Set waypoint index.
|
-- Set waypoint index.
|
||||||
local wpnumber=self:GetWaypointIndexAfterID(AfterWaypointWithID)
|
local wpnumber=self:GetWaypointIndexAfterID(AfterWaypointWithID)
|
||||||
@ -1107,7 +1126,7 @@ function NAVYGROUP:_InitGroup()
|
|||||||
self.position=self:GetCoordinate()
|
self.position=self:GetCoordinate()
|
||||||
|
|
||||||
-- Radio parameters from template.
|
-- Radio parameters from template.
|
||||||
self.radioOn=true -- Radio is always on for ships.
|
self.radio.On=false -- Radio is always on for ships but we set it to false to check if it has been changed before spawn.
|
||||||
self.radio.Freq=tonumber(self.template.units[1].frequency)/1000000
|
self.radio.Freq=tonumber(self.template.units[1].frequency)/1000000
|
||||||
self.radio.Modu=tonumber(self.template.units[1].modulation)
|
self.radio.Modu=tonumber(self.template.units[1].modulation)
|
||||||
|
|
||||||
@ -1152,7 +1171,7 @@ function NAVYGROUP:_InitGroup()
|
|||||||
text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise))
|
text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise))
|
||||||
text=text..string.format("Elements = %d\n", #self.elements)
|
text=text..string.format("Elements = %d\n", #self.elements)
|
||||||
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
||||||
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu), tostring(self.radioOn))
|
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu), tostring(self.radio.On))
|
||||||
text=text..string.format("Ammo = %d (G=%d/R=%d/M=%d/T=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Missiles, self.ammo.Torpedos)
|
text=text..string.format("Ammo = %d (G=%d/R=%d/M=%d/T=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Missiles, self.ammo.Torpedos)
|
||||||
text=text..string.format("FSM state = %s\n", self:GetState())
|
text=text..string.format("FSM state = %s\n", self:GetState())
|
||||||
text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive()))
|
text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive()))
|
||||||
@ -1190,7 +1209,13 @@ function NAVYGROUP:_CheckFreePath(DistanceMax, dx)
|
|||||||
return distance
|
return distance
|
||||||
end
|
end
|
||||||
|
|
||||||
local offsetY=1
|
-- Offset above sea level.
|
||||||
|
local offsetY=0.1
|
||||||
|
|
||||||
|
-- Current bug on Caucasus. LoS returns false.
|
||||||
|
if UTILS.GetDCSMap()==DCSMAP.Caucasus then
|
||||||
|
offsetY=5.01
|
||||||
|
end
|
||||||
|
|
||||||
-- Current coordinate.
|
-- Current coordinate.
|
||||||
local coordinate=self:GetCoordinate():SetAltitude(offsetY, true)
|
local coordinate=self:GetCoordinate():SetAltitude(offsetY, true)
|
||||||
@ -1199,7 +1224,7 @@ function NAVYGROUP:_CheckFreePath(DistanceMax, dx)
|
|||||||
local heading=self:GetHeading()
|
local heading=self:GetHeading()
|
||||||
|
|
||||||
-- Check from 500 meters in front.
|
-- Check from 500 meters in front.
|
||||||
coordinate=coordinate:Translate(500, heading, true)
|
--coordinate=coordinate:Translate(500, heading, true)
|
||||||
|
|
||||||
local function LoS(dist)
|
local function LoS(dist)
|
||||||
local checkcoord=coordinate:Translate(dist, heading, true)
|
local checkcoord=coordinate:Translate(dist, heading, true)
|
||||||
@ -1534,7 +1559,7 @@ function NAVYGROUP:_FindPathToNextWaypoint()
|
|||||||
local delta=dist/10
|
local delta=dist/10
|
||||||
|
|
||||||
-- Create a grid of nodes. We only want nodes of surface type water.
|
-- Create a grid of nodes. We only want nodes of surface type water.
|
||||||
astar:CreateGrid({land.SurfaceType.WATER}, boxwidth, spacex, delta, delta*2, false)
|
astar:CreateGrid({land.SurfaceType.WATER}, boxwidth, spacex, delta, delta*2, self.Debug)
|
||||||
|
|
||||||
-- Valid neighbour nodes need to have line of sight.
|
-- Valid neighbour nodes need to have line of sight.
|
||||||
astar:SetValidNeighbourLoS(400)
|
astar:SetValidNeighbourLoS(400)
|
||||||
|
|||||||
@ -58,16 +58,13 @@
|
|||||||
--
|
--
|
||||||
-- @field #OPSGROUP.Radio radio Current radio settings.
|
-- @field #OPSGROUP.Radio radio Current radio settings.
|
||||||
-- @field #OPSGROUP.Radio radioDefault Default radio settings.
|
-- @field #OPSGROUP.Radio radioDefault Default radio settings.
|
||||||
-- @field #boolean radioOn If true, radio is currently turned on.
|
|
||||||
-- @field Core.RadioQueue#RADIOQUEUE radioQueue Radio queue.
|
-- @field Core.RadioQueue#RADIOQUEUE radioQueue Radio queue.
|
||||||
--
|
--
|
||||||
-- @field #OPSGROUP.Beacon tacan Current TACAN settings.
|
-- @field #OPSGROUP.Beacon tacan Current TACAN settings.
|
||||||
-- @field #OPSGROUP.Beacon tacanDefault Default TACAN settings.
|
-- @field #OPSGROUP.Beacon tacanDefault Default TACAN settings.
|
||||||
-- @field #boolean tacanOn If true, TACAN is currently active.
|
|
||||||
--
|
--
|
||||||
-- @field #OPSGROUP.Beacon icls Current ICLS settings.
|
-- @field #OPSGROUP.Beacon icls Current ICLS settings.
|
||||||
-- @field #OPSGROUP.Beacon iclsDefault Default ICLS settings.
|
-- @field #OPSGROUP.Beacon iclsDefault Default ICLS settings.
|
||||||
-- @field #boolean iclsOn If true, ICLS is currently active.
|
|
||||||
--
|
--
|
||||||
-- @field #OPSGROUP.Option option Current optional settings.
|
-- @field #OPSGROUP.Option option Current optional settings.
|
||||||
-- @field #OPSGROUP.Option optionDefault Default option settings.
|
-- @field #OPSGROUP.Option optionDefault Default option settings.
|
||||||
@ -202,11 +199,13 @@ OPSGROUP.TaskType={
|
|||||||
-- @field #string Band Band "X" or "Y" for TACAN beacon.
|
-- @field #string Band Band "X" or "Y" for TACAN beacon.
|
||||||
-- @field #string BeaconName Name of the unit acting as beacon.
|
-- @field #string BeaconName Name of the unit acting as beacon.
|
||||||
-- @field Wrapper.Unit#UNIT BeaconUnit Unit object acting as beacon.
|
-- @field Wrapper.Unit#UNIT BeaconUnit Unit object acting as beacon.
|
||||||
|
-- @field #boolean On If true, beacon is on, if false, beacon is turned off. If nil, has not been used yet.
|
||||||
|
|
||||||
--- Radio data.
|
--- Radio data.
|
||||||
-- @type OPSGROUP.Radio
|
-- @type OPSGROUP.Radio
|
||||||
-- @field #number Freq Frequency
|
-- @field #number Freq Frequency
|
||||||
-- @field #number Modu Modulation.
|
-- @field #number Modu Modulation.
|
||||||
|
-- @field #boolean On If true, radio is on, if false, radio is turned off. If nil, has not been used yet.
|
||||||
|
|
||||||
--- Callsign data.
|
--- Callsign data.
|
||||||
-- @type OPSGROUP.Callsign
|
-- @type OPSGROUP.Callsign
|
||||||
@ -255,7 +254,9 @@ OPSGROUP.TaskType={
|
|||||||
-- @field #boolean astar If true, this waypint was found by A* pathfinding algorithm.
|
-- @field #boolean astar If true, this waypint was found by A* pathfinding algorithm.
|
||||||
-- @field Core.Point#COORDINATE coordinate Waypoint coordinate.
|
-- @field Core.Point#COORDINATE coordinate Waypoint coordinate.
|
||||||
-- @field Core.Point#COORDINATE roadcoord Closest point to road.
|
-- @field Core.Point#COORDINATE roadcoord Closest point to road.
|
||||||
|
-- @field #number roaddist Distance to closest point on road.
|
||||||
-- @field Wrapper.Marker#MARKER marker Marker on the F10 map.
|
-- @field Wrapper.Marker#MARKER marker Marker on the F10 map.
|
||||||
|
-- @field #string formation Ground formation. Similar to action but on/off road.
|
||||||
|
|
||||||
--- NavyGroup version.
|
--- NavyGroup version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
@ -864,6 +865,14 @@ end
|
|||||||
|
|
||||||
--- Get unique ID of waypoint.
|
--- Get unique ID of waypoint.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #OPSGROUP.Waypoint waypoint The waypoint data table.
|
||||||
|
-- @return #number Unique ID.
|
||||||
|
function OPSGROUP:GetWaypointUID(waypoint)
|
||||||
|
return waypoint.uid
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get unique ID of waypoint given its index.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
-- @param #number indx Waypoint index.
|
-- @param #number indx Waypoint index.
|
||||||
-- @return #number Unique ID.
|
-- @return #number Unique ID.
|
||||||
function OPSGROUP:GetWaypointID(indx)
|
function OPSGROUP:GetWaypointID(indx)
|
||||||
@ -1213,7 +1222,7 @@ function OPSGROUP:AddTaskWaypoint(task, Waypoint, description, prio, duration)
|
|||||||
|
|
||||||
-- Task data structure.
|
-- Task data structure.
|
||||||
local newtask={} --#OPSGROUP.Task
|
local newtask={} --#OPSGROUP.Task
|
||||||
newtask.description=description
|
newtask.description=description or string.format("Task #%d", self.taskcounter)
|
||||||
newtask.status=OPSGROUP.TaskStatus.SCHEDULED
|
newtask.status=OPSGROUP.TaskStatus.SCHEDULED
|
||||||
newtask.dcstask=task
|
newtask.dcstask=task
|
||||||
newtask.prio=prio or 50
|
newtask.prio=prio or 50
|
||||||
@ -2592,6 +2601,72 @@ function OPSGROUP:_CheckGroupDone(delay)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Status Info Common to Air, Land and Sea
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Print info on mission and task status to DCS log file.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
function OPSGROUP:_PrintTaskAndMissionStatus()
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Tasks: verbose >= 2
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Task queue.
|
||||||
|
if #self.taskqueue>0 and self.verbose>=2 then
|
||||||
|
local text=string.format("Tasks #%d", #self.taskqueue)
|
||||||
|
for i,_task in pairs(self.taskqueue) do
|
||||||
|
local task=_task --Ops.OpsGroup#OPSGROUP.Task
|
||||||
|
local name=task.description
|
||||||
|
local taskid=task.dcstask.id or "unknown"
|
||||||
|
local status=task.status
|
||||||
|
local clock=UTILS.SecondsToClock(task.time, true)
|
||||||
|
local eta=task.time-timer.getAbsTime()
|
||||||
|
local started=task.timestamp and UTILS.SecondsToClock(task.timestamp, true) or "N/A"
|
||||||
|
local duration=-1
|
||||||
|
if task.duration then
|
||||||
|
duration=task.duration
|
||||||
|
if task.timestamp then
|
||||||
|
-- Time the task is running.
|
||||||
|
duration=task.duration-(timer.getAbsTime()-task.timestamp)
|
||||||
|
else
|
||||||
|
-- Time the task is supposed to run.
|
||||||
|
duration=task.duration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Output text for element.
|
||||||
|
if task.type==OPSGROUP.TaskType.SCHEDULED then
|
||||||
|
text=text..string.format("\n[%d] %s (%s): status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
|
||||||
|
elseif task.type==OPSGROUP.TaskType.WAYPOINT then
|
||||||
|
text=text..string.format("\n[%d] %s (%s): status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:I(self.lid..text)
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Missions: verbose>=1
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Current mission name.
|
||||||
|
if self.verbose>0 then
|
||||||
|
local Mission=self:GetMissionByID(self.currentmission)
|
||||||
|
|
||||||
|
-- Current status.
|
||||||
|
local text=string.format("Missions %d, Current: %s", self:CountRemainingMissison(), Mission and Mission.name or "none")
|
||||||
|
for i,_mission in pairs(self.missionqueue) do
|
||||||
|
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||||
|
local Cstart= UTILS.SecondsToClock(mission.Tstart, true)
|
||||||
|
local Cstop = mission.Tstop and UTILS.SecondsToClock(mission.Tstop, true) or "INF"
|
||||||
|
text=text..string.format("\n[%d] %s (%s) status=%s (%s), Time=%s-%s, prio=%d wp=%s targets=%d",
|
||||||
|
i, tostring(mission.name), mission.type, mission:GetGroupStatus(self), tostring(mission.status), Cstart, Cstop, mission.prio, tostring(mission:GetGroupWaypointIndex(self)), mission:CountMissionTargets())
|
||||||
|
end
|
||||||
|
self:I(self.lid..text)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Waypoints & Routing
|
-- Waypoints & Routing
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -2653,9 +2728,13 @@ function OPSGROUP:InitWaypoints()
|
|||||||
|
|
||||||
for index,wp in pairs(self.waypoints0) do
|
for index,wp in pairs(self.waypoints0) do
|
||||||
|
|
||||||
local waypoint=self:_CreateWaypoint(wp)
|
--local waypoint=self:_CreateWaypoint(wp)
|
||||||
|
--self:_AddWaypoint(waypoint)
|
||||||
|
|
||||||
self:_AddWaypoint(waypoint)
|
local coordinate=COORDINATE:New(wp.x, wp.alt, wp.y)
|
||||||
|
local speedknots=UTILS.MpsToKnots(wp.speed)
|
||||||
|
|
||||||
|
self:AddWaypoint(coordinate, speedknots, index-1, nil, false)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2871,19 +2950,26 @@ end
|
|||||||
|
|
||||||
--- Set current ROE for the group.
|
--- Set current ROE for the group.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #string roe ROE of group. Default is the value defined by :SetDefaultROE().
|
-- @param #string roe ROE of group. Default is `ENUMS.ROE.ReturnFire`.
|
||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SwitchROE(roe)
|
function OPSGROUP:SwitchROE(roe)
|
||||||
|
|
||||||
|
if self:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
self.option.ROE=roe or self.optionDefault.ROE
|
self.option.ROE=roe or ENUMS.ROE.ReturnFire
|
||||||
|
|
||||||
if self:IsAlive() then
|
if self:IsInUtero() then
|
||||||
|
self:I(self.lid..string.format("Setting current ROE=%d when GROUP is SPAWNED", self.option.ROE))
|
||||||
self.group:OptionROE(self.option.ROE)
|
else
|
||||||
|
|
||||||
|
self.group:OptionROE(roe)
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Setting current ROE=%d (0=WeaponFree, 1=OpenFireWeaponFree, 2=OpenFire, 3=ReturnFire, 4=WeaponHold)", self.option.ROE))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
self:I(self.lid..string.format("Setting current ROE=%d (0=WeaponFree, 1=OpenFireWeaponFree, 2=OpenFire, 3=ReturnFire, 4=WeaponHold)", self.option.ROE))
|
|
||||||
else
|
else
|
||||||
-- TODO WARNING
|
self:E(self.lid.."WARNING: Cannot switch ROE! Group is not alive")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -2907,19 +2993,26 @@ end
|
|||||||
|
|
||||||
--- Set ROT for the group.
|
--- Set ROT for the group.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #string rot ROT of group. Default is the value defined by :SetDefaultROT().
|
-- @param #string rot ROT of group. Default is `ENUMS.ROT.PassiveDefense`.
|
||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SwitchROT(rot)
|
function OPSGROUP:SwitchROT(rot)
|
||||||
|
|
||||||
self.option.ROT=rot or self.optionDefault.ROT
|
|
||||||
|
|
||||||
if self:IsAlive() then
|
if self:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
self.group:OptionROT(self.option.ROT)
|
self.option.ROT=rot or ENUMS.ROT.PassiveDefense
|
||||||
|
|
||||||
|
if self:IsInUtero() then
|
||||||
|
self:I(self.lid..string.format("Setting current ROT=%d when GROUP is SPAWNED", self.option.ROT))
|
||||||
|
else
|
||||||
|
|
||||||
self:T2(self.lid..string.format("Setting current ROT=%d (0=NoReaction, 1=Passive, 2=Evade, 3=ByPass, 4=AllowAbort)", self.option.ROT))
|
self.group:OptionROT(self.option.ROT)
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Setting current ROT=%d (0=NoReaction, 1=Passive, 2=Evade, 3=ByPass, 4=AllowAbort)", self.option.ROT))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
-- TODO WARNING
|
self:E(self.lid.."WARNING: Cannot switch ROT! Group is not alive")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -2943,29 +3036,41 @@ function OPSGROUP:SetDefaultAlarmstate(alarmstate)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Set current Alarm State of the group.
|
--- Set current Alarm State of the group.
|
||||||
|
--
|
||||||
|
-- * 0 = "Auto"
|
||||||
|
-- * 1 = "Green"
|
||||||
|
-- * 2 = "Red"
|
||||||
|
--
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #string alarmstate Alarm state of group. Default is the value defined by :SetDefaultAlarmstate().
|
-- @param #number alarmstate Alarm state of group. Default is 0="Auto".
|
||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SwitchAlarmstate(alarmstate)
|
function OPSGROUP:SwitchAlarmstate(alarmstate)
|
||||||
|
|
||||||
self.option.Alarm=alarmstate or self.optionDefault.Alarm
|
|
||||||
|
|
||||||
if self:IsAlive() then
|
if self:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
if self.option.Alarm==0 then
|
self.option.Alarm=alarmstate or 0
|
||||||
self.group:OptionAlarmStateAuto()
|
|
||||||
elseif self.option.Alarm==1 then
|
|
||||||
self.group:OptionAlarmStateGreen()
|
|
||||||
elseif self.option.Alarm==2 then
|
|
||||||
self.group:OptionAlarmStateRed()
|
|
||||||
else
|
|
||||||
self:E("ERROR: Unknown Alarm State! Setting to AUTO.")
|
|
||||||
self.group:OptionAlarmStateAuto()
|
|
||||||
end
|
|
||||||
|
|
||||||
self:I(self.lid..string.format("Setting current Alarm State=%d (0=Auto, 1=Green, 2=Red)", self.option.Alarm))
|
if self:IsInUtero() then
|
||||||
|
self:I(self.lid..string.format("Setting current Alarm State=%d when GROUP is SPAWNED", self.option.Alarm))
|
||||||
|
else
|
||||||
|
|
||||||
|
if self.option.Alarm==0 then
|
||||||
|
self.group:OptionAlarmStateAuto()
|
||||||
|
elseif self.option.Alarm==1 then
|
||||||
|
self.group:OptionAlarmStateGreen()
|
||||||
|
elseif self.option.Alarm==2 then
|
||||||
|
self.group:OptionAlarmStateRed()
|
||||||
|
else
|
||||||
|
self:E("ERROR: Unknown Alarm State! Setting to AUTO")
|
||||||
|
self.group:OptionAlarmStateAuto()
|
||||||
|
self.option.Alarm=0
|
||||||
|
end
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Setting current Alarm State=%d (0=Auto, 1=Green, 2=Red)", self.option.Alarm))
|
||||||
|
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- TODO WARNING
|
self:E(self.lid.."WARNING: Cannot switch Alarm State! Group is not alive.")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -2996,6 +3101,15 @@ function OPSGROUP:SetDefaultTACAN(Channel, Morse, UnitName, Band)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Activate/switch TACAN beacon settings.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #OPSGROUP.Beacon Tacan Tacan data table.
|
||||||
|
-- @return #OPSGROUP self
|
||||||
|
function OPSGROUP:_SwitchTACAN(Tacan)
|
||||||
|
self:SwitchTACAN(Tacan.Channel, Tacan.Morse, Tacan.BeaconName, Tacan.Band)
|
||||||
|
end
|
||||||
|
|
||||||
--- Activate/switch TACAN beacon settings.
|
--- Activate/switch TACAN beacon settings.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #number Channel TACAN Channel.
|
-- @param #number Channel TACAN Channel.
|
||||||
@ -3005,7 +3119,7 @@ end
|
|||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SwitchTACAN(Channel, Morse, UnitName, Band)
|
function OPSGROUP:SwitchTACAN(Channel, Morse, UnitName, Band)
|
||||||
|
|
||||||
if self:IsAlive() then
|
if self:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
local unit=self.group:GetUnit(1) --Wrapper.Unit#UNIT
|
local unit=self.group:GetUnit(1) --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
@ -3022,15 +3136,10 @@ function OPSGROUP:SwitchTACAN(Channel, Morse, UnitName, Band)
|
|||||||
unit=self.group:GetUnit(1)
|
unit=self.group:GetUnit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Channel then
|
Channel=Channel or 74
|
||||||
Channel=self.tacanDefault and self.tacanDefault.Channel or nil
|
Morse=Morse or "XXX"
|
||||||
end
|
|
||||||
|
|
||||||
if not Morse then
|
if unit and unit:IsAlive() or self:IsInUtero() then
|
||||||
Morse=self.tacanDefault and self.tacanDefault.Morse or "XXX"
|
|
||||||
end
|
|
||||||
|
|
||||||
if unit and unit:IsAlive() and Channel then
|
|
||||||
|
|
||||||
local UnitID=unit:GetID()
|
local UnitID=unit:GetID()
|
||||||
|
|
||||||
@ -3039,7 +3148,7 @@ function OPSGROUP:SwitchTACAN(Channel, Morse, UnitName, Band)
|
|||||||
|
|
||||||
if self.isAircraft then
|
if self.isAircraft then
|
||||||
System=BEACON.System.TACAN_TANKER_Y
|
System=BEACON.System.TACAN_TANKER_Y
|
||||||
Band=Band or "Y"
|
Band=Band or "Y"
|
||||||
else
|
else
|
||||||
System=BEACON.System.TACAN
|
System=BEACON.System.TACAN
|
||||||
Band=Band or "X"
|
Band=Band or "X"
|
||||||
@ -3048,26 +3157,31 @@ function OPSGROUP:SwitchTACAN(Channel, Morse, UnitName, Band)
|
|||||||
-- Tacan frequency.
|
-- Tacan frequency.
|
||||||
local Frequency=UTILS.TACANToFrequency(Channel, Band)
|
local Frequency=UTILS.TACANToFrequency(Channel, Band)
|
||||||
|
|
||||||
-- Activate beacon.
|
|
||||||
unit:CommandActivateBeacon(Type, System, Frequency, UnitID, Channel, Band, true, Morse, true)
|
|
||||||
|
|
||||||
-- Update info.
|
-- Update info.
|
||||||
self.tacan={}
|
|
||||||
self.tacan.Channel=Channel
|
self.tacan.Channel=Channel
|
||||||
self.tacan.Morse=Morse
|
self.tacan.Morse=Morse
|
||||||
self.tacan.Band=Band
|
self.tacan.Band=Band
|
||||||
self.tacan.BeaconName=unit:GetName()
|
self.tacan.BeaconName=unit:GetName()
|
||||||
self.tacan.BeaconUnit=unit
|
self.tacan.BeaconUnit=unit
|
||||||
|
self.tacan.On=true
|
||||||
|
|
||||||
-- TACAN is now on.
|
if self:IsInUtero() then
|
||||||
self.tacanOn=true
|
self:I(self.lid..string.format("Switching TACAN to Channel %d%s Morse %s on unit %s when GROUP is SPAWNED", self.tacan.Channel, self.tacan.Band, tostring(self.tacan.Morse), self.tacan.BeaconName))
|
||||||
|
else
|
||||||
self:I(self.lid..string.format("Switching TACAN to Channel %d%s Morse %s on unit %s", self.tacan.Channel, self.tacan.Band, tostring(self.tacan.Morse), self.tacan.BeaconName))
|
|
||||||
|
-- Activate beacon.
|
||||||
|
unit:CommandActivateBeacon(Type, System, Frequency, UnitID, Channel, Band, true, Morse, true)
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Switching TACAN to Channel %d%s Morse %s on unit %s", self.tacan.Channel, self.tacan.Band, tostring(self.tacan.Morse), self.tacan.BeaconName))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(self.lid.."ERROR: Cound not set TACAN! Unit is not alive.")
|
self:E(self.lid.."ERROR: Cound not set TACAN! Unit is not alive")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: Cound not set TACAN! Group is not alive")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -3107,13 +3221,21 @@ end
|
|||||||
|
|
||||||
--- Activate/switch ICLS beacon settings.
|
--- Activate/switch ICLS beacon settings.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #number Channel ICLS Channel.
|
-- @param #OPSGROUP.Beacon Icls ICLS data table.
|
||||||
-- @param #string Morse ICLS morse code. Default is the value set in @{#OPSGROUP.SetDefaultICLS} or if not set "XXX".
|
-- @return #OPSGROUP self
|
||||||
|
function OPSGROUP:_SwitchICLS(Icls)
|
||||||
|
self:SwitchICLS(Icls.Channel, Icls.Morse, Icls.BeaconName)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Activate/switch ICLS beacon settings.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #number Channel ICLS Channel. Default is 1.
|
||||||
|
-- @param #string Morse ICLS morse code. Default is "XXX".
|
||||||
-- @param #string UnitName Name of the unit in the group which should activate the ICLS beacon. Can also be given as #number to specify the unit number. Default is the first unit of the group.
|
-- @param #string UnitName Name of the unit in the group which should activate the ICLS beacon. Can also be given as #number to specify the unit number. Default is the first unit of the group.
|
||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SwitchICLS(Channel, Morse, UnitName)
|
function OPSGROUP:SwitchICLS(Channel, Morse, UnitName)
|
||||||
|
|
||||||
if self:IsAlive() then
|
if self:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
local unit=self.group:GetUnit(1) --Wrapper.Unit#UNIT
|
local unit=self.group:GetUnit(1) --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
@ -3130,33 +3252,32 @@ function OPSGROUP:SwitchICLS(Channel, Morse, UnitName)
|
|||||||
unit=self.group:GetUnit(1)
|
unit=self.group:GetUnit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Channel then
|
Channel=Channel or 1
|
||||||
Channel=self.iclsDefault and self.iclsDefault.Channel or nil
|
Morse=Morse or "XXX"
|
||||||
end
|
|
||||||
|
|
||||||
if not Morse then
|
|
||||||
Morse=self.iclsDefault and self.iclsDefault.Morse or "XXX"
|
|
||||||
end
|
|
||||||
|
|
||||||
if unit and unit:IsAlive() and Channel then
|
if unit and unit:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
local UnitID=unit:GetID()
|
local UnitID=unit:GetID()
|
||||||
|
|
||||||
-- Activate beacon.
|
|
||||||
unit:CommandActivateICLS(Channel, UnitID, Morse)
|
|
||||||
|
|
||||||
-- Update info.
|
-- Update info.
|
||||||
self.icls={}
|
|
||||||
self.icls.Channel=Channel
|
self.icls.Channel=Channel
|
||||||
self.icls.Morse=Morse
|
self.icls.Morse=Morse
|
||||||
self.icls.Band=Band
|
self.icls.Band=nil
|
||||||
self.icls.BeaconName=unit:GetName()
|
self.icls.BeaconName=unit:GetName()
|
||||||
self.icls.BeaconUnit=unit
|
self.icls.BeaconUnit=unit
|
||||||
|
self.icls.On=true
|
||||||
|
|
||||||
|
|
||||||
-- ICLS is now on.
|
if self:IsInUtero() then
|
||||||
self.iclsOn=true
|
self:I(self.lid..string.format("Switching ICLS to Channel %d Morse %s on unit %s when GROUP is SPAWNED", self.icls.Channel, tostring(self.icls.Morse), self.icls.BeaconName))
|
||||||
|
else
|
||||||
|
|
||||||
self:I(self.lid..string.format("Switching ICLS to Channel %d Morse %s on unit %s", self.icls.Channel, tostring(self.icls.Morse), self.icls.BeaconName))
|
-- Activate beacon.
|
||||||
|
unit:CommandActivateICLS(Channel, UnitID, Morse)
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Switching ICLS to Channel %d Morse %s on unit %s", self.icls.Channel, tostring(self.icls.Morse), self.icls.BeaconName))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(self.lid.."ERROR: Cound not set ICLS! Unit is not alive.")
|
self:E(self.lid.."ERROR: Cound not set ICLS! Unit is not alive.")
|
||||||
@ -3204,33 +3325,42 @@ function OPSGROUP:GetRadio()
|
|||||||
return self.radio.Freq, self.radio.Modu
|
return self.radio.Freq, self.radio.Modu
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Turn radio on.
|
--- Turn radio on or switch frequency/modulation.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #number Frequency Radio frequency in MHz.
|
-- @param #number Frequency Radio frequency in MHz. Default is 127.5 MHz.
|
||||||
-- @param #number Modulation Radio modulation. Default `radio.Modulation.AM`.
|
-- @param #number Modulation Radio modulation. Default `radio.Modulation.AM`.
|
||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SwitchRadio(Frequency, Modulation)
|
function OPSGROUP:SwitchRadio(Frequency, Modulation)
|
||||||
|
|
||||||
if self:IsAlive() and Frequency then
|
if self:IsAlive() or self:IsInUtero() then
|
||||||
|
|
||||||
Modulation=Modulation or self.radioDefault.Modu
|
Frequency=Frequency or 127.5
|
||||||
|
Modulation=Modulation or radio.modulation.AM
|
||||||
|
|
||||||
local group=self.group --Wrapper.Group#GROUP
|
local group=self.group --Wrapper.Group#GROUP
|
||||||
|
|
||||||
if self.isAircraft and not self.radioOn then
|
if self.isAircraft and not self.radio.On then
|
||||||
group:SetOption(AI.Option.Air.id.SILENCE, false)
|
group:SetOption(AI.Option.Air.id.SILENCE, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
group:CommandSetFrequency(Frequency, Modulation)
|
-- Set radio
|
||||||
|
|
||||||
self.radio.Freq=Frequency
|
self.radio.Freq=Frequency
|
||||||
self.radio.Modu=Modulation
|
self.radio.Modu=Modulation
|
||||||
|
self.radio.On=true
|
||||||
|
|
||||||
-- Radio is on.
|
if self:IsInUtero() then
|
||||||
self.radioOn=true
|
self:I(self.lid..string.format("Switching radio to frequency %.3f MHz %s when GROUP is SPAWNED", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu)))
|
||||||
|
else
|
||||||
self:I(self.lid..string.format("Switching radio to frequency %.3f MHz %s", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu)))
|
|
||||||
|
|
||||||
|
-- Give command
|
||||||
|
group:CommandSetFrequency(Frequency, Modulation)
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Switching radio to frequency %.3f MHz %s", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu)))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: Cound not set Radio! Group is not alive")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -3252,11 +3382,11 @@ function OPSGROUP:TurnOffRadio()
|
|||||||
--self.radio.Modu=nil
|
--self.radio.Modu=nil
|
||||||
|
|
||||||
-- Radio is off.
|
-- Radio is off.
|
||||||
self.radioOn=false
|
self.radio.On=false
|
||||||
|
|
||||||
self:I(self.lid..string.format("Switching radio OFF"))
|
self:I(self.lid..string.format("Switching radio OFF"))
|
||||||
else
|
else
|
||||||
self:E(self.lid.."ERROR radio can only be turned off for aircraft!")
|
self:E(self.lid.."ERROR: Radio can only be turned off for aircraft!")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -156,8 +156,10 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
|
|||||||
-- From State --> Event --> To State
|
-- From State --> Event --> To State
|
||||||
self:AddTransition("Stopped", "Start", "OnDuty") -- Start FSM.
|
self:AddTransition("Stopped", "Start", "OnDuty") -- Start FSM.
|
||||||
self:AddTransition("*", "Status", "*") -- Status update.
|
self:AddTransition("*", "Status", "*") -- Status update.
|
||||||
|
|
||||||
self:AddTransition("OnDuty", "Pause", "Paused") -- Pause squadron.
|
self:AddTransition("OnDuty", "Pause", "Paused") -- Pause squadron.
|
||||||
self:AddTransition("Paused", "Unpause", "OnDuty") -- Unpause squadron.
|
self:AddTransition("Paused", "Unpause", "OnDuty") -- Unpause squadron.
|
||||||
|
|
||||||
self:AddTransition("*", "Stop", "Stopped") -- Stop squadron.
|
self:AddTransition("*", "Stop", "Stopped") -- Stop squadron.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user