mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Ops
This commit is contained in:
@@ -966,7 +966,7 @@ function AIRWING:CheckTANKER()
|
||||
|
||||
local altitude=patrol.altitude+1000*patrol.noccupied
|
||||
|
||||
local mission=AUFTRAG:NewTANKER(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg, 0)
|
||||
local mission=AUFTRAG:NewTANKER(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg, 1)
|
||||
|
||||
mission.patroldata=patrol
|
||||
|
||||
@@ -984,7 +984,7 @@ function AIRWING:CheckTANKER()
|
||||
|
||||
local altitude=patrol.altitude+1000*patrol.noccupied
|
||||
|
||||
local mission=AUFTRAG:NewTANKER(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg, 1)
|
||||
local mission=AUFTRAG:NewTANKER(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg, 0)
|
||||
|
||||
mission.patroldata=patrol
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
-- * [F-14A/B Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI)
|
||||
-- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI)
|
||||
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI) [**WIP**]
|
||||
-- * [T-45C Goshawk (VNAO)(Player & AI)]
|
||||
-- * F/A-18C Hornet (AI)
|
||||
-- * F-14A Tomcat (AI)
|
||||
-- * E-2D Hawkeye (AI)
|
||||
@@ -1271,6 +1272,7 @@ AIRBOSS.AircraftCarrier={
|
||||
F14B="F-14B",
|
||||
F14A_AI="F-14A",
|
||||
FA18C="F/A-18C",
|
||||
T45C="T-45",
|
||||
S3B="S-3B",
|
||||
S3BTANKER="S-3B Tanker",
|
||||
E2D="E-2C",
|
||||
@@ -1705,7 +1707,7 @@ AIRBOSS.MenuF10Root=nil
|
||||
|
||||
--- Airboss class version.
|
||||
-- @field #string version
|
||||
AIRBOSS.version="1.1.5"
|
||||
AIRBOSS.version="1.1.6"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -1939,7 +1941,7 @@ function AIRBOSS:New(carriername, alias)
|
||||
|
||||
-- Welcome players.
|
||||
self:SetWelcomePlayers(true)
|
||||
|
||||
|
||||
-- Coordinates
|
||||
self.landingcoord=COORDINATE:New(0,0,0) --Core.Point#COORDINATE
|
||||
self.sterncoord=COORDINATE:New(0, 0, 0) --Core.Point#COORDINATE
|
||||
@@ -1951,11 +1953,11 @@ function AIRBOSS:New(carriername, alias)
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.ROOSEVELT then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.LINCOLN then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.WASHINGTON then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.TRUMAN then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.WASHINGTON then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.TRUMAN then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.VINSON then
|
||||
-- TODO: Carl Vinson parameters.
|
||||
self:_InitStennis()
|
||||
@@ -1993,7 +1995,7 @@ function AIRBOSS:New(carriername, alias)
|
||||
self:_GetZoneGroove():SmokeZone(SMOKECOLOR.Red, 5)
|
||||
self:_GetZoneLineup():SmokeZone(SMOKECOLOR.Green, 5)
|
||||
self:_GetZoneBullseye(case):SmokeZone(SMOKECOLOR.White, 45)
|
||||
self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45)
|
||||
self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45)
|
||||
self:_GetZoneArcIn(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
||||
self:_GetZoneArcOut(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
||||
self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
||||
@@ -2033,7 +2035,7 @@ function AIRBOSS:New(carriername, alias)
|
||||
|
||||
-- Bow
|
||||
bow:FlareYellow()
|
||||
|
||||
|
||||
-- Runway half width = 10 m.
|
||||
local r1=stern:Translate(self.carrierparam.rwywidth*0.5, FB+90)
|
||||
local r2=stern:Translate(self.carrierparam.rwywidth*0.5, FB-90)
|
||||
@@ -2646,6 +2648,15 @@ function AIRBOSS:SetRecoveryTurnTime(interval)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set multiplayer environment wire correction.
|
||||
-- @param #AIRBOSS self
|
||||
-- @param #number Dcorr Correction distance in meters. Default 8.7 m.
|
||||
-- @return #AIRBOSS self
|
||||
function AIRBOSS:SetMPWireCorrection(Dcorr)
|
||||
self.mpWireCorrection=Dcorr or 8.7
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set time interval for updating queues and other stuff.
|
||||
-- @param #AIRBOSS self
|
||||
-- @param #number interval Time interval in seconds. Default 30 sec.
|
||||
@@ -3284,7 +3295,7 @@ function AIRBOSS:GetNextRecoveryTime(InSeconds)
|
||||
if InSeconds then
|
||||
return self.recoverywindow.START, self.recoverywindow.STOP
|
||||
else
|
||||
return UTILS.SecondsToClock(self.recoverywindow.START), UTILS.SecondsToClock(self.recoverywindow.STOP)
|
||||
return UTILS.SecondsToClock(self.recoverywindow.START), UTILS.SecondsToClock(self.recoverywindow.STOP)
|
||||
end
|
||||
else
|
||||
if InSeconds then
|
||||
@@ -3398,7 +3409,7 @@ function AIRBOSS:onafterStart(From, Event, To)
|
||||
|
||||
--self.StatusScheduler=SCHEDULER:New(self)
|
||||
--self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5)
|
||||
|
||||
|
||||
self.StatusTimer=TIMER:New(self._Status, self):Start(2, 0.5)
|
||||
|
||||
-- Start status check in 1 second.
|
||||
@@ -3484,9 +3495,9 @@ function AIRBOSS:onafterStatus(From, Event, To)
|
||||
-- Disable turn into the wind for this window so that we do not do this all over again.
|
||||
self.recoverywindow.WIND=false
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -3582,9 +3593,9 @@ function AIRBOSS:_CheckAIStatus()
|
||||
|
||||
-- Get lineup and distance to carrier.
|
||||
local lineup=self:_Lineup(unit, true)
|
||||
|
||||
|
||||
local unitcoord=unit:GetCoord()
|
||||
|
||||
|
||||
local dist=unitcoord:Get2DDistance(self:GetCoord())
|
||||
|
||||
-- Distance in NM.
|
||||
@@ -4145,7 +4156,7 @@ end
|
||||
-- @param #string To To state.
|
||||
function AIRBOSS:onafterStop(From, Event, To)
|
||||
self:I(self.lid..string.format("Stopping airboss script."))
|
||||
|
||||
|
||||
-- Unhandle events.
|
||||
self:UnHandleEvent(EVENTS.Birth)
|
||||
self:UnHandleEvent(EVENTS.Land)
|
||||
@@ -4169,7 +4180,7 @@ function AIRBOSS:_InitStennis()
|
||||
|
||||
-- Carrier Parameters.
|
||||
self.carrierparam.sterndist =-153
|
||||
self.carrierparam.deckheight = 19
|
||||
self.carrierparam.deckheight = 19.06
|
||||
|
||||
-- Total size of the carrier (approx as rectangle).
|
||||
self.carrierparam.totlength=310 -- Wiki says 332.8 meters overall length.
|
||||
@@ -4177,7 +4188,7 @@ function AIRBOSS:_InitStennis()
|
||||
self.carrierparam.totwidthstarboard=30
|
||||
|
||||
-- Landing runway.
|
||||
self.carrierparam.rwyangle = -9
|
||||
self.carrierparam.rwyangle = -9.1359
|
||||
self.carrierparam.rwylength = 225
|
||||
self.carrierparam.rwywidth = 20
|
||||
|
||||
@@ -4320,7 +4331,7 @@ function AIRBOSS:_InitNimitz()
|
||||
|
||||
-- Carrier Parameters.
|
||||
self.carrierparam.sterndist =-164
|
||||
self.carrierparam.deckheight = 20
|
||||
self.carrierparam.deckheight = 20.1494 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\Database\USS_CVN_7X.lua
|
||||
|
||||
-- Total size of the carrier (approx as rectangle).
|
||||
self.carrierparam.totlength=332.8 -- Wiki says 332.8 meters overall length.
|
||||
@@ -4328,7 +4339,7 @@ function AIRBOSS:_InitNimitz()
|
||||
self.carrierparam.totwidthstarboard=35
|
||||
|
||||
-- Landing runway.
|
||||
self.carrierparam.rwyangle = -9
|
||||
self.carrierparam.rwyangle = -9.1359 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\scripts\USS_Nimitz_RunwaysAndRoutes.lua
|
||||
self.carrierparam.rwylength = 250
|
||||
self.carrierparam.rwywidth = 25
|
||||
|
||||
@@ -5471,6 +5482,7 @@ function AIRBOSS:_GetAircraftAoA(playerData)
|
||||
|
||||
-- Get AC type.
|
||||
local hornet=playerData.actype==AIRBOSS.AircraftCarrier.HORNET
|
||||
local goshawk=playerData.actype==AIRBOSS.AircraftCarrier.T45C
|
||||
local skyhawk=playerData.actype==AIRBOSS.AircraftCarrier.A4EC
|
||||
local harrier=playerData.actype==AIRBOSS.AircraftCarrier.AV8B
|
||||
local tomcat=playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B
|
||||
@@ -5497,6 +5509,15 @@ function AIRBOSS:_GetAircraftAoA(playerData)
|
||||
aoa.OnSpeedMin = self:_AoAUnit2Deg(playerData, 14.5) --14.17 --14.5 units
|
||||
aoa.Fast = self:_AoAUnit2Deg(playerData, 14.0) --13.33 --14.0 units
|
||||
aoa.FAST = self:_AoAUnit2Deg(playerData, 13.0) --11.67 --13.0 units
|
||||
elseif goshawk then
|
||||
-- T-45C Goshawk parameters.
|
||||
aoa.SLOW = 8.00 --19
|
||||
aoa.Slow = 7.75 --18
|
||||
aoa.OnSpeedMax = 7.25 --17.5
|
||||
aoa.OnSpeed = 7.00 --17
|
||||
aoa.OnSpeedMin = 6.75 --16.5
|
||||
aoa.Fast = 6.25 --16
|
||||
aoa.FAST = 6.00 --15
|
||||
elseif skyhawk then
|
||||
-- A-4E-C Skyhawk parameters from https://forums.eagle.ru/showpost.php?p=3703467&postcount=390
|
||||
-- Note that these are arbitrary UNITS and not degrees. We need a conversion formula!
|
||||
@@ -5681,6 +5702,9 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
elseif skyhawk then
|
||||
alt=UTILS.FeetToMeters(600)
|
||||
speed=UTILS.KnotsToMps(250)
|
||||
elseif goshawk then
|
||||
alt=UTILS.FeetToMeters(800)
|
||||
speed=UTILS.KnotsToMps(300)
|
||||
end
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.BREAKENTRY then
|
||||
@@ -5691,11 +5715,14 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
elseif skyhawk then
|
||||
alt=UTILS.FeetToMeters(600)
|
||||
speed=UTILS.KnotsToMps(250)
|
||||
elseif goshawk then
|
||||
alt=UTILS.FeetToMeters(800)
|
||||
speed=UTILS.KnotsToMps(300)
|
||||
end
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.EARLYBREAK then
|
||||
|
||||
if hornet or tomcat or harrier then
|
||||
if hornet or tomcat or harrier or goshawk then
|
||||
alt=UTILS.FeetToMeters(800)
|
||||
elseif skyhawk then
|
||||
alt=UTILS.FeetToMeters(600)
|
||||
@@ -5703,7 +5730,7 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.LATEBREAK then
|
||||
|
||||
if hornet or tomcat or harrier then
|
||||
if hornet or tomcat or harrier or goshawk then
|
||||
alt=UTILS.FeetToMeters(800)
|
||||
elseif skyhawk then
|
||||
alt=UTILS.FeetToMeters(600)
|
||||
@@ -5711,7 +5738,7 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.ABEAM then
|
||||
|
||||
if hornet or tomcat or harrier then
|
||||
if hornet or tomcat or harrier or goshawk then
|
||||
alt=UTILS.FeetToMeters(600)
|
||||
elseif skyhawk then
|
||||
alt=UTILS.FeetToMeters(500)
|
||||
@@ -5726,10 +5753,19 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
dist=UTILS.NMToMeters(1.2)
|
||||
end
|
||||
|
||||
if goshawk then
|
||||
-- 0.9 to 1.1 NM per natops ch.4 page 48
|
||||
dist=UTILS.NMToMeters(0.9)
|
||||
else
|
||||
dist=UTILS.NMToMeters(1.1)
|
||||
end
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.NINETY then
|
||||
|
||||
if hornet or tomcat then
|
||||
alt=UTILS.FeetToMeters(500)
|
||||
elseif goshawk then
|
||||
alt=UTILS.FeetToMeters(450)
|
||||
elseif skyhawk then
|
||||
alt=UTILS.FeetToMeters(500)
|
||||
elseif harrier then
|
||||
@@ -5740,7 +5776,7 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.WAKE then
|
||||
|
||||
if hornet then
|
||||
if hornet or goshawk then
|
||||
alt=UTILS.FeetToMeters(370)
|
||||
elseif tomcat then
|
||||
alt=UTILS.FeetToMeters(430) -- Tomcat should be a bit higher as it intercepts the GS a bit higher.
|
||||
@@ -5753,7 +5789,7 @@ function AIRBOSS:_GetAircraftParameters(playerData, step)
|
||||
|
||||
elseif step==AIRBOSS.PatternStep.FINAL then
|
||||
|
||||
if hornet then
|
||||
if hornet or goshawk then
|
||||
alt=UTILS.FeetToMeters(300)
|
||||
elseif tomcat then
|
||||
alt=UTILS.FeetToMeters(360)
|
||||
@@ -6086,7 +6122,7 @@ function AIRBOSS:_ScanCarrierZone()
|
||||
|
||||
-- Get flight group.
|
||||
local flight=_DATABASE:GetFlightGroup(groupname)
|
||||
|
||||
|
||||
if flight and flight:IsInbound() and flight.destbase:GetName()==self.carrier:GetName() then
|
||||
if flight.ishelo then
|
||||
else
|
||||
@@ -6123,7 +6159,7 @@ function AIRBOSS:_ScanCarrierZone()
|
||||
-- Break the loop to not have all flights at once! Spams the message screen.
|
||||
break
|
||||
|
||||
end -- Closed in or tanker/AWACS
|
||||
end -- Closed in or tanker/AWACS
|
||||
|
||||
end
|
||||
|
||||
@@ -6229,7 +6265,7 @@ function AIRBOSS:_MarshalPlayer(playerData, stack)
|
||||
|
||||
-- Set stack flag.
|
||||
flight.flag=stack
|
||||
|
||||
|
||||
-- Trigger Marshal event.
|
||||
self:Marshal(flight)
|
||||
end
|
||||
@@ -6488,7 +6524,7 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn)
|
||||
|
||||
-- Route group.
|
||||
flight.group:Route(wp, 1)
|
||||
|
||||
|
||||
-- Trigger Marshal event.
|
||||
self:Marshal(flight)
|
||||
|
||||
@@ -7024,7 +7060,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
|
||||
|
||||
-- Recovery case.
|
||||
case=case or self.case
|
||||
|
||||
|
||||
if case==1 then
|
||||
return self:_GetFreeStack_Old(ai, case, empty)
|
||||
end
|
||||
@@ -7040,7 +7076,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
|
||||
for i=1,nmaxstacks do
|
||||
stack[i]=self.NmaxStack -- Number of human flights per stack.
|
||||
end
|
||||
|
||||
|
||||
local nmax=1
|
||||
|
||||
-- Loop over all flights in marshal stack.
|
||||
@@ -7052,7 +7088,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
|
||||
|
||||
-- Get stack of flight.
|
||||
local n=flight.flag
|
||||
|
||||
|
||||
if n>nmax then
|
||||
nmax=n
|
||||
end
|
||||
@@ -7069,7 +7105,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local nfree=nil
|
||||
if stack[nmax]==0 then
|
||||
-- Max occupied stack is completely full!
|
||||
@@ -7085,7 +7121,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
|
||||
-- Case II/III return next stack
|
||||
nfree=nmax+1
|
||||
end
|
||||
|
||||
|
||||
elseif stack[nmax]==self.NmaxStack then
|
||||
-- Max occupied stack is completely empty! This should happen only when there is no other flight in the marshal queue.
|
||||
self:E(self.lid..string.format("ERROR: Max occupied stack is empty. Should not happen! Nmax=%d, stack[nmax]=%d", nmax, stack[nmax]))
|
||||
@@ -7097,7 +7133,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
|
||||
else
|
||||
nfree=nmax
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
self:I(self.lid..string.format("Returning free stack %s", tostring(nfree)))
|
||||
@@ -10370,7 +10406,7 @@ function AIRBOSS:_GetSternCoord()
|
||||
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(7, FB+90, true, true)
|
||||
else
|
||||
-- Nimitz SC: translate 8 meters starboard wrt Final bearing.
|
||||
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(8.5, FB+90, true, true)
|
||||
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(9.5, FB+90, true, true)
|
||||
end
|
||||
|
||||
-- Set altitude.
|
||||
@@ -10400,6 +10436,11 @@ function AIRBOSS:_GetWire(Lcoord, dc)
|
||||
|
||||
-- Corrected landing distance wrt to stern. Landing distance needs to be reduced due to delayed landing event for human players.
|
||||
local d=Ldist-dc
|
||||
|
||||
-- Multiplayer wire correction.
|
||||
if self.mpWireCorrection then
|
||||
d=d-self.mpWireCorrection
|
||||
end
|
||||
|
||||
-- Shift wires from stern to their correct position.
|
||||
local w1=self.carrierparam.wire1
|
||||
@@ -10491,6 +10532,9 @@ function AIRBOSS:_Trapped(playerData)
|
||||
elseif playerData.actype==AIRBOSS.AircraftCarrier.A4EC then
|
||||
-- A-4E gets slowed down much faster the the F/A-18C!
|
||||
dcorr=56
|
||||
elseif playerData.actype==AIRBOSS.AircraftCarrier.T45C then
|
||||
-- T-45 also gets slowed down much faster the the F/A-18C.
|
||||
dcorr=56
|
||||
end
|
||||
|
||||
-- Get wire.
|
||||
@@ -10617,7 +10661,7 @@ function AIRBOSS:_GetZoneInitial(case)
|
||||
|
||||
-- Polygon zone.
|
||||
--local zone=ZONE_POLYGON_BASE:New("Zone CASE I/II Initial", vec2)
|
||||
|
||||
|
||||
self.zoneInitial:UpdateFromVec2(vec2)
|
||||
|
||||
--return zone
|
||||
@@ -10646,13 +10690,13 @@ function AIRBOSS:_GetZoneLineup()
|
||||
|
||||
-- Vec2 array.
|
||||
local vec2={c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2()}
|
||||
|
||||
|
||||
self.zoneLineup:UpdateFromVec2(vec2)
|
||||
|
||||
-- Polygon zone.
|
||||
--local zone=ZONE_POLYGON_BASE:New("Zone Lineup", vec2)
|
||||
--return zone
|
||||
|
||||
|
||||
return self.zoneLineup
|
||||
end
|
||||
|
||||
@@ -10687,13 +10731,13 @@ function AIRBOSS:_GetZoneGroove(l, w, b)
|
||||
|
||||
-- Vec2 array.
|
||||
local vec2={c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2(), c6:GetVec2()}
|
||||
|
||||
|
||||
self.zoneGroove:UpdateFromVec2(vec2)
|
||||
|
||||
-- Polygon zone.
|
||||
--local zone=ZONE_POLYGON_BASE:New("Zone Groove", vec2)
|
||||
--return zone
|
||||
|
||||
|
||||
return self.zoneGroove
|
||||
end
|
||||
|
||||
@@ -10719,7 +10763,7 @@ function AIRBOSS:_GetZoneBullseye(case)
|
||||
-- Create zone.
|
||||
local zone=ZONE_RADIUS:New("Zone Bullseye", vec2, radius)
|
||||
return zone
|
||||
|
||||
|
||||
--self.zoneBullseye=self.zoneBullseye or ZONE_RADIUS:New("Zone Bullseye", vec2, radius)
|
||||
end
|
||||
|
||||
@@ -10948,9 +10992,9 @@ function AIRBOSS:_GetZoneCarrierBox()
|
||||
-- Create polygon zone.
|
||||
--local zone=ZONE_POLYGON_BASE:New("Carrier Box Zone", vec2)
|
||||
--return zone
|
||||
|
||||
|
||||
self.zoneCarrierbox:UpdateFromVec2(vec2)
|
||||
|
||||
|
||||
return self.zoneCarrierbox
|
||||
end
|
||||
|
||||
@@ -10985,9 +11029,9 @@ function AIRBOSS:_GetZoneRunwayBox()
|
||||
-- Create polygon zone.
|
||||
--local zone=ZONE_POLYGON_BASE:New("Landing Runway Zone", vec2)
|
||||
--return zone
|
||||
|
||||
|
||||
self.zoneRunwaybox:UpdateFromVec2(vec2)
|
||||
|
||||
|
||||
return self.zoneRunwaybox
|
||||
end
|
||||
|
||||
@@ -11118,7 +11162,7 @@ function AIRBOSS:_GetZoneHolding(case, stack)
|
||||
-- Square zone length=7NM width=6 NM behind the carrier starting at angels+15 NM behind the carrier.
|
||||
-- So stay 0-5 NM (+1 NM error margin) port of carrier.
|
||||
self.zoneHolding=self.zoneHolding or ZONE_POLYGON_BASE:New("CASE II/III Holding Zone")
|
||||
|
||||
|
||||
self.zoneHolding:UpdateFromVec2(p)
|
||||
end
|
||||
|
||||
@@ -11164,12 +11208,12 @@ function AIRBOSS:_GetZoneCommence(case, stack)
|
||||
|
||||
-- Create holding zone.
|
||||
self.zoneCommence=self.zoneCommence or ZONE_RADIUS:New("CASE I Commence Zone")
|
||||
|
||||
|
||||
self.zoneCommence:UpdateFromVec2(Three:GetVec2(), R)
|
||||
|
||||
else
|
||||
-- Case II/III
|
||||
|
||||
|
||||
stack=stack or 1
|
||||
|
||||
-- Start point at 21 NM for stack=1.
|
||||
@@ -11197,7 +11241,7 @@ function AIRBOSS:_GetZoneCommence(case, stack)
|
||||
|
||||
-- Zone polygon.
|
||||
self.zoneCommence=self.zoneCommence or ZONE_POLYGON_BASE:New("CASE II/III Commence Zone")
|
||||
|
||||
|
||||
self.zoneCommence:UpdateFromVec2(p)
|
||||
|
||||
end
|
||||
@@ -11445,7 +11489,7 @@ end
|
||||
-- @param #AIRBOSS self
|
||||
-- @return Core.Point#COORDINATE Optimal landing coordinate.
|
||||
function AIRBOSS:_GetOptLandingCoordinate()
|
||||
|
||||
|
||||
-- Start with stern coordiante.
|
||||
self.landingcoord:UpdateFromCoordinate(self:_GetSternCoord())
|
||||
|
||||
@@ -12001,15 +12045,15 @@ function AIRBOSS:_EvalGrooveTime(playerData)
|
||||
|
||||
local grade=""
|
||||
if t<9 then
|
||||
grade="--"
|
||||
elseif t<12 then
|
||||
grade="(OK)"
|
||||
elseif t<22 then
|
||||
grade="OK"
|
||||
grade="_NESA_"
|
||||
elseif t<15 then
|
||||
grade="NESA"
|
||||
elseif t<19 then
|
||||
grade="OK Groove"
|
||||
elseif t<=24 then
|
||||
grade="(OK)"
|
||||
grade="(LIG)"
|
||||
else
|
||||
grade="--"
|
||||
grade="LIG"
|
||||
end
|
||||
|
||||
-- The unicorn!
|
||||
@@ -12050,7 +12094,7 @@ function AIRBOSS:_LSOgrade(playerData)
|
||||
|
||||
-- Groove time 16-18 sec for a unicorn.
|
||||
local Tgroove=playerData.Tgroove
|
||||
local TgrooveUnicorn=Tgroove and (Tgroove>=16.0 and Tgroove<=18.0) or false
|
||||
local TgrooveUnicorn=Tgroove and (Tgroove>=15.0 and Tgroove<=18.99) or false
|
||||
|
||||
local grade
|
||||
local points
|
||||
@@ -14080,6 +14124,8 @@ function AIRBOSS:_GetACNickname(actype)
|
||||
local nickname="unknown"
|
||||
if actype==AIRBOSS.AircraftCarrier.A4EC then
|
||||
nickname="Skyhawk"
|
||||
elseif actype==AIRBOSS.AircraftCarrier.T45C then
|
||||
nickname="Goshawk"
|
||||
elseif actype==AIRBOSS.AircraftCarrier.AV8B then
|
||||
nickname="Harrier"
|
||||
elseif actype==AIRBOSS.AircraftCarrier.E2D then
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
-- @field #boolean clustermarkers If true, create cluster markers on F10 map.
|
||||
-- @field #number clustercounter Running number of clusters.
|
||||
-- @field #number dTforget Time interval in seconds before a known contact which is not detected any more is forgotten.
|
||||
-- @field #number clusterradius Radius im kilometers in which groups/units are considered to belong to a cluster
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- Top Secret!
|
||||
@@ -46,7 +47,7 @@
|
||||
-- @field #INTEL
|
||||
INTEL = {
|
||||
ClassName = "INTEL",
|
||||
verbose = 2,
|
||||
verbose = 0,
|
||||
lid = nil,
|
||||
alias = nil,
|
||||
filterCategory = {},
|
||||
@@ -56,6 +57,7 @@ INTEL = {
|
||||
ContactsUnknown = {},
|
||||
Clusters = {},
|
||||
clustercounter = 1,
|
||||
clusterradius = 15,
|
||||
}
|
||||
|
||||
--- Detected item info.
|
||||
@@ -74,6 +76,8 @@ INTEL = {
|
||||
-- @field #boolean isship
|
||||
-- @field #boolean ishelo
|
||||
-- @field #boolean isgrund
|
||||
-- @field Ops.Auftrag#AUFTRAG mission The current Auftrag attached to this contact
|
||||
-- @field #string recce The name of the recce unit that detected this contact
|
||||
|
||||
--- Cluster info.
|
||||
-- @type INTEL.Cluster
|
||||
@@ -85,11 +89,12 @@ INTEL = {
|
||||
-- @field #number threatlevelAve Average of threat levels.
|
||||
-- @field Core.Point#COORDINATE coordinate Coordinate of the cluster.
|
||||
-- @field Wrapper.Marker#MARKER marker F10 marker.
|
||||
-- @field Ops.Auftrag#AUFTRAG mission The current Auftrag attached to this cluster
|
||||
|
||||
|
||||
--- INTEL class version.
|
||||
-- @field #string version
|
||||
INTEL.version="0.1.0"
|
||||
INTEL.version="0.2.0"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ToDo list
|
||||
@@ -175,6 +180,8 @@ function INTEL:New(DetectionSet, Coalition, Alias)
|
||||
self:AddTransition("*", "NewContact", "*") -- New contact has been detected.
|
||||
self:AddTransition("*", "LostContact", "*") -- Contact could not be detected any more.
|
||||
|
||||
self:AddTransition("*", "NewCluster", "*") -- New cluster has been detected.
|
||||
self:AddTransition("*", "LostCluster", "*") -- Cluster could not be detected any more.
|
||||
|
||||
-- Defaults
|
||||
self:SetForgetTime()
|
||||
@@ -210,10 +217,43 @@ function INTEL:New(DetectionSet, Coalition, Alias)
|
||||
-- @function [parent=#INTEL] __Status
|
||||
-- @param #INTEL self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On After "NewContact" event.
|
||||
-- @function [parent=#INTEL] OnAfterNewContact
|
||||
-- @param #INTEL self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Contact Contact Detected contact.
|
||||
|
||||
--- On After "LostContact" event.
|
||||
-- @function [parent=#INTEL] OnAfterLostContact
|
||||
-- @param #INTEL self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Contact Contact Lost contact.
|
||||
|
||||
--- On After "NewCluster" event.
|
||||
-- @function [parent=#INTEL] OnAfterNewCluster
|
||||
-- @param #INTEL self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Contact Contact Detected contact.
|
||||
-- @param #INTEL.Cluster Cluster Detected cluster
|
||||
|
||||
--- On After "LostCluster" event.
|
||||
-- @function [parent=#INTEL] OnAfterLostCluster
|
||||
-- @param #INTEL self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Cluster Cluster Lost cluster
|
||||
-- @param Ops.Auftrag#AUFTRAG Mission The Auftrag connected with this cluster or nil
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- User functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -307,7 +347,7 @@ function INTEL:SetFilterCategory(Categories)
|
||||
for _,category in pairs(self.filterCategory) do
|
||||
text=text..string.format("%d,", category)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
self:T(self.lid..text)
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -334,7 +374,7 @@ function INTEL:FilterCategoryGroup(GroupCategories)
|
||||
for _,category in pairs(self.filterCategoryGroup) do
|
||||
text=text..string.format("%d,", category)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
self:T(self.lid..text)
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -351,6 +391,49 @@ function INTEL:SetClusterAnalysis(Switch, Markers)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set verbosity level for debugging.
|
||||
-- @param #INTEL self
|
||||
-- @param #number Verbosity The higher, the noisier, e.g. 0=off, 2=debug
|
||||
-- @return #INTEL self
|
||||
function INTEL:SetVerbosity(Verbosity)
|
||||
self.verbose=Verbosity or 2
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a Mission (Auftrag) to a contact for tracking.
|
||||
-- @param #INTEL self
|
||||
-- @param #INTEL.Contact Contact The contact
|
||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission connected with this contact
|
||||
-- @return #INTEL self
|
||||
function INTEL:AddMissionToContact(Contact, Mission)
|
||||
if Mission and Contact then
|
||||
Contact.mission = Mission
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a Mission (Auftrag) to a cluster for tracking.
|
||||
-- @param #INTEL self
|
||||
-- @param #INTEL.Cluster Cluster The cluster
|
||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission connected with this cluster
|
||||
-- @return #INTEL self
|
||||
function INTEL:AddMissionToCluster(Cluster, Mission)
|
||||
if Mission and Cluster then
|
||||
Cluster.mission = Mission
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Change radius of the Clusters
|
||||
-- @param #INTEL self
|
||||
-- @param #number radius The radius of the clusters
|
||||
-- @return #INTEL self
|
||||
function INTEL:SetClusterRadius(radius)
|
||||
local radius = radius or 15
|
||||
self.clusterradius = radius
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Start & Status
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -389,10 +472,11 @@ function INTEL:onafterStatus(From, Event, To)
|
||||
|
||||
-- Number of total contacts.
|
||||
local Ncontacts=#self.Contacts
|
||||
local Nclusters=#self.Clusters
|
||||
|
||||
-- Short info.
|
||||
if self.verbose>=1 then
|
||||
local text=string.format("Status %s [Agents=%s]: Contacts=%d, New=%d, Lost=%d", fsmstate, self.detectionset:CountAlive(), Ncontacts, #self.ContactsUnknown, #self.ContactsLost)
|
||||
local text=string.format("Status %s [Agents=%s]: Contacts=%d, Clusters=%d, New=%d, Lost=%d", fsmstate, self.detectionset:CountAlive(), Ncontacts, Nclusters, #self.ContactsUnknown, #self.ContactsLost)
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
|
||||
@@ -421,7 +505,8 @@ function INTEL:UpdateIntel()
|
||||
|
||||
-- Set of all detected units.
|
||||
local DetectedUnits={}
|
||||
|
||||
-- Set of which units was detected by which recce
|
||||
local RecceDetecting = {}
|
||||
-- Loop over all units providing intel.
|
||||
for _,_group in pairs(self.detectionset.Set or {}) do
|
||||
local group=_group --Wrapper.Group#GROUP
|
||||
@@ -432,7 +517,7 @@ function INTEL:UpdateIntel()
|
||||
local recce=_recce --Wrapper.Unit#UNIT
|
||||
|
||||
-- Get detected units.
|
||||
self:GetDetectedUnits(recce, DetectedUnits)
|
||||
self:GetDetectedUnits(recce, DetectedUnits, RecceDetecting)
|
||||
|
||||
end
|
||||
|
||||
@@ -489,7 +574,7 @@ function INTEL:UpdateIntel()
|
||||
end
|
||||
end
|
||||
if not keepit then
|
||||
self:I(self.lid..string.format("Removing unit %s category=%d", unitname, unit:GetCategory()))
|
||||
self:T(self.lid..string.format("Removing unit %s category=%d", unitname, unit:GetCategory()))
|
||||
table.insert(remove, unitname)
|
||||
end
|
||||
end
|
||||
@@ -502,17 +587,20 @@ function INTEL:UpdateIntel()
|
||||
end
|
||||
|
||||
-- Create detected groups.
|
||||
local DetectedGroups={}
|
||||
local DetectedGroups={}
|
||||
local RecceGroups={}
|
||||
for unitname,_unit in pairs(DetectedUnits) do
|
||||
local unit=_unit --Wrapper.Unit#UNIT
|
||||
local group=unit:GetGroup()
|
||||
if group then
|
||||
DetectedGroups[group:GetName()]=group
|
||||
local groupname = group:GetName()
|
||||
DetectedGroups[groupname]=group
|
||||
RecceGroups[groupname]=RecceDetecting[unitname]
|
||||
end
|
||||
end
|
||||
|
||||
-- Create detected contacts.
|
||||
self:CreateDetectedItems(DetectedGroups)
|
||||
self:CreateDetectedItems(DetectedGroups, RecceGroups)
|
||||
|
||||
-- Paint a picture of the battlefield.
|
||||
if self.clusteranalysis then
|
||||
@@ -528,8 +616,9 @@ end
|
||||
--- Create detected items.
|
||||
-- @param #INTEL self
|
||||
-- @param #table DetectedGroups Table of detected Groups
|
||||
function INTEL:CreateDetectedItems(DetectedGroups)
|
||||
|
||||
-- @param #table RecceDetecting Table of detecting recce names
|
||||
function INTEL:CreateDetectedItems(DetectedGroups, RecceDetecting)
|
||||
self:F({RecceDetecting=RecceDetecting})
|
||||
-- Current time.
|
||||
local Tnow=timer.getAbsTime()
|
||||
|
||||
@@ -569,7 +658,8 @@ function INTEL:CreateDetectedItems(DetectedGroups)
|
||||
item.position=group:GetCoordinate()
|
||||
item.velocity=group:GetVelocityVec3()
|
||||
item.speed=group:GetVelocityMPS()
|
||||
|
||||
item.recce=RecceDetecting[groupname]
|
||||
self:T(string.format("%s group detect by %s/%s", groupname, RecceDetecting[groupname] or "unknonw", item.recce or "unknown"))
|
||||
-- Add contact to table.
|
||||
self:AddContact(item)
|
||||
|
||||
@@ -602,17 +692,20 @@ end
|
||||
-- If no detection method is given, the detection will use all the available methods by default.
|
||||
-- @param #INTEL self
|
||||
-- @param Wrapper.Unit#UNIT Unit The unit detecting.
|
||||
-- @param #table DetectedUnits Table of detected units to be filled
|
||||
-- @param #table RecceDetecting Table of recce per unit to be filled
|
||||
-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets.
|
||||
-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets.
|
||||
-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar.
|
||||
-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST.
|
||||
-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR.
|
||||
-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link.
|
||||
function INTEL:GetDetectedUnits(Unit, DetectedUnits, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)
|
||||
function INTEL:GetDetectedUnits(Unit, DetectedUnits, RecceDetecting, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)
|
||||
|
||||
-- Get detected DCS units.
|
||||
local detectedtargets=Unit:GetDetectedTargets(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)
|
||||
|
||||
local reccename = Unit:GetName()
|
||||
|
||||
for DetectionObjectID, Detection in pairs(detectedtargets or {}) do
|
||||
local DetectedObject=Detection.object -- DCS#Object
|
||||
|
||||
@@ -625,7 +718,8 @@ function INTEL:GetDetectedUnits(Unit, DetectedUnits, DetectVisual, DetectOptical
|
||||
local unitname=unit:GetName()
|
||||
|
||||
DetectedUnits[unitname]=unit
|
||||
|
||||
RecceDetecting[unitname]=reccename
|
||||
self:T(string.format("Unit %s detect by %s", unitname, reccename))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -643,7 +737,7 @@ end
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Contact Contact Detected contact.
|
||||
function INTEL:onafterNewContact(From, Event, To, Contact)
|
||||
self:I(self.lid..string.format("NEW contact %s", Contact.groupname))
|
||||
self:F(self.lid..string.format("NEW contact %s", Contact.groupname))
|
||||
table.insert(self.ContactsUnknown, Contact)
|
||||
end
|
||||
|
||||
@@ -654,10 +748,37 @@ end
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Contact Contact Detected contact.
|
||||
function INTEL:onafterLostContact(From, Event, To, Contact)
|
||||
self:I(self.lid..string.format("LOST contact %s", Contact.groupname))
|
||||
self:F(self.lid..string.format("LOST contact %s", Contact.groupname))
|
||||
table.insert(self.ContactsLost, Contact)
|
||||
end
|
||||
|
||||
--- On after "NewCluster" event.
|
||||
-- @param #INTEL self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Contact Contact Detected contact.
|
||||
-- @param #INTEL.Cluster Cluster Detected cluster
|
||||
function INTEL:onafterNewCluster(From, Event, To, Contact, Cluster)
|
||||
self:F(self.lid..string.format("NEW cluster %d size %d with contact %s", Cluster.index, Cluster.size, Contact.groupname))
|
||||
end
|
||||
|
||||
--- On after "LostCluster" event.
|
||||
-- @param #INTEL self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #INTEL.Cluster Cluster Lost cluster
|
||||
-- @param Ops.Auftrag#AUFTRAG Mission The Auftrag connected with this cluster or nil
|
||||
function INTEL:onafterLostCluster(From, Event, To, Cluster, Mission)
|
||||
local text = self.lid..string.format("LOST cluster %d", Cluster.index)
|
||||
if Mission then
|
||||
local mission=Mission --Ops.Auftrag#AUFTRAG
|
||||
text=text..string.format(" mission name=%s type=%s target=%s", mission.name, mission.type, mission:GetTargetName() or "unkown")
|
||||
end
|
||||
self:T(text)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Misc Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -752,11 +873,27 @@ function INTEL:PaintPicture()
|
||||
self:RemoveContactFromCluster(contact, cluster)
|
||||
end
|
||||
end
|
||||
|
||||
-- clean up cluster table
|
||||
local ClusterSet = {}
|
||||
for _i,_cluster in pairs(self.Clusters) do
|
||||
if (_cluster.size > 0) and (self:ClusterCountUnits(_cluster) > 0) then
|
||||
table.insert(ClusterSet,_cluster)
|
||||
else
|
||||
local mission = _cluster.mission or nil
|
||||
local marker = _cluster.marker
|
||||
if marker then
|
||||
marker:Remove()
|
||||
end
|
||||
self:LostCluster(_cluster, mission)
|
||||
end
|
||||
end
|
||||
self.Clusters = ClusterSet
|
||||
-- update positions
|
||||
self:_UpdateClusterPositions()
|
||||
|
||||
for _,_contact in pairs(self.Contacts) do
|
||||
local contact=_contact --#INTEL.Contact
|
||||
|
||||
self:T(string.format("Paint Picture: checking for %s",contact.groupname))
|
||||
-- Check if this contact is in any cluster.
|
||||
local isincluster=self:CheckContactInClusters(contact)
|
||||
|
||||
@@ -764,7 +901,7 @@ function INTEL:PaintPicture()
|
||||
local currentcluster=self:GetClusterOfContact(contact)
|
||||
|
||||
if currentcluster then
|
||||
|
||||
--self:I(string.format("Paint Picture: %s has current cluster",contact.groupname))
|
||||
---
|
||||
-- Contact is currently part of a cluster.
|
||||
---
|
||||
@@ -772,8 +909,8 @@ function INTEL:PaintPicture()
|
||||
-- Check if the contact is still connected to the cluster.
|
||||
local isconnected=self:IsContactConnectedToCluster(contact, currentcluster)
|
||||
|
||||
if not isconnected then
|
||||
|
||||
if (not isconnected) and (currentcluster.size > 1) then
|
||||
--self:I(string.format("Paint Picture: %s has LOST current cluster",contact.groupname))
|
||||
local cluster=self:IsContactPartOfAnyClusters(contact)
|
||||
|
||||
if cluster then
|
||||
@@ -782,6 +919,7 @@ function INTEL:PaintPicture()
|
||||
|
||||
local newcluster=self:CreateCluster(contact.position)
|
||||
self:AddContactToCluster(contact, newcluster)
|
||||
self:NewCluster(contact, newcluster)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -792,7 +930,7 @@ function INTEL:PaintPicture()
|
||||
---
|
||||
-- Contact is not in any cluster yet.
|
||||
---
|
||||
|
||||
--self:I(string.format("Paint Picture: %s has NO current cluster",contact.groupname))
|
||||
local cluster=self:IsContactPartOfAnyClusters(contact)
|
||||
|
||||
if cluster then
|
||||
@@ -801,6 +939,7 @@ function INTEL:PaintPicture()
|
||||
|
||||
local newcluster=self:CreateCluster(contact.position)
|
||||
self:AddContactToCluster(contact, newcluster)
|
||||
self:NewCluster(contact, newcluster)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -810,16 +949,17 @@ function INTEL:PaintPicture()
|
||||
|
||||
|
||||
-- Update F10 marker text if cluster has changed.
|
||||
for _,_cluster in pairs(self.Clusters) do
|
||||
local cluster=_cluster --#INTEL.Cluster
|
||||
|
||||
local coordinate=self:GetClusterCoordinate(cluster)
|
||||
|
||||
|
||||
-- Update F10 marker.
|
||||
self:UpdateClusterMarker(cluster)
|
||||
if self.clustermarkers then
|
||||
for _,_cluster in pairs(self.Clusters) do
|
||||
local cluster=_cluster --#INTEL.Cluster
|
||||
|
||||
local coordinate=self:GetClusterCoordinate(cluster)
|
||||
|
||||
|
||||
-- Update F10 marker.
|
||||
self:UpdateClusterMarker(cluster)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Create a new cluster.
|
||||
@@ -976,9 +1116,11 @@ function INTEL:IsContactConnectedToCluster(contact, cluster)
|
||||
|
||||
if Contact.groupname~=contact.groupname then
|
||||
|
||||
local dist=Contact.position:Get2DDistance(contact.position)
|
||||
--local dist=Contact.position:Get2DDistance(contact.position)
|
||||
local dist=Contact.position:DistanceFromPointVec2(contact.position)
|
||||
|
||||
if dist<10*1000 then
|
||||
local radius = self.clusterradius or 15
|
||||
if dist<radius*1000 then
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -1032,7 +1174,6 @@ end
|
||||
-- @param #INTEL.Cluster cluster The cluster.
|
||||
-- @return Core.Point#COORDINATE The coordinate of this cluster.
|
||||
function INTEL:GetClusterCoordinate(cluster)
|
||||
|
||||
-- Init.
|
||||
local x=0 ; local y=0 ; local z=0 ; local n=0
|
||||
|
||||
@@ -1058,12 +1199,14 @@ end
|
||||
--- Get the coordinate of a cluster.
|
||||
-- @param #INTEL self
|
||||
-- @param #INTEL.Cluster cluster The cluster.
|
||||
-- @param Core.Point#COORDINATE coordinate (Optional) Coordinate of the new cluster. Default is to calculate the current coordinate.
|
||||
-- @param Core.Point#COORDINATE coordinate (Optional) Coordinate of the new cluster. Default is to calculate the current coordinate.
|
||||
-- @return #boolean
|
||||
function INTEL:CheckClusterCoordinateChanged(cluster, coordinate)
|
||||
|
||||
coordinate=coordinate or self:GetClusterCoordinate(cluster)
|
||||
|
||||
local dist=cluster.coordinate:Get2DDistance(coordinate)
|
||||
--local dist=cluster.coordinate:Get2DDistance(coordinate)
|
||||
local dist=cluster.coordinate:DistanceFromPointVec2(coordinate)
|
||||
|
||||
if dist>1000 then
|
||||
return true
|
||||
@@ -1073,6 +1216,27 @@ function INTEL:CheckClusterCoordinateChanged(cluster, coordinate)
|
||||
|
||||
end
|
||||
|
||||
--- Update coordinates of the known clusters.
|
||||
-- @param #INTEL self
|
||||
function INTEL:_UpdateClusterPositions()
|
||||
for _,_cluster in pairs (self.Clusters) do
|
||||
local coord = self:GetClusterCoordinate(_cluster)
|
||||
_cluster.coordinate = coord
|
||||
self:T(self.lid..string.format("Cluster size: %s", _cluster.size))
|
||||
end
|
||||
end
|
||||
|
||||
--- Count number of units in cluster
|
||||
-- @param #INTEL self
|
||||
-- @param #INTEL.Cluster Cluster The cluster
|
||||
-- @return #number unitcount
|
||||
function INTEL:ClusterCountUnits(Cluster)
|
||||
local unitcount = 0
|
||||
for _,_group in pairs (Cluster.Contacts) do -- get Wrapper.GROUP#GROUP _group
|
||||
unitcount = unitcount + _group.group:CountAliveUnits()
|
||||
end
|
||||
return unitcount
|
||||
end
|
||||
|
||||
--- Update cluster F10 marker.
|
||||
-- @param #INTEL self
|
||||
@@ -1081,7 +1245,8 @@ end
|
||||
function INTEL:UpdateClusterMarker(cluster)
|
||||
|
||||
-- Create a marker.
|
||||
local text=string.format("Cluster #%d. Size %d, TLsum=%d", cluster.index, cluster.size, cluster.threatlevelSum)
|
||||
local unitcount = self:ClusterCountUnits(cluster)
|
||||
local text=string.format("Cluster #%d. Size %d, Units %d, TLsum=%d", cluster.index, cluster.size, unitcount, cluster.threatlevelSum)
|
||||
|
||||
if not cluster.marker then
|
||||
cluster.marker=MARKER:New(cluster.coordinate, text):ToAll()
|
||||
|
||||
Reference in New Issue
Block a user