mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Autolase - better calculation of LoS for lasing, somewhat faster detection
This commit is contained in:
parent
554f063def
commit
d112ffaf6a
@ -53,7 +53,8 @@
|
|||||||
-- :InitDelayOff()
|
-- :InitDelayOff()
|
||||||
-- :OnSpawnGroup(
|
-- :OnSpawnGroup(
|
||||||
-- function (group)
|
-- function (group)
|
||||||
-- local name = group:GetName()
|
-- local unit = group:GetUnit(1)
|
||||||
|
-- local name = unit:GetName()
|
||||||
-- autolaser:SetRecceLaserCode(name,1688)
|
-- autolaser:SetRecceLaserCode(name,1688)
|
||||||
-- end
|
-- end
|
||||||
-- )
|
-- )
|
||||||
@ -107,7 +108,7 @@ AUTOLASE = {
|
|||||||
|
|
||||||
--- AUTOLASE class version.
|
--- AUTOLASE class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AUTOLASE.version = "0.0.3"
|
AUTOLASE.version = "0.0.4"
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
-- Begin Functional.Autolase.lua
|
-- Begin Functional.Autolase.lua
|
||||||
@ -179,6 +180,8 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet)
|
|||||||
self.smoketargets = false
|
self.smoketargets = false
|
||||||
self.smokecolor = SMOKECOLOR.Red
|
self.smokecolor = SMOKECOLOR.Red
|
||||||
self.notifypilots = true
|
self.notifypilots = true
|
||||||
|
--self.statusupdate = -28 -- for #INTEL
|
||||||
|
self.targetsperrecce = {}
|
||||||
|
|
||||||
-- Set some string id for output to DCS.log file.
|
-- Set some string id for output to DCS.log file.
|
||||||
self.lid=string.format("AUTOLASE %s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown")
|
self.lid=string.format("AUTOLASE %s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown")
|
||||||
@ -308,7 +311,7 @@ end
|
|||||||
|
|
||||||
--- Function to get a laser code by recce name
|
--- Function to get a laser code by recce name
|
||||||
-- @param #AUTOLASE self
|
-- @param #AUTOLASE self
|
||||||
-- @param #string RecceName Name of the Recce
|
-- @param #string RecceName Unit(!) name of the Recce
|
||||||
-- @return #AUTOLASE self
|
-- @return #AUTOLASE self
|
||||||
function AUTOLASE:GetLaserCode(RecceName)
|
function AUTOLASE:GetLaserCode(RecceName)
|
||||||
local code = 1688
|
local code = 1688
|
||||||
@ -341,7 +344,7 @@ end
|
|||||||
|
|
||||||
--- (User) Function to set a specific code to a Recce.
|
--- (User) Function to set a specific code to a Recce.
|
||||||
-- @param #AUTOLASE self
|
-- @param #AUTOLASE self
|
||||||
-- @param #string RecceName Name of the Recce
|
-- @param #string RecceName (Unit!) Name of the Recce
|
||||||
-- @param #number Code The lase code
|
-- @param #number Code The lase code
|
||||||
-- @return #AUTOLASE self
|
-- @return #AUTOLASE self
|
||||||
function AUTOLASE:SetRecceLaserCode(RecceName, Code)
|
function AUTOLASE:SetRecceLaserCode(RecceName, Code)
|
||||||
@ -367,8 +370,8 @@ end
|
|||||||
-- @param #number Duration (Max) duration for lasing in seconds
|
-- @param #number Duration (Max) duration for lasing in seconds
|
||||||
-- @return #AUTOLASE self
|
-- @return #AUTOLASE self
|
||||||
function AUTOLASE:SetLasingParameters(Distance, Duration)
|
function AUTOLASE:SetLasingParameters(Distance, Duration)
|
||||||
self.LaseDistance = distance or 4000
|
self.LaseDistance = Distance or 5000
|
||||||
self.LaseDuration = duration or 120
|
self.LaseDuration = Duration or 300
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -383,14 +386,40 @@ function AUTOLASE:SetSmokeTargets(OnOff,Color)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to calculate line of sight.
|
||||||
|
-- @param #AUTOLASE self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit
|
||||||
|
-- @return #number LOS Line of sight in meters
|
||||||
|
function AUTOLASE:GetLosFromUnit(Unit)
|
||||||
|
local lasedistance = self.LaseDistance
|
||||||
|
local unitheight = Unit:GetHeight()
|
||||||
|
local coord = Unit:GetCoordinate()
|
||||||
|
local landheight = coord:GetLandHeight()
|
||||||
|
local asl = unitheight - landheight
|
||||||
|
if asl > 100 then
|
||||||
|
local absquare = lasedistance^2+asl^2
|
||||||
|
lasedistance = math.sqrt(absquare)
|
||||||
|
end
|
||||||
|
--self:I({lasedistance=lasedistance})
|
||||||
|
return lasedistance
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Function to check on lased targets.
|
--- (Internal) Function to check on lased targets.
|
||||||
-- @param #AUTOLASE self
|
-- @param #AUTOLASE self
|
||||||
-- @return #AUTOLASE self
|
-- @return #AUTOLASE self
|
||||||
function AUTOLASE:CleanCurrentLasing()
|
function AUTOLASE:CleanCurrentLasing()
|
||||||
local lasingtable = self.CurrentLasing
|
local lasingtable = self.CurrentLasing
|
||||||
local newtable = {}
|
local newtable = {}
|
||||||
|
local newreccecount = {}
|
||||||
local lasing = 0
|
local lasing = 0
|
||||||
|
|
||||||
|
for _ind,_entry in pairs(lasingtable) do
|
||||||
|
local entry = _entry -- #AUTOLASE.LaserSpot
|
||||||
|
if not newreccecount[entry.reccename] then
|
||||||
|
newreccecount[entry.reccename] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
for _ind,_entry in pairs(lasingtable) do
|
for _ind,_entry in pairs(lasingtable) do
|
||||||
local entry = _entry -- #AUTOLASE.LaserSpot
|
local entry = _entry -- #AUTOLASE.LaserSpot
|
||||||
local valid = 0
|
local valid = 0
|
||||||
@ -425,8 +454,9 @@ function AUTOLASE:CleanCurrentLasing()
|
|||||||
if not reccedead and not unitdead then
|
if not reccedead and not unitdead then
|
||||||
local coord = unit:GetCoordinate() -- Core.Point#COORDINATE
|
local coord = unit:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
local coord2 = recce:GetCoordinate() -- Core.Point#COORDINATE
|
local coord2 = recce:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
local dist = coord2:Get2DDistance(coord)
|
local dist = coord2:Get3DDistance(coord)
|
||||||
if dist <= self.LaseDistance then
|
local lasedistance = self:GetLosFromUnit(recce)
|
||||||
|
if dist <= lasedistance then
|
||||||
valid = valid + 1
|
valid = valid + 1
|
||||||
else
|
else
|
||||||
lostsight = true
|
lostsight = true
|
||||||
@ -450,10 +480,13 @@ function AUTOLASE:CleanCurrentLasing()
|
|||||||
if valid == 4 then
|
if valid == 4 then
|
||||||
self.lasingindex = self.lasingindex + 1
|
self.lasingindex = self.lasingindex + 1
|
||||||
newtable[self.lasingindex] = entry
|
newtable[self.lasingindex] = entry
|
||||||
|
newreccecount[entry.reccename] = newreccecount[entry.reccename] + 1
|
||||||
lasing = lasing + 1
|
lasing = lasing + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.CurrentLasing = newtable
|
self.CurrentLasing = newtable
|
||||||
|
self.targetsperrecce = newreccecount
|
||||||
|
--self:I({newreccecount})
|
||||||
return lasing
|
return lasing
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -507,13 +540,43 @@ function AUTOLASE:NotifyPilots(Message,Duration)
|
|||||||
else
|
else
|
||||||
local m = MESSAGE:New(Message,Duration,"Autolase"):ToAll()
|
local m = MESSAGE:New(Message,Duration,"Autolase"):ToAll()
|
||||||
end
|
end
|
||||||
|
if self.debug then self:I(Message) end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to check if a unit is already lased.
|
||||||
|
-- @param #AUTOLASE self
|
||||||
|
-- @param #string unitname Name of the unit to check
|
||||||
|
-- @return #boolean outcome True or false
|
||||||
|
function AUTOLASE:CheckIsLased(unitname)
|
||||||
|
local outcome = false
|
||||||
|
for _,_laserspot in pairs(self.CurrentLasing) do
|
||||||
|
local spot = _laserspot -- #AUTOLASE.LaserSpot
|
||||||
|
if spot.unitname == unitname then
|
||||||
|
outcome = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return outcome
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
-- FSM Functions
|
-- FSM Functions
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- (Internal) FSM Function for monitoring
|
||||||
|
-- @param #AUTOLASE self
|
||||||
|
-- @param #string From The from state
|
||||||
|
-- @param #string Event The event
|
||||||
|
-- @param #string To The to state
|
||||||
|
-- @return #AUTOLASE self
|
||||||
|
function AUTOLASE:onbeforeMonitor(From, Event, To)
|
||||||
|
self:T({From, Event, To})
|
||||||
|
-- Check if group has detected any units.
|
||||||
|
self:UpdateIntel()
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) FSM Function for monitoring
|
--- (Internal) FSM Function for monitoring
|
||||||
-- @param #AUTOLASE self
|
-- @param #AUTOLASE self
|
||||||
-- @param #string From The from state
|
-- @param #string From The from state
|
||||||
@ -522,7 +585,7 @@ end
|
|||||||
-- @return #AUTOLASE self
|
-- @return #AUTOLASE self
|
||||||
function AUTOLASE:onafterMonitor(From, Event, To)
|
function AUTOLASE:onafterMonitor(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
|
|
||||||
-- Housekeeping
|
-- Housekeeping
|
||||||
local countlases = self:CleanCurrentLasing()
|
local countlases = self:CleanCurrentLasing()
|
||||||
|
|
||||||
@ -541,13 +604,15 @@ function AUTOLASE:onafterMonitor(From, Event, To)
|
|||||||
local reccename = contact.recce
|
local reccename = contact.recce
|
||||||
local reccegrp = UNIT:FindByName(reccename)
|
local reccegrp = UNIT:FindByName(reccename)
|
||||||
local reccecoord = reccegrp:GetCoordinate()
|
local reccecoord = reccegrp:GetCoordinate()
|
||||||
local distance = math.floor(reccecoord:Get2DDistance(coord))
|
local distance = math.floor(reccecoord:Get3DDistance(coord))
|
||||||
local text = string.format("%s of %s | Distance %d km | Threatlevel %d",contact.attribute, contact.groupname, distance/ 1000, contact.threatlevel)
|
local text = string.format("%s of %s | Distance %d km | Threatlevel %d",contact.attribute, contact.groupname, math.floor(distance/1000), contact.threatlevel)
|
||||||
report:Add(text)
|
report:Add(text)
|
||||||
self:T(text)
|
self:T(text)
|
||||||
|
if self.debug then self:I(text) end
|
||||||
lines = lines + 1
|
lines = lines + 1
|
||||||
-- sort out groups beyond sight
|
-- sort out groups beyond sight
|
||||||
if distance <= self.LaseDistance then
|
local lasedistance = self:GetLosFromUnit(reccegrp)
|
||||||
|
if grp:IsGround() and lasedistance >= distance then
|
||||||
table.insert(groupsbythreat,{contact.group,contact.threatlevel})
|
table.insert(groupsbythreat,{contact.group,contact.threatlevel})
|
||||||
self.RecceNames[contact.groupname] = contact.recce
|
self.RecceNames[contact.groupname] = contact.recce
|
||||||
end
|
end
|
||||||
@ -565,20 +630,24 @@ function AUTOLASE:onafterMonitor(From, Event, To)
|
|||||||
return aNum > bNum -- Return their comparisons, < for ascending, > for descending
|
return aNum > bNum -- Return their comparisons, < for ascending, > for descending
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--self:T("Groups by Threat")
|
-- self:T("Groups by Threat")
|
||||||
--self:T({self.GroupsByThreat})
|
--self:T({self.GroupsByThreat})
|
||||||
|
|
||||||
-- build table of Units
|
-- build table of Units
|
||||||
local unitsbythreat = {}
|
local unitsbythreat = {}
|
||||||
for _,_entry in ipairs(self.GroupsByThreat) do
|
for _,_entry in pairs(self.GroupsByThreat) do
|
||||||
local group = _entry[1] -- Wrapper.Group#GROUP
|
local group = _entry[1] -- Wrapper.Group#GROUP
|
||||||
if group and group:IsAlive() then
|
if group and group:IsAlive() then
|
||||||
local units = group:GetUnits()
|
local units = group:GetUnits()
|
||||||
local reccename = self.RecceNames[group:GetName()]
|
local reccename = self.RecceNames[group:GetName()]
|
||||||
|
--local recceunit UNIT:FindByName(reccename)
|
||||||
|
--local reccecoord = recceunit:GetCoordinate()
|
||||||
for _,_unit in pairs(units) do
|
for _,_unit in pairs(units) do
|
||||||
local unit = _unit -- Wrapper.Unit#UNIT
|
local unit = _unit -- Wrapper.Unit#UNIT
|
||||||
if unit and unit:IsAlive() then
|
if unit and unit:IsAlive() then
|
||||||
local threat = unit:GetThreatLevel()
|
local threat = unit:GetThreatLevel()
|
||||||
|
local coord = unit:GetCoordinate()
|
||||||
|
--local distance = math.floor(reccecoord:Get3DDistance(coord))
|
||||||
if threat > 0 then
|
if threat > 0 then
|
||||||
local unitname = unit:GetName()
|
local unitname = unit:GetName()
|
||||||
table.insert(unitsbythreat,{unit,threat})
|
table.insert(unitsbythreat,{unit,threat})
|
||||||
@ -597,10 +666,13 @@ function AUTOLASE:onafterMonitor(From, Event, To)
|
|||||||
return aNum > bNum -- Return their comparisons, < for ascending, > for descending
|
return aNum > bNum -- Return their comparisons, < for ascending, > for descending
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- self:I("Units by Threat")
|
||||||
|
-- self:I({self.UnitsByThreat})
|
||||||
|
|
||||||
local unitreport = REPORT:New("Detected Units")
|
local unitreport = REPORT:New("Detected Units")
|
||||||
|
|
||||||
local lines = 0
|
local lines = 0
|
||||||
for _,_entry in ipairs(self.UnitsByThreat) do
|
for _,_entry in pairs(self.UnitsByThreat) do
|
||||||
local threat = _entry[2]
|
local threat = _entry[2]
|
||||||
local unit = _entry[1]
|
local unit = _entry[1]
|
||||||
local unitname = unit:GetName()
|
local unitname = unit:GetName()
|
||||||
@ -608,6 +680,7 @@ function AUTOLASE:onafterMonitor(From, Event, To)
|
|||||||
unitreport:Add(text)
|
unitreport:Add(text)
|
||||||
lines = lines + 1
|
lines = lines + 1
|
||||||
self:T(text)
|
self:T(text)
|
||||||
|
if self.debug then self:I(text) end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.verbose > 2 and lines > 0 then
|
if self.verbose > 2 and lines > 0 then
|
||||||
@ -621,8 +694,10 @@ function AUTOLASE:onafterMonitor(From, Event, To)
|
|||||||
local unitname = unit:GetName()
|
local unitname = unit:GetName()
|
||||||
local reccename = self.RecceUnitNames[unitname]
|
local reccename = self.RecceUnitNames[unitname]
|
||||||
local recce = UNIT:FindByName(reccename)
|
local recce = UNIT:FindByName(reccename)
|
||||||
if targets < self.maxlasing and unit:IsAlive() == true then
|
local reccecount = self.targetsperrecce[reccename] or 0
|
||||||
|
if (targets < self.maxlasing or reccecount < targets) and not self:CheckIsLased(unitname) and unit:IsAlive() == true then
|
||||||
targets = targets + 1
|
targets = targets + 1
|
||||||
|
self.targetsperrecce[reccename] = reccecount + 1
|
||||||
local code = self:GetLaserCode(reccename)
|
local code = self:GetLaserCode(reccename)
|
||||||
local spot = SPOT:New(recce)
|
local spot = SPOT:New(recce)
|
||||||
spot:LaseOn(unit,code,self.LaseDuration)
|
spot:LaseOn(unit,code,self.LaseDuration)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user