mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Ops
- Laser
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
-- @field #number dT Time interval between function calls in seconds.
|
-- @field #number dT Time interval between function calls in seconds.
|
||||||
-- @field #number ncalls Counter of function calls.
|
-- @field #number ncalls Counter of function calls.
|
||||||
-- @field #number ncallsMax Max number of function calls. If reached, timer is stopped.
|
-- @field #number ncallsMax Max number of function calls. If reached, timer is stopped.
|
||||||
|
-- @field #boolean isrunning If `true`, timer is running. Else it was not started yet or was stopped.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- *Better three hours too soon than a minute too late.* - William Shakespeare
|
--- *Better three hours too soon than a minute too late.* - William Shakespeare
|
||||||
@@ -111,7 +112,7 @@ _TIMERID=0
|
|||||||
|
|
||||||
--- TIMER class version.
|
--- TIMER class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
TIMER.version="0.1.0"
|
TIMER.version="0.1.1"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -143,6 +144,9 @@ function TIMER:New(Function, ...)
|
|||||||
-- Number of function calls.
|
-- Number of function calls.
|
||||||
self.ncalls=0
|
self.ncalls=0
|
||||||
|
|
||||||
|
-- Not running yet.
|
||||||
|
self.isrunning=false
|
||||||
|
|
||||||
-- Increase counter
|
-- Increase counter
|
||||||
_TIMERID=_TIMERID+1
|
_TIMERID=_TIMERID+1
|
||||||
|
|
||||||
@@ -186,6 +190,9 @@ function TIMER:Start(Tstart, dT, Duration)
|
|||||||
-- Set log id.
|
-- Set log id.
|
||||||
self.lid=string.format("TIMER UID=%d/%d | ", self.uid, self.tid)
|
self.lid=string.format("TIMER UID=%d/%d | ", self.uid, self.tid)
|
||||||
|
|
||||||
|
-- Is now running.
|
||||||
|
self.isrunning=true
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Starting Timer in %.3f sec, dT=%s, Tstop=%s", self.Tstart-Tnow, tostring(self.dT), tostring(self.Tstop)))
|
self:T(self.lid..string.format("Starting Timer in %.3f sec, dT=%s, Tstop=%s", self.Tstart-Tnow, tostring(self.dT), tostring(self.Tstop)))
|
||||||
|
|
||||||
@@ -210,6 +217,9 @@ function TIMER:Stop(Delay)
|
|||||||
self:T(self.lid..string.format("Stopping timer by removing timer function after %d calls!", self.ncalls))
|
self:T(self.lid..string.format("Stopping timer by removing timer function after %d calls!", self.ncalls))
|
||||||
timer.removeFunction(self.tid)
|
timer.removeFunction(self.tid)
|
||||||
|
|
||||||
|
-- Not running any more.
|
||||||
|
self.isrunning=false
|
||||||
|
|
||||||
-- Remove DB entry.
|
-- Remove DB entry.
|
||||||
--_TIMERDB[self.uid]=nil
|
--_TIMERDB[self.uid]=nil
|
||||||
|
|
||||||
@@ -229,6 +239,13 @@ function TIMER:SetMaxFunctionCalls(Nmax)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check if the timer has been started and was not stopped.
|
||||||
|
-- @param #TIMER self
|
||||||
|
-- @return #boolean If `true`, the timer is running.
|
||||||
|
function TIMER:IsRunning()
|
||||||
|
return self.isrunning
|
||||||
|
end
|
||||||
|
|
||||||
--- Call timer function.
|
--- Call timer function.
|
||||||
-- @param #TIMER self
|
-- @param #TIMER self
|
||||||
-- @param #number time DCS model time in seconds.
|
-- @param #number time DCS model time in seconds.
|
||||||
|
|||||||
@@ -275,6 +275,8 @@ OPSGROUP.TaskType={
|
|||||||
-- @field Core.Point#COORDINATE Coordinate where the spot is pointing.
|
-- @field Core.Point#COORDINATE Coordinate where the spot is pointing.
|
||||||
-- @field #number TargetType Type of target: 0=coordinate, 1=static, 2=unit, 3=group.
|
-- @field #number TargetType Type of target: 0=coordinate, 1=static, 2=unit, 3=group.
|
||||||
-- @field #boolean On If true, the laser is on.
|
-- @field #boolean On If true, the laser is on.
|
||||||
|
-- @field #boolean Paused If true, laser is paused.
|
||||||
|
-- @field #boolean lostLOS If true, laser lost LOS.
|
||||||
-- @field #OPSGROUP.Element element The element of the group that is lasing.
|
-- @field #OPSGROUP.Element element The element of the group that is lasing.
|
||||||
-- @field DCS#Vec3 vec3 The 3D positon vector of the laser (and IR) spot.
|
-- @field DCS#Vec3 vec3 The 3D positon vector of the laser (and IR) spot.
|
||||||
-- @field DCS#Vec3 offset Local offset of the laser source.
|
-- @field DCS#Vec3 offset Local offset of the laser source.
|
||||||
@@ -415,6 +417,7 @@ function OPSGROUP:New(Group)
|
|||||||
self:AddTransition("*", "LaserOff", "*") -- Turn laser off.
|
self:AddTransition("*", "LaserOff", "*") -- Turn laser off.
|
||||||
self:AddTransition("*", "LaserCode", "*") -- Switch laser code.
|
self:AddTransition("*", "LaserCode", "*") -- Switch laser code.
|
||||||
self:AddTransition("*", "LaserPause", "*") -- Turn laser off temporarily.
|
self:AddTransition("*", "LaserPause", "*") -- Turn laser off temporarily.
|
||||||
|
self:AddTransition("*", "LaserResume", "*") -- Turn laser back on again if it was paused.
|
||||||
self:AddTransition("*", "LaserLostLOS", "*") -- Lasing element lost line of sight.
|
self:AddTransition("*", "LaserLostLOS", "*") -- Lasing element lost line of sight.
|
||||||
self:AddTransition("*", "LaserGotLOS", "*") -- Lasing element got line of sight.
|
self:AddTransition("*", "LaserGotLOS", "*") -- Lasing element got line of sight.
|
||||||
|
|
||||||
@@ -671,6 +674,76 @@ function OPSGROUP:GetThreat(ThreatLevelMin, ThreatLevelMax)
|
|||||||
return threat, level
|
return threat, level
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get highest threat.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @return Wrapper.Unit#UNIT The highest threat unit.
|
||||||
|
-- @return #number Threat level of the unit.
|
||||||
|
function OPSGROUP:GetHighestThreat()
|
||||||
|
|
||||||
|
local threat=nil
|
||||||
|
local levelmax=-1
|
||||||
|
for _,_unit in pairs(self.detectedunits:GetSet()) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
local threatlevel=unit:GetThreatLevel()
|
||||||
|
|
||||||
|
if threatlevel>levelmax then
|
||||||
|
threat=unit
|
||||||
|
levelmax=threatlevel
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return threat, levelmax
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if an element of the group has line of sight to a coordinate.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The position to which we check the LoS.
|
||||||
|
-- @param #OPSGROUP.Element Element The (optinal) element. If not given, all elements are checked.
|
||||||
|
-- @param DCS#Vec3 OffsetElement Offset vector of the element.
|
||||||
|
-- @param DCS#Vec3 OffsetCoordinate Offset vector of the coordinate.
|
||||||
|
-- @return #boolean If `true`, there is line of sight to the specified coordinate.
|
||||||
|
function OPSGROUP:HasLoS(Coordinate, Element, OffsetElement, OffsetCoordinate)
|
||||||
|
|
||||||
|
-- Target vector.
|
||||||
|
local Vec3=Coordinate:GetVec3()
|
||||||
|
|
||||||
|
-- Optional offset.
|
||||||
|
if OffsetCoordinate then
|
||||||
|
Vec3=UTILS.VecAdd(Vec3, OffsetCoordinate)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Function to check LoS for an element of the group.
|
||||||
|
local function checklos(element)
|
||||||
|
local vec3=element.unit:GetVec3()
|
||||||
|
if OffsetElement then
|
||||||
|
vec3=UTILS.VecAdd(vec3, OffsetElement)
|
||||||
|
end
|
||||||
|
local _los=land.isVisible(vec3, Vec3)
|
||||||
|
--self:I({los=_los, source=vec3, target=Vec3})
|
||||||
|
return _los
|
||||||
|
end
|
||||||
|
|
||||||
|
if Element then
|
||||||
|
local los=checklos(Element)
|
||||||
|
return los
|
||||||
|
else
|
||||||
|
|
||||||
|
for _,element in pairs(self.elements) do
|
||||||
|
-- Get LoS of this element.
|
||||||
|
local los=checklos(element)
|
||||||
|
if los then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Get MOOSE GROUP object.
|
--- Get MOOSE GROUP object.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @return Wrapper.Group#GROUP Moose group object.
|
-- @return Wrapper.Group#GROUP Moose group object.
|
||||||
@@ -3085,7 +3158,7 @@ function OPSGROUP:onbeforeLaserOn(From, Event, To, Target)
|
|||||||
|
|
||||||
else
|
else
|
||||||
-- No target specified.
|
-- No target specified.
|
||||||
--TODO: error message
|
self:E(self.lid.."ERROR: No target provided for LASER!")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3097,9 +3170,6 @@ function OPSGROUP:onbeforeLaserOn(From, Event, To, Target)
|
|||||||
-- Set element.
|
-- Set element.
|
||||||
self.spot.element=element
|
self.spot.element=element
|
||||||
|
|
||||||
-- Vec3.
|
|
||||||
self.spot.vec3=self.spot.Coordinate:GetVec3()
|
|
||||||
|
|
||||||
-- Height offset. No offset for aircraft. We take the height for ground or naval.
|
-- Height offset. No offset for aircraft. We take the height for ground or naval.
|
||||||
local offsetY=0
|
local offsetY=0
|
||||||
if self.isGround or self.isNaval then
|
if self.isGround or self.isNaval then
|
||||||
@@ -3113,13 +3183,15 @@ function OPSGROUP:onbeforeLaserOn(From, Event, To, Target)
|
|||||||
if self.spot.CheckLOS then
|
if self.spot.CheckLOS then
|
||||||
|
|
||||||
-- Check LOS.
|
-- Check LOS.
|
||||||
self.spot.LOS=self:HasLoS(self.spot.Coordinate, self.spot.element, self.spot.offset)
|
local los=self:HasLoS(self.spot.Coordinate, self.spot.element, self.spot.offset)
|
||||||
|
|
||||||
if self.spot.LOS then
|
--self:I({los=los, coord=self.spot.Coordinate, offset=self.spot.offset})
|
||||||
|
|
||||||
|
if los then
|
||||||
self:LaserGotLOS()
|
self:LaserGotLOS()
|
||||||
else
|
else
|
||||||
-- Try to switch laser on again in 10 sec.
|
-- Try to switch laser on again in 10 sec.
|
||||||
self:T(self.lid.."LASER got no LOS currently. Trying to switch the laser on again in 10 sec")
|
self:I(self.lid.."LASER got no LOS currently. Trying to switch the laser on again in 10 sec")
|
||||||
self:__LaserOn(-10, Target)
|
self:__LaserOn(-10, Target)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@@ -3143,7 +3215,9 @@ end
|
|||||||
function OPSGROUP:onafterLaserOn(From, Event, To, Target)
|
function OPSGROUP:onafterLaserOn(From, Event, To, Target)
|
||||||
|
|
||||||
-- Start timer that calls the update twice per sec by default.
|
-- Start timer that calls the update twice per sec by default.
|
||||||
self.spot.timer:Start(nil, self.spot.dt)
|
if not self.spot.timer:IsRunning() then
|
||||||
|
self.spot.timer:Start(nil, self.spot.dt)
|
||||||
|
end
|
||||||
|
|
||||||
-- Get DCS unit.
|
-- Get DCS unit.
|
||||||
local DCSunit=self.spot.element.unit:GetDCSObject()
|
local DCSunit=self.spot.element.unit:GetDCSObject()
|
||||||
@@ -3157,6 +3231,9 @@ function OPSGROUP:onafterLaserOn(From, Event, To, Target)
|
|||||||
-- Laser is on.
|
-- Laser is on.
|
||||||
self.spot.On=true
|
self.spot.On=true
|
||||||
|
|
||||||
|
-- No paused in case it was.
|
||||||
|
self.spot.Paused=false
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:T(self.lid.."Switching LASER on")
|
self:T(self.lid.."Switching LASER on")
|
||||||
|
|
||||||
@@ -3168,7 +3245,7 @@ end
|
|||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function OPSGROUP:onbeforeLaserOff(From, Event, To)
|
function OPSGROUP:onbeforeLaserOff(From, Event, To)
|
||||||
return self.spot.On
|
return self.spot.On or self.spot.Paused
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "LaserOff" event.
|
--- On after "LaserOff" event.
|
||||||
@@ -3182,20 +3259,26 @@ function OPSGROUP:onafterLaserOff(From, Event, To)
|
|||||||
self:T(self.lid.."Switching LASER off")
|
self:T(self.lid.."Switching LASER off")
|
||||||
|
|
||||||
-- "Destroy" the laser beam.
|
-- "Destroy" the laser beam.
|
||||||
self.spot.Laser:destroy()
|
if self.spot.On then
|
||||||
self.spot.IR:destroy()
|
self.spot.Laser:destroy()
|
||||||
|
self.spot.IR:destroy()
|
||||||
|
|
||||||
|
-- Set to nil.
|
||||||
|
self.spot.Laser=nil
|
||||||
|
self.spot.IR=nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Stop update timer.
|
-- Stop update timer.
|
||||||
self.spot.timer:Stop()
|
self.spot.timer:Stop()
|
||||||
|
|
||||||
-- Set to nil.
|
-- No target unit.
|
||||||
self.spot.Laser=nil
|
|
||||||
self.spot.IR=nil
|
|
||||||
self.spot.TargetUnit=nil
|
self.spot.TargetUnit=nil
|
||||||
|
|
||||||
-- Laser is off.
|
-- Laser is off.
|
||||||
self.spot.On=false
|
self.spot.On=false
|
||||||
|
|
||||||
|
-- Not paused if it was.
|
||||||
|
self.spot.Paused=false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "LaserPause" event.
|
--- On after "LaserPause" event.
|
||||||
@@ -3219,6 +3302,52 @@ function OPSGROUP:onafterLaserPause(From, Event, To)
|
|||||||
-- Laser is off.
|
-- Laser is off.
|
||||||
self.spot.On=false
|
self.spot.On=false
|
||||||
|
|
||||||
|
-- Laser is paused.
|
||||||
|
self.spot.Paused=true
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On before "LaserResume" event.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
function OPSGROUP:onbeforeLaserResume(From, Event, To)
|
||||||
|
return self.spot.Paused
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "LaserResume" event.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
function OPSGROUP:onafterLaserResume(From, Event, To)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:I(self.lid.."Resuming LASER")
|
||||||
|
|
||||||
|
-- Unset paused.
|
||||||
|
self.spot.Paused=false
|
||||||
|
|
||||||
|
-- Set target.
|
||||||
|
local target=nil
|
||||||
|
if self.spot.TargetType==0 then
|
||||||
|
target=self.spot.Coordinate
|
||||||
|
elseif self.spot.TargetType==1 or self.spot.TargetType==2 then
|
||||||
|
target=self.spot.TargetUnit
|
||||||
|
elseif self.spot.TargetType==3 then
|
||||||
|
target=self.spot.TargetGroup
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Switch laser back on.
|
||||||
|
if target then
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid.."Switching LASER on again at target ".. target:GetName())
|
||||||
|
|
||||||
|
self:LaserOn(target)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "LaserCode" event. Changes the LASER code.
|
--- On after "LaserCode" event. Changes the LASER code.
|
||||||
@@ -3253,9 +3382,12 @@ end
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function OPSGROUP:onafterLaserLostLOS(From, Event, To)
|
function OPSGROUP:onafterLaserLostLOS(From, Event, To)
|
||||||
|
|
||||||
-- Lost line of sight.
|
-- No of sight.
|
||||||
self.spot.LOS=false
|
self.spot.LOS=false
|
||||||
|
|
||||||
|
-- Lost line of sight.
|
||||||
|
self.spot.lostLOS=true
|
||||||
|
|
||||||
if self.spot.On then
|
if self.spot.On then
|
||||||
|
|
||||||
-- Switch laser off.
|
-- Switch laser off.
|
||||||
@@ -3272,25 +3404,24 @@ end
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function OPSGROUP:onafterLaserGotLOS(From, Event, To)
|
function OPSGROUP:onafterLaserGotLOS(From, Event, To)
|
||||||
|
|
||||||
-- Lost line of sight.
|
-- Has line of sight.
|
||||||
self.spot.LOS=true
|
self.spot.LOS=true
|
||||||
|
|
||||||
if not self.spot.On then
|
env.info("FF Laser Got LOS")
|
||||||
|
|
||||||
local target=nil
|
if self.spot.lostLOS then
|
||||||
|
|
||||||
if self.spot.TargetType==0 then
|
-- Did not loose LOS anymore.
|
||||||
target=self.spot.Coordinate
|
self.spot.lostLOS=false
|
||||||
elseif self.spot.TargetType==1 or self.spot.TargetType==2 then
|
|
||||||
target=self.spot.TargetUnit
|
env.info("FF had lost LOS and regained it")
|
||||||
elseif self.spot.TargetType==3 then
|
|
||||||
target=self.spot.TargetGroup
|
-- Resume laser if currently paused.
|
||||||
|
if self.spot.Paused then
|
||||||
|
env.info("FF laser was paused ==> resume")
|
||||||
|
self:LaserResume()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Switch laser back on.
|
|
||||||
if target then
|
|
||||||
self:__LaserOn(-1, target)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -3327,7 +3458,7 @@ function OPSGROUP:SetLaserTarget(Target)
|
|||||||
local size,x,y,z=self.spot.TargetUnit:GetObjectSize()
|
local size,x,y,z=self.spot.TargetUnit:GetObjectSize()
|
||||||
|
|
||||||
if y then
|
if y then
|
||||||
self.spot.offsetTarget={x=0, y=y/2, z=0}
|
self.spot.offsetTarget={x=0, y=y*0.75, z=0}
|
||||||
else
|
else
|
||||||
self.spot.offsetTarget={x=0, 2, z=0}
|
self.spot.offsetTarget={x=0, 2, z=0}
|
||||||
end
|
end
|
||||||
@@ -3348,159 +3479,83 @@ function OPSGROUP:SetLaserTarget(Target)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Set vec3 and account for target offset.
|
-- Set vec3 and account for target offset.
|
||||||
self.spot.vec3=UTILS.VecAdd(Target:GetVec3(), self.spot.offsetTarget)
|
self.spot.vec3=UTILS.VecAdd(Target:GetVec3(), self.spot.offsetTarget)
|
||||||
|
|
||||||
-- Set coordinate.
|
-- Set coordinate.
|
||||||
self.spot.Coordinate:UpdateFromVec3(self.spot.vec3)
|
self.spot.Coordinate:UpdateFromVec3(self.spot.vec3)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get highest threat.
|
|
||||||
-- @param #OPSGROUP self
|
|
||||||
-- @return Wrapper.Unit#UNIT The highest threat unit.
|
|
||||||
-- @return #number Threat level of the unit.
|
|
||||||
function OPSGROUP:GetHighestThreat()
|
|
||||||
|
|
||||||
local threat=nil
|
|
||||||
local levelmax=-1
|
|
||||||
for _,_unit in pairs(self.detectedunits:GetSet()) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
local threatlevel=unit:GetThreatLevel()
|
|
||||||
|
|
||||||
if threatlevel>levelmax then
|
|
||||||
threat=unit
|
|
||||||
levelmax=threatlevel
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return threat, levelmax
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Check if an element of the group has line of sight to a coordinate.
|
|
||||||
-- @param #OPSGROUP self
|
|
||||||
-- @param Core.Point#COORDINATE Coordinate The position to which we check the LoS.
|
|
||||||
-- @param #OPSGROUP.Element Element The (optinal) element. If not given, all elements are checked.
|
|
||||||
-- @param DCS#Vec3 OffsetElement Offset vector of the element.
|
|
||||||
-- @param DCS#Vec3 OffsetCoordinate Offset vector of the coordinate.
|
|
||||||
-- @return #boolean If `true`, there is line of sight to the specified coordinate.
|
|
||||||
function OPSGROUP:HasLoS(Coordinate, Element, OffsetElement, OffsetCoordinate)
|
|
||||||
|
|
||||||
-- Target vector.
|
|
||||||
local Vec3=Coordinate:GetVec3()
|
|
||||||
|
|
||||||
-- Optional offset.
|
|
||||||
if OffsetCoordinate then
|
|
||||||
Vec3=UTILS.VecAdd(vec3, OffsetCoordinate)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Function to check LoS for an element of the group.
|
|
||||||
local function checklos(element)
|
|
||||||
local vec3=element.unit:GetVec3()
|
|
||||||
if OffsetElement then
|
|
||||||
vec3=UTILS.VecAdd(vec3, OffsetElement)
|
|
||||||
end
|
|
||||||
local _los=land.isVisible(vec3, Vec3)
|
|
||||||
--self:I({los=_los, source=vec3, target=Vec3})
|
|
||||||
return _los
|
|
||||||
end
|
|
||||||
|
|
||||||
if Element then
|
|
||||||
local los=checklos(Element)
|
|
||||||
return los
|
|
||||||
else
|
|
||||||
|
|
||||||
for _,element in pairs(self.elements) do
|
|
||||||
-- Get LoS of this element.
|
|
||||||
local los=checklos(element)
|
|
||||||
if los then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Update laser point.
|
--- Update laser point.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
function OPSGROUP:_UpdateLaser()
|
function OPSGROUP:_UpdateLaser()
|
||||||
|
|
||||||
-- Firstly, check if laser is on.
|
-- Check if we have a POSITIONABLE to lase.
|
||||||
if self.spot.On then
|
if self.spot.TargetUnit then
|
||||||
|
|
||||||
---
|
---
|
||||||
-- LASER is ON
|
-- Lasing a possibly moving target
|
||||||
---
|
---
|
||||||
|
|
||||||
-- Check if we have a POSITIONABLE to lase.
|
if self.spot.TargetUnit:IsAlive() then
|
||||||
if self.spot.TargetUnit then
|
|
||||||
|
|
||||||
---
|
-- Get current target position.
|
||||||
-- Lasing a possibly moving target
|
local vec3=self.spot.TargetUnit:GetVec3()
|
||||||
---
|
|
||||||
|
|
||||||
if self.spot.TargetUnit:IsAlive() then
|
-- Add target offset.
|
||||||
|
vec3=UTILS.VecAdd(vec3, self.spot.offsetTarget)
|
||||||
|
|
||||||
-- Get current target position.
|
-- Calculate distance
|
||||||
local vec3=self.spot.TargetUnit:GetVec3()
|
local dist=UTILS.VecDist3D(vec3, self.spot.vec3)
|
||||||
|
|
||||||
-- Add target offset.
|
-- Store current position.
|
||||||
vec3=UTILS.VecAdd(vec3, self.spot.offsetTarget)
|
self.spot.vec3=vec3
|
||||||
|
|
||||||
-- Calculate distance
|
-- Update beam coordinate.
|
||||||
local dist=UTILS.VecDist3D(vec3, self.spot.vec3)
|
self.spot.Coordinate:UpdateFromVec3(vec3)
|
||||||
|
|
||||||
-- Update laser if target moved more than one meter.
|
-- Update laser if target moved more than one meter.
|
||||||
if dist>1 then
|
if dist>1 then
|
||||||
|
|
||||||
-- Store current position.
|
-- If the laser is ON, set the new laser target point.
|
||||||
self.spot.vec3=vec3
|
if self.spot.On then
|
||||||
|
|
||||||
-- Update beam coordinate.
|
|
||||||
self.spot.Coordinate:UpdateFromVec3(vec3)
|
|
||||||
|
|
||||||
-- Set the new laser target point.
|
|
||||||
self.spot.Laser:setPoint(vec3)
|
self.spot.Laser:setPoint(vec3)
|
||||||
if self.spot.IRon then
|
if self.spot.IRon then
|
||||||
self.spot.IR:setPoint(vec3)
|
self.spot.IR:setPoint(vec3)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
end
|
||||||
|
|
||||||
if self.spot.TargetGroup and self.spot.TargetGroup:IsAlive() then
|
else
|
||||||
|
|
||||||
-- Get first alive unit in the group.
|
if self.spot.TargetGroup and self.spot.TargetGroup:IsAlive() then
|
||||||
local unit=self.spot.TargetGroup:GetHighestThreat()
|
|
||||||
|
|
||||||
if unit then
|
-- Get first alive unit in the group.
|
||||||
self:I(self.lid..string.format("Switching to target unit %s in the group", unit:GetName()))
|
local unit=self.spot.TargetGroup:GetHighestThreat()
|
||||||
self.spot.TargetUnit=unit
|
|
||||||
else
|
|
||||||
-- Switch laser off.
|
|
||||||
self:I(self.lid.."Target is not alive any more ==> switching LASER off")
|
|
||||||
self:LaserOff()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if unit then
|
||||||
|
self:I(self.lid..string.format("Switching to target unit %s in the group", unit:GetName()))
|
||||||
|
self.spot.TargetUnit=unit
|
||||||
|
-- We update the laser position in the next update cycle and then check the LOS.
|
||||||
|
return
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Switch laser off.
|
-- Switch laser off.
|
||||||
self:I(self.lid.."Target is not alive any more ==> switching LASER off")
|
self:I(self.lid.."Target is not alive any more ==> switching LASER off")
|
||||||
self:LaserOff()
|
self:LaserOff()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Switch laser off.
|
||||||
|
self:I(self.lid.."Target is not alive any more ==> switching LASER off")
|
||||||
|
self:LaserOff()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3510,17 +3565,18 @@ function OPSGROUP:_UpdateLaser()
|
|||||||
-- Check current LOS.
|
-- Check current LOS.
|
||||||
local los=self:HasLoS(self.spot.Coordinate, self.spot.element, self.spot.offset)
|
local los=self:HasLoS(self.spot.Coordinate, self.spot.element, self.spot.offset)
|
||||||
|
|
||||||
--env.info(string.format("FF check LOS=%s", tostring(los)))
|
env.info(string.format("FF check LOS current=%s previous=%s", tostring(los), tostring(self.spot.LOS)))
|
||||||
|
|
||||||
if los then
|
if los then
|
||||||
-- Got LOS
|
-- Got LOS
|
||||||
if not self.spot.LOS then
|
if self.spot.lostLOS then
|
||||||
|
--self:I({los=self.spot.LOS, coord=self.spot.Coordinate, offset=self.spot.offset})
|
||||||
self:LaserGotLOS()
|
self:LaserGotLOS()
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
-- No LOS currently
|
-- No LOS currently
|
||||||
if self.spot.LOS then
|
if not self.spot.lostLOS then
|
||||||
self:LaserLostLOS()
|
self:LaserLostLOS()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user