mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
62 Commits
3749142670
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8efcad123c | ||
|
|
b9cf1e46af | ||
|
|
47409b11cb | ||
|
|
4a04d7cce7 | ||
|
|
5ef6383c63 | ||
|
|
35f15435a3 | ||
|
|
38dcd04334 | ||
|
|
b32a8a2899 | ||
|
|
8cac4dbf9e | ||
|
|
ef2bec72a1 | ||
|
|
03c3a20b1b | ||
|
|
4c97d966a2 | ||
|
|
f075c02db5 | ||
|
|
32e61a7a09 | ||
|
|
674c6eec81 | ||
|
|
da535eaddc | ||
|
|
c75c3d8777 | ||
|
|
4fa63986dc | ||
|
|
029f7a3f5c | ||
|
|
eb6eba25f3 | ||
|
|
e9194c59f4 | ||
|
|
c8d693c8e7 | ||
|
|
72d8b29699 | ||
|
|
2341014882 | ||
|
|
eb15fadcfe | ||
|
|
1e7203320f | ||
|
|
e3b587aa95 | ||
|
|
13fa8f373e | ||
|
|
c3dc055fb2 | ||
|
|
4e024f7173 | ||
|
|
1248006f3d | ||
|
|
b318e8ae13 | ||
|
|
1af4d44ca5 | ||
|
|
7e963bef41 | ||
|
|
933000ffc7 | ||
|
|
9b217e1c97 | ||
|
|
324f4944b4 | ||
|
|
b9d738c1ad | ||
|
|
f735f1eb53 | ||
|
|
7149226283 | ||
|
|
4164a5288a | ||
|
|
1992276b07 | ||
|
|
21a7023b7b | ||
|
|
bd054b26c0 | ||
|
|
f094716b73 | ||
|
|
b3100d2f5e | ||
|
|
4b1888a34d | ||
|
|
f4cd214823 | ||
|
|
b9be3aa7f8 | ||
|
|
bb6db2b7f8 | ||
|
|
fd2dacaefb | ||
|
|
cc60e85901 | ||
|
|
9520782a04 | ||
|
|
f172f6efeb | ||
|
|
b6b6686873 | ||
|
|
5e724e7a3f | ||
|
|
90f1d1df2a | ||
|
|
a5726c0ed8 | ||
|
|
1860366986 | ||
|
|
9db1d38a15 | ||
|
|
04ceda693b | ||
|
|
23ff128ac8 |
@@ -777,7 +777,9 @@ do -- COORDINATE
|
|||||||
-- @return DCS#Vec2 Vec2
|
-- @return DCS#Vec2 Vec2
|
||||||
function COORDINATE:GetRandomVec2InRadius( OuterRadius, InnerRadius )
|
function COORDINATE:GetRandomVec2InRadius( OuterRadius, InnerRadius )
|
||||||
self:F2( { OuterRadius, InnerRadius } )
|
self:F2( { OuterRadius, InnerRadius } )
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
local Theta = 2 * math.pi * math.random()
|
local Theta = 2 * math.pi * math.random()
|
||||||
local Radials = math.random() + math.random()
|
local Radials = math.random() + math.random()
|
||||||
if Radials > 1 then
|
if Radials > 1 then
|
||||||
@@ -837,6 +839,26 @@ do -- COORDINATE
|
|||||||
return land.getHeight( Vec2 )
|
return land.getHeight( Vec2 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns a table of DCS#Vec3 points representing the terrain profile between two points.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Destination DCS#Vec3 Ending point of the profile.
|
||||||
|
-- @return #table DCS#Vec3 table of the profile
|
||||||
|
function COORDINATE:GetLandProfileVec3(Destination)
|
||||||
|
return land.profile(self:GetVec3(), Destination)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a table of #COORDINATE representing the terrain profile between two points.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Destination #COORDINATE Ending coordinate of the profile.
|
||||||
|
-- @return #table #COORDINATE table of the profile
|
||||||
|
function COORDINATE:GetLandProfileCoordinates(Destination)
|
||||||
|
local points = self:GetLandProfileVec3(Destination:GetVec3())
|
||||||
|
local coords = {}
|
||||||
|
for _, point in ipairs(points) do
|
||||||
|
table.insert(coords, COORDINATE:NewFromVec3(point))
|
||||||
|
end
|
||||||
|
return coords
|
||||||
|
end
|
||||||
|
|
||||||
--- Set the heading of the coordinate, if applicable.
|
--- Set the heading of the coordinate, if applicable.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
local Name = Info.name or "?"
|
local Name = Info.name or "?"
|
||||||
|
|
||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
env.info( "Error in timer function: " .. errmsg )
|
env.info( "Error in timer function: " .. errmsg or "" )
|
||||||
if BASE.Debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( BASE.Debug.traceback() )
|
env.info( BASE.Debug.traceback() )
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6691,6 +6691,8 @@ do -- SET_ZONE
|
|||||||
--
|
--
|
||||||
-- -- Stop watching after 1 hour
|
-- -- Stop watching after 1 hour
|
||||||
-- zoneset:__TriggerStop(3600)
|
-- zoneset:__TriggerStop(3600)
|
||||||
|
-- -- Call :SetPartlyInside() on any zone (or SET_ZONE) if you want GROUPs to count as inside when any of their units enters even if they are far apart.
|
||||||
|
-- -- Make sure to call :SetPartlyInside() before :Trigger()!.
|
||||||
function SET_ZONE:Trigger(Objects)
|
function SET_ZONE:Trigger(Objects)
|
||||||
--self:I("Added Set_Zone Trigger")
|
--self:I("Added Set_Zone Trigger")
|
||||||
self:AddTransition("*","TriggerStart","TriggerRunning")
|
self:AddTransition("*","TriggerStart","TriggerRunning")
|
||||||
@@ -6741,6 +6743,20 @@ do -- SET_ZONE
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone The zone left.
|
-- @param Core.Zone#ZONE_BASE Zone The zone left.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Toggle “partly-inside” handling for every zone in the set when those zones are used with :Trigger().
|
||||||
|
-- * Call with no argument or **true** → enable for all.
|
||||||
|
-- * Call with **false** → disable again (handy if it was enabled before).
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @return #SET_ZONE self
|
||||||
|
function SET_ZONE:SetPartlyInside(state)
|
||||||
|
for _,Zone in pairs(self.Set) do
|
||||||
|
if Zone.SetPartlyInside then
|
||||||
|
Zone:SetPartlyInside(state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||||
-- @param #SET_ZONE self
|
-- @param #SET_ZONE self
|
||||||
-- @param #boolean fromstart If true, do the init of the objects
|
-- @param #boolean fromstart If true, do the init of the objects
|
||||||
@@ -6776,8 +6792,13 @@ do -- SET_ZONE
|
|||||||
-- has not been tagged previously - wasn't in set!
|
-- has not been tagged previously - wasn't in set!
|
||||||
obj.TriggerInZone[_zone.ZoneName] = false
|
obj.TriggerInZone[_zone.ZoneName] = false
|
||||||
end
|
end
|
||||||
-- is obj in zone?
|
-- is obj in this zone?
|
||||||
local inzone = _zone:IsCoordinateInZone(obj:GetCoordinate())
|
local inzone
|
||||||
|
if _zone.PartlyInside and obj.ClassName == "GROUP" then
|
||||||
|
inzone = obj:IsAnyInZone(_zone) -- TRUE as soon as any unit is inside
|
||||||
|
else
|
||||||
|
inzone = _zone:IsCoordinateInZone(obj:GetCoordinate()) -- original centroid test
|
||||||
|
end
|
||||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||||
if inzone and not obj.TriggerInZone[_zone.ZoneName] then
|
if inzone and not obj.TriggerInZone[_zone.ZoneName] then
|
||||||
-- wasn't in zone before
|
-- wasn't in zone before
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
|
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
|
||||||
-- @field #number Surface Type of surface. Only determined at the center of the zone!
|
-- @field #number Surface Type of surface. Only determined at the center of the zone!
|
||||||
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
|
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
|
||||||
|
-- @field #boolean PartlyInside When called, a GROUP is considered inside as soon as any of its units enters the zone even if they are far apart.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
@@ -534,6 +535,19 @@ function ZONE_BASE:GetZoneProbability()
|
|||||||
return self.ZoneProbability
|
return self.ZoneProbability
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the coordinate on the radius of the zone nearest to Outsidecoordinate. Useto e.g. find an ingress point.
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @param Core.Point#COORDINATE Outsidecoordinate The coordinate outside of the zone from where to look.
|
||||||
|
-- @return Core.Point#COORDINATE CoordinateOnRadius
|
||||||
|
function ZONE_BASE:FindNearestCoordinateOnRadius(Outsidecoordinate)
|
||||||
|
local Vec1 = self:GetVec2()
|
||||||
|
local Radius = self:GetRadius()
|
||||||
|
local Vec2 = Outsidecoordinate:GetVec2()
|
||||||
|
local Point = UTILS.FindNearestPointOnCircle(Vec1,Radius,Vec2)
|
||||||
|
local rc = COORDINATE:NewFromVec2(Point)
|
||||||
|
return rc
|
||||||
|
end
|
||||||
|
|
||||||
--- Get the zone taking into account the randomization probability of a zone to be selected.
|
--- Get the zone taking into account the randomization probability of a zone to be selected.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
||||||
@@ -599,6 +613,8 @@ end
|
|||||||
--
|
--
|
||||||
-- -- Stop watching the zone after 1 hour
|
-- -- Stop watching the zone after 1 hour
|
||||||
-- triggerzone:__TriggerStop(3600)
|
-- triggerzone:__TriggerStop(3600)
|
||||||
|
-- -- Call :SetPartlyInside() if you use SET_GROUP to count as inside when any of their units enters even when they are far apart.
|
||||||
|
-- -- Make sure to call :SetPartlyInside() before :Trigger()!
|
||||||
function ZONE_BASE:Trigger(Objects)
|
function ZONE_BASE:Trigger(Objects)
|
||||||
--self:I("Added Zone Trigger")
|
--self:I("Added Zone Trigger")
|
||||||
self:SetStartState("TriggerStopped")
|
self:SetStartState("TriggerStopped")
|
||||||
@@ -667,6 +683,16 @@ function ZONE_BASE:Trigger(Objects)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Toggle “partly-inside” handling for this zone. To be used before :Trigger().
|
||||||
|
-- * Default:* flag is **false** until you call the method.
|
||||||
|
-- * Call with no argument or with **true** → enable.
|
||||||
|
-- * Call with **false** → disable again (handy if it was enabled before).
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @return #ZONE_BASE self
|
||||||
|
function ZONE_BASE:SetPartlyInside(state)
|
||||||
|
self.PartlyInside = state or not ( state == false )
|
||||||
|
return self
|
||||||
|
end
|
||||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param #boolean fromstart If true, do the init of the objects
|
-- @param #boolean fromstart If true, do the init of the objects
|
||||||
@@ -705,7 +731,12 @@ function ZONE_BASE:_TriggerCheck(fromstart)
|
|||||||
obj.TriggerInZone[self.ZoneName] = false
|
obj.TriggerInZone[self.ZoneName] = false
|
||||||
end
|
end
|
||||||
-- is obj in zone?
|
-- is obj in zone?
|
||||||
local inzone = self:IsCoordinateInZone(obj:GetCoordinate())
|
local inzone
|
||||||
|
if self.PartlyInside and obj.ClassName == "GROUP" then
|
||||||
|
inzone = obj:IsAnyInZone(self) -- TRUE if any unit is inside
|
||||||
|
else
|
||||||
|
inzone = self:IsCoordinateInZone(obj:GetCoordinate()) -- original barycentre test
|
||||||
|
end
|
||||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||||
if inzone and obj.TriggerInZone[self.ZoneName] then
|
if inzone and obj.TriggerInZone[self.ZoneName] then
|
||||||
-- just count
|
-- just count
|
||||||
@@ -1510,6 +1541,7 @@ function ZONE_RADIUS:IsVec3InZone( Vec3 )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param #number PosRadius Required clear radius around each position.
|
-- @param #number PosRadius Required clear radius around each position.
|
||||||
-- @param #number NumPositions Number of positions to find.
|
-- @param #number NumPositions Number of positions to find.
|
||||||
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
||||||
@@ -1519,6 +1551,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
||||||
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
||||||
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
||||||
@@ -1539,6 +1572,10 @@ function ZONE_RADIUS:GetRandomVec2(inner, outer, surfacetypes)
|
|||||||
local _inner = inner or 0
|
local _inner = inner or 0
|
||||||
local _outer = outer or self:GetRadius()
|
local _outer = outer or self:GetRadius()
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
if surfacetypes and type(surfacetypes)~="table" then
|
if surfacetypes and type(surfacetypes)~="table" then
|
||||||
surfacetypes={surfacetypes}
|
surfacetypes={surfacetypes}
|
||||||
end
|
end
|
||||||
@@ -2506,6 +2543,7 @@ function ZONE_POLYGON_BASE:Flush()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @param #number PosRadius Required clear radius around each position.
|
-- @param #number PosRadius Required clear radius around each position.
|
||||||
-- @param #number NumPositions Number of positions to find.
|
-- @param #number NumPositions Number of positions to find.
|
||||||
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
||||||
@@ -2515,6 +2553,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
||||||
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
||||||
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
||||||
@@ -2901,6 +2940,11 @@ end
|
|||||||
function ZONE_POLYGON_BASE:GetRandomVec2()
|
function ZONE_POLYGON_BASE:GetRandomVec2()
|
||||||
-- make sure we assign weights to the triangles based on their surface area, otherwise
|
-- make sure we assign weights to the triangles based on their surface area, otherwise
|
||||||
-- we'll be more likely to generate random points in smaller triangles
|
-- we'll be more likely to generate random points in smaller triangles
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
local weights = {}
|
local weights = {}
|
||||||
for _, triangle in pairs(self._Triangles) do
|
for _, triangle in pairs(self._Triangles) do
|
||||||
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ AUTOLASE = {
|
|||||||
debug = false,
|
debug = false,
|
||||||
smokemenu = true,
|
smokemenu = true,
|
||||||
RoundingPrecision = 0,
|
RoundingPrecision = 0,
|
||||||
increasegroundawareness = true,
|
increasegroundawareness = false,
|
||||||
MonitorFrequency = 30,
|
MonitorFrequency = 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet)
|
|||||||
self.smokemenu = true
|
self.smokemenu = true
|
||||||
self.threatmenu = true
|
self.threatmenu = true
|
||||||
self.RoundingPrecision = 0
|
self.RoundingPrecision = 0
|
||||||
self.increasegroundawareness = true
|
self.increasegroundawareness = false
|
||||||
self.MonitorFrequency = 30
|
self.MonitorFrequency = 30
|
||||||
|
|
||||||
self:EnableSmokeMenu({Angle=math.random(0,359),Distance=math.random(10,20)})
|
self:EnableSmokeMenu({Angle=math.random(0,359),Distance=math.random(10,20)})
|
||||||
@@ -1020,7 +1020,7 @@ function AUTOLASE:_Prescient()
|
|||||||
self:T(self.lid.."Checking possibly visible STATICs for Recce "..unit:GetName())
|
self:T(self.lid.."Checking possibly visible STATICs for Recce "..unit:GetName())
|
||||||
for _,_static in pairs(Statics) do -- DCS static object here
|
for _,_static in pairs(Statics) do -- DCS static object here
|
||||||
local static = STATIC:Find(_static)
|
local static = STATIC:Find(_static)
|
||||||
if static and static:GetCoalition() ~= self.coalition then
|
if static and static:GetCoalition() ~= self.coalition and static:GetCoordinate() then
|
||||||
local IsLOS = position:IsLOS(static:GetCoordinate())
|
local IsLOS = position:IsLOS(static:GetCoordinate())
|
||||||
if IsLOS then
|
if IsLOS then
|
||||||
unit:KnowUnit(static,true,true)
|
unit:KnowUnit(static,true,true)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
--
|
--
|
||||||
-- Last Update: July 2025
|
-- Last Update: August 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
@@ -108,10 +108,15 @@
|
|||||||
-- * Patriot
|
-- * Patriot
|
||||||
-- * Rapier
|
-- * Rapier
|
||||||
-- * Roland
|
-- * Roland
|
||||||
|
-- * IRIS-T SLM
|
||||||
|
-- * Pantsir S1
|
||||||
|
-- * TOR M2
|
||||||
|
-- * C-RAM
|
||||||
-- * Silkworm (though strictly speaking this is a surface to ship missile)
|
-- * Silkworm (though strictly speaking this is a surface to ship missile)
|
||||||
-- * SA-2, SA-3, SA-5, SA-6, SA-7, SA-8, SA-9, SA-10, SA-11, SA-13, SA-15, SA-19
|
-- * SA-2, SA-3, SA-5, SA-6, SA-7, SA-8, SA-9, SA-10, SA-11, SA-13, SA-15, SA-19
|
||||||
-- * From IDF mod: STUNNER IDFA, TAMIR IDFA (Note all caps!)
|
-- * From IDF mod: STUNNER IDFA, TAMIR IDFA (Note all caps!)
|
||||||
-- * From HDS (see note on HDS below): SA-2, SA-3, SA-10B, SA-10C, SA-12, SA-17, SA-20A, SA-20B, SA-23, HQ-2, SAMP/T Block 1, SAMP/T Block 1INT, SAMP/T Block2
|
-- * From HDS (see note on HDS below): SA-2, SA-3, SA-10B, SA-10C, SA-12, SA-17, SA-20A, SA-20B, SA-23, HQ-2, SAMP/T Block 1, SAMP/T Block 1INT, SAMP/T Block2
|
||||||
|
-- * Other Mods: Nike
|
||||||
--
|
--
|
||||||
-- * From SMA: RBS98M, RBS70, RBS90, RBS90M, RBS103A, RBS103B, RBS103AM, RBS103BM, Lvkv9040M
|
-- * From SMA: RBS98M, RBS70, RBS90, RBS90M, RBS103A, RBS103B, RBS103AM, RBS103BM, Lvkv9040M
|
||||||
-- **NOTE** If you are using the Swedish Military Assets (SMA), please note that the **group name** for RBS-SAM types also needs to contain the keyword "SMA"
|
-- **NOTE** If you are using the Swedish Military Assets (SMA), please note that the **group name** for RBS-SAM types also needs to contain the keyword "SMA"
|
||||||
@@ -275,7 +280,7 @@
|
|||||||
MANTIS = {
|
MANTIS = {
|
||||||
ClassName = "MANTIS",
|
ClassName = "MANTIS",
|
||||||
name = "mymantis",
|
name = "mymantis",
|
||||||
version = "0.9.32",
|
version = "0.9.34",
|
||||||
SAM_Templates_Prefix = "",
|
SAM_Templates_Prefix = "",
|
||||||
SAM_Group = nil,
|
SAM_Group = nil,
|
||||||
EWR_Templates_Prefix = "",
|
EWR_Templates_Prefix = "",
|
||||||
@@ -384,7 +389,7 @@ MANTIS.SamData = {
|
|||||||
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
||||||
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
|
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
|
||||||
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
||||||
["HEMTT_C-RAM_Phalanx"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="HEMTT_C-RAM_Phalanx", Point="true" },
|
["C-RAM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="HEMTT_C-RAM_Phalanx", Point="true" },
|
||||||
-- units from HDS Mod, multi launcher options is tricky
|
-- units from HDS Mod, multi launcher options is tricky
|
||||||
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
|
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
|
||||||
["SA-17"] = { Range=50, Blindspot=3, Height=50, Type="Medium", Radar="SA-17" },
|
["SA-17"] = { Range=50, Blindspot=3, Height=50, Type="Medium", Radar="SA-17" },
|
||||||
@@ -393,6 +398,12 @@ MANTIS.SamData = {
|
|||||||
["HQ-2"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
|
["HQ-2"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
|
||||||
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
|
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
|
||||||
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
|
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
|
||||||
|
["NIKE"] = { Range=155, Blindspot=6, Height=30, Type="Long", Radar="HIPAR" },
|
||||||
|
["Dog Ear"] = { Range=11, Blindspot=0, Height=9, Type="Point", Radar="Dog Ear", Point="true" },
|
||||||
|
-- CH Added to DCS core 2.9.19.x
|
||||||
|
["Pantsir S1"] = { Range=20, Blindspot=1.2, Height=15, Type="Point", Radar="PantsirS1" , Point="true" },
|
||||||
|
["Tor M2"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2", Point="true" },
|
||||||
|
["IRIS-T SLM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
|
||||||
}
|
}
|
||||||
|
|
||||||
--- SAM data HDS
|
--- SAM data HDS
|
||||||
@@ -458,15 +469,15 @@ MANTIS.SamDataCH = {
|
|||||||
-- https://www.currenthill.com/
|
-- https://www.currenthill.com/
|
||||||
-- group name MUST contain CHM to ID launcher type correctly!
|
-- group name MUST contain CHM to ID launcher type correctly!
|
||||||
["2S38 CHM"] = { Range=6, Blindspot=0.1, Height=4.5, Type="Short", Radar="2S38" },
|
["2S38 CHM"] = { Range=6, Blindspot=0.1, Height=4.5, Type="Short", Radar="2S38" },
|
||||||
["PantsirS1 CHM"] = { Range=20, Blindspot=1.2, Height=15, Type="Short", Radar="PantsirS1" },
|
["PantsirS1 CHM"] = { Range=20, Blindspot=1.2, Height=15, Type="Point", Radar="PantsirS1", Point="true" },
|
||||||
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
||||||
["PGL-625 CHM"] = { Range=10, Blindspot=1, Height=5, Type="Short", Radar="PGL_625" },
|
["PGL-625 CHM"] = { Range=10, Blindspot=1, Height=5, Type="Short", Radar="PGL_625" },
|
||||||
["HQ-17A CHM"] = { Range=15, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
|
["HQ-17A CHM"] = { Range=15, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
|
||||||
["M903PAC2 CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
|
["M903PAC2 CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
|
||||||
["M903PAC3 CHM"] = { Range=160, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
|
["M903PAC3 CHM"] = { Range=160, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
|
||||||
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2" },
|
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2", Point="true" },
|
||||||
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2K", Point="true" },
|
||||||
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Point", Radar="TorM2M", Point="true" },
|
||||||
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
||||||
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
||||||
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_Centurion_C_RAM", Point="true" },
|
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_Centurion_C_RAM", Point="true" },
|
||||||
@@ -882,7 +893,11 @@ do
|
|||||||
self.AcceptZones = AcceptZones or {}
|
self.AcceptZones = AcceptZones or {}
|
||||||
self.RejectZones = RejectZones or {}
|
self.RejectZones = RejectZones or {}
|
||||||
self.ConflictZones = ConflictZones or {}
|
self.ConflictZones = ConflictZones or {}
|
||||||
if #self.AcceptZones > 0 or #self.RejectZones > 0 or #self.ConflictZones > 0 then
|
self.AcceptZonesNo = UTILS.TableLength(self.AcceptZones)
|
||||||
|
self.RejectZonesNo = UTILS.TableLength(self.RejectZones)
|
||||||
|
self.ConflictZonesNo = UTILS.TableLength(self.ConflictZones)
|
||||||
|
self:T(string.format("AcceptZonesNo = %d | RejectZonesNo = %d | ConflictZonesNo = %d",self.AcceptZonesNo,self.RejectZonesNo,self.ConflictZonesNo))
|
||||||
|
if self.AcceptZonesNo > 0 or self.RejectZonesNo > 0 or self.ConflictZonesNo > 0 then
|
||||||
self.usezones = true
|
self.usezones = true
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@@ -1274,7 +1289,8 @@ do
|
|||||||
self:T(self.lid.."_CheckCoordinateInZones")
|
self:T(self.lid.."_CheckCoordinateInZones")
|
||||||
local inzone = false
|
local inzone = false
|
||||||
-- acceptzones
|
-- acceptzones
|
||||||
if #self.AcceptZones > 0 then
|
self:T(string.format("AcceptZonesNo = %d | RejectZonesNo = %d | ConflictZonesNo = %d",self.AcceptZonesNo,self.RejectZonesNo,self.ConflictZonesNo))
|
||||||
|
if self.AcceptZonesNo > 0 then
|
||||||
for _,_zone in pairs(self.AcceptZones) do
|
for _,_zone in pairs(self.AcceptZones) do
|
||||||
local zone = _zone -- Core.Zone#ZONE
|
local zone = _zone -- Core.Zone#ZONE
|
||||||
if zone:IsCoordinateInZone(coord) then
|
if zone:IsCoordinateInZone(coord) then
|
||||||
@@ -1285,7 +1301,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- rejectzones
|
-- rejectzones
|
||||||
if #self.RejectZones > 0 and inzone then -- maybe in accept zone, but check the overlaps
|
if self.RejectZonesNo > 0 then
|
||||||
for _,_zone in pairs(self.RejectZones) do
|
for _,_zone in pairs(self.RejectZones) do
|
||||||
local zone = _zone -- Core.Zone#ZONE
|
local zone = _zone -- Core.Zone#ZONE
|
||||||
if zone:IsCoordinateInZone(coord) then
|
if zone:IsCoordinateInZone(coord) then
|
||||||
@@ -1296,7 +1312,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- conflictzones
|
-- conflictzones
|
||||||
if #self.ConflictZones > 0 and not inzone then -- if not already accepted, might be in conflict zones
|
if self.ConflictZonesNo > 0 then
|
||||||
for _,_zone in pairs(self.ConflictZones) do
|
for _,_zone in pairs(self.ConflictZones) do
|
||||||
local zone = _zone -- Core.Zone#ZONE
|
local zone = _zone -- Core.Zone#ZONE
|
||||||
if zone:IsCoordinateInZone(coord) then
|
if zone:IsCoordinateInZone(coord) then
|
||||||
@@ -1362,6 +1378,7 @@ do
|
|||||||
end
|
end
|
||||||
-- check accept/reject zones
|
-- check accept/reject zones
|
||||||
local zonecheck = true
|
local zonecheck = true
|
||||||
|
self:T("self.usezones = "..tostring(self.usezones))
|
||||||
if self.usezones then
|
if self.usezones then
|
||||||
-- DONE
|
-- DONE
|
||||||
zonecheck = self:_CheckCoordinateInZones(coord)
|
zonecheck = self:_CheckCoordinateInZones(coord)
|
||||||
|
|||||||
@@ -985,6 +985,7 @@ function SCORING:_EventOnHit( Event )
|
|||||||
local TargetUnitCoalition = nil
|
local TargetUnitCoalition = nil
|
||||||
local TargetUnitCategory = nil
|
local TargetUnitCategory = nil
|
||||||
local TargetUnitType = nil
|
local TargetUnitType = nil
|
||||||
|
local TargetIsScenery = false
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
@@ -1025,6 +1026,12 @@ function SCORING:_EventOnHit( Event )
|
|||||||
TargetCategory = Event.TgtCategory
|
TargetCategory = Event.TgtCategory
|
||||||
TargetType = Event.TgtTypeName
|
TargetType = Event.TgtTypeName
|
||||||
|
|
||||||
|
-- Scenery hit
|
||||||
|
if (not TargetCategory) and TargetUNIT ~= nil and TargetUnit:IsInstanceOf("SCENERY") then
|
||||||
|
TargetCategory = Unit.Category.STRUCTURE
|
||||||
|
TargetIsScenery = true
|
||||||
|
end
|
||||||
|
|
||||||
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
@@ -1117,17 +1124,22 @@ function SCORING:_EventOnHit( Event )
|
|||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
else
|
elseif TargetIsScenery ~= true then
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
||||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
|
elseif TargetIsScenery == true then
|
||||||
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object." .. " Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||||
|
MESSAGE.Type.Update )
|
||||||
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
end
|
end
|
||||||
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
end
|
end
|
||||||
else -- A scenery object was hit.
|
else -- A scenery object was hit.
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object.",
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit nothing special.",
|
||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
--- **Functional** - TIRESIAS - manages AI behaviour.
|
----- **Functional** - TIRESIAS - manages AI behaviour (OPTIMIZED VERSION).
|
||||||
|
|
||||||
|
---- ===
|
||||||
|
|
||||||
|
--- The @{#TIRESIAS} class is working in the back to keep your large-scale ground units in check.
|
||||||
--
|
--
|
||||||
-- ===
|
-- -- Features:
|
||||||
--
|
|
||||||
-- The @{#TIRESIAS} class is working in the back to keep your large-scale ground units in check.
|
|
||||||
--
|
|
||||||
-- ## Features:
|
|
||||||
--
|
--
|
||||||
-- * Designed to keep CPU and Network usage lower on missions with a lot of ground units.
|
-- * Designed to keep CPU and Network usage lower on missions with a lot of ground units.
|
||||||
-- * Does not affect ships to keep the Navy guys happy.
|
-- * Does not affect ships to keep the Navy guys happy.
|
||||||
@@ -16,24 +16,29 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ## Missions:
|
-- ## Optimizations Applied:
|
||||||
--
|
--
|
||||||
-- ### [TIRESIAS](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master)
|
-- * Cached frequently used functions and constants
|
||||||
|
-- * Reduced string concatenations and formatting
|
||||||
|
-- * Optimized loop structures and conditions
|
||||||
|
-- * Pre-allocated tables where possible
|
||||||
|
-- * Reduced function call overhead
|
||||||
|
-- * Improved memory management
|
||||||
--
|
--
|
||||||
-- ===
|
---- ===
|
||||||
--
|
|
||||||
-- ### Author : **applevangelist **
|
|
||||||
--
|
--
|
||||||
|
---- #-- Author : **applevangelist ** (Optimized by AI)
|
||||||
|
|
||||||
|
---
|
||||||
-- @module Functional.Tiresias
|
-- @module Functional.Tiresias
|
||||||
-- @image Functional.Tiresias.jpg
|
-- @image Functional.Tiresias.jpg
|
||||||
--
|
|
||||||
-- Last Update: Dec 2023
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
--- Last Update: July 2025
|
||||||
|
|
||||||
--- **TIRESIAS** class, extends Core.Base#BASE
|
--- **TIRESIAS** class, extends Core.Base#BASE
|
||||||
-- @type TIRESIAS
|
-- @type TIRESIAS
|
||||||
-- @field #string ClassName
|
-- @field #string ClassName
|
||||||
-- @field #booelan debug
|
-- @field #boolean debug
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
-- @field #number Interval
|
-- @field #number Interval
|
||||||
-- @field Core.Set#SET_GROUP GroundSet
|
-- @field Core.Set#SET_GROUP GroundSet
|
||||||
@@ -48,6 +53,9 @@
|
|||||||
-- @field #number PlaneSwitchRange
|
-- @field #number PlaneSwitchRange
|
||||||
-- @field Core.Set#SET_GROUP FlightSet
|
-- @field Core.Set#SET_GROUP FlightSet
|
||||||
-- @field #boolean SwitchAAA
|
-- @field #boolean SwitchAAA
|
||||||
|
-- @field #string lid
|
||||||
|
-- @field #table _cached_zones
|
||||||
|
-- @field #table _cached_groupsets
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -58,8 +66,8 @@
|
|||||||
-- @field #boolean AIOff
|
-- @field #boolean AIOff
|
||||||
-- @field #boolean exception
|
-- @field #boolean exception
|
||||||
|
|
||||||
|
---
|
||||||
--- *Tiresias, Greek demi-god and shapeshifter, blinded by the Gods, works as oracle for you.* (Wiki)
|
-- *Tiresias, Greek demi-god and shapeshifter, blinded by the Gods, works as oracle for you.* (Wiki)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -74,18 +82,17 @@
|
|||||||
-- * Easy setup.
|
-- * Easy setup.
|
||||||
--
|
--
|
||||||
-- ## Setup
|
-- ## Setup
|
||||||
--
|
-- -- Setup is a one-liner:
|
||||||
-- Setup is a one-liner:
|
|
||||||
--
|
--
|
||||||
-- local blinder = TIRESIAS:New()
|
-- local blinder = TIRESIAS:New()
|
||||||
--
|
--
|
||||||
-- Optionally you can set up exceptions, e.g. for convoys driving around
|
-- -- Optionally you can set up exceptions, e.g. for convoys driving around
|
||||||
--
|
--
|
||||||
-- local exceptionset = SET_GROUP:New():FilterCoalitions(" red" ):FilterPrefixes(" Convoy" ):FilterStart()
|
-- local exceptionset = SET_GROUP:New():FilterCoalitions(" red" ):FilterPrefixes(" Convoy" ):FilterStart()
|
||||||
-- local blinder = TIRESIAS:New()
|
-- local blinder = TIRESIAS:New()
|
||||||
-- blinder:AddExceptionSet(exceptionset)
|
-- blinder:AddExceptionSet(exceptionset)
|
||||||
--
|
--
|
||||||
-- Options
|
-- -- Options
|
||||||
--
|
--
|
||||||
-- -- Setup different radius for activation around helo and airplane groups (applies to AI and humans)
|
-- -- Setup different radius for activation around helo and airplane groups (applies to AI and humans)
|
||||||
-- blinder:SetActivationRanges(10,25) -- defaults are 10, and 25
|
-- blinder:SetActivationRanges(10,25) -- defaults are 10, and 25
|
||||||
@@ -93,11 +100,12 @@
|
|||||||
-- -- Setup engagement ranges for AAA (non-advanced SAM units like Flaks etc) and if you want them to be AIOff
|
-- -- Setup engagement ranges for AAA (non-advanced SAM units like Flaks etc) and if you want them to be AIOff
|
||||||
-- blinder:SetAAARanges(60,true) -- defaults are 60, and true
|
-- blinder:SetAAARanges(60,true) -- defaults are 60, and true
|
||||||
--
|
--
|
||||||
|
---
|
||||||
-- @field #TIRESIAS
|
-- @field #TIRESIAS
|
||||||
TIRESIAS = {
|
TIRESIAS = {
|
||||||
ClassName = "TIRESIAS",
|
ClassName = "TIRESIAS",
|
||||||
debug = false,
|
debug = true,
|
||||||
version = "0.0.5",
|
version = " 0.0.7-OPT" ,
|
||||||
Interval = 20,
|
Interval = 20,
|
||||||
GroundSet = nil,
|
GroundSet = nil,
|
||||||
VehicleSet = nil,
|
VehicleSet = nil,
|
||||||
@@ -108,9 +116,12 @@ TIRESIAS = {
|
|||||||
HeloSwitchRange = 10, -- NM
|
HeloSwitchRange = 10, -- NM
|
||||||
PlaneSwitchRange = 25, -- NM
|
PlaneSwitchRange = 25, -- NM
|
||||||
SwitchAAA = true,
|
SwitchAAA = true,
|
||||||
|
_cached_zones = {}, -- Cache for zone objects
|
||||||
|
_cached_groupsets = {}, -- Cache for group_set objects
|
||||||
}
|
}
|
||||||
|
|
||||||
--- [USER] Create a new Tiresias object and start it up.
|
---
|
||||||
|
-- [USER] Create a new Tiresias object and start it up.
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:New()
|
function TIRESIAS:New()
|
||||||
@@ -129,11 +140,13 @@ function TIRESIAS:New()
|
|||||||
self:AddTransition("*", "Status", "*") -- TIRESIAS status update.
|
self:AddTransition("*", "Status", "*") -- TIRESIAS status update.
|
||||||
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
||||||
|
|
||||||
self.ExceptionSet = SET_GROUP:New():Clear(false)
|
self.ExceptionSet = nil --SET_GROUP:New():Clear(false)
|
||||||
|
self._cached_zones = {} -- Initialize zone cache
|
||||||
|
|
||||||
self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler)
|
self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler)
|
||||||
|
|
||||||
self.lid = string.format("TIRESIAS %s | ",self.version)
|
-- Cache the log identifier to avoid string concatenation in loops
|
||||||
|
self.lid = "TIRESIAS " .. self.version .. " | "
|
||||||
|
|
||||||
self:I(self.lid .. "Managing ground groups!")
|
self:I(self.lid .. "Managing ground groups!")
|
||||||
|
|
||||||
@@ -156,14 +169,15 @@ function TIRESIAS:New()
|
|||||||
-- @param #number delay Delay in seconds.
|
-- @param #number delay Delay in seconds.
|
||||||
|
|
||||||
self:__Start(1)
|
self:__Start(1)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-----
|
||||||
--
|
|
||||||
|
---
|
||||||
-- Helper Functions
|
-- Helper Functions
|
||||||
--
|
---
|
||||||
-------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--- [USER] Set activation radius for Helos and Planes in Nautical Miles.
|
--- [USER] Set activation radius for Helos and Planes in Nautical Miles.
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
@@ -173,6 +187,8 @@ end
|
|||||||
function TIRESIAS:SetActivationRanges(HeloMiles, PlaneMiles)
|
function TIRESIAS:SetActivationRanges(HeloMiles, PlaneMiles)
|
||||||
self.HeloSwitchRange = HeloMiles or 10
|
self.HeloSwitchRange = HeloMiles or 10
|
||||||
self.PlaneSwitchRange = PlaneMiles or 25
|
self.PlaneSwitchRange = PlaneMiles or 25
|
||||||
|
-- Clear zone cache when ranges change
|
||||||
|
self._cached_zones = {}
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -193,238 +209,286 @@ end
|
|||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:AddExceptionSet(Set)
|
function TIRESIAS:AddExceptionSet(Set)
|
||||||
self:T(self.lid .. " AddExceptionSet" )
|
self:T(self.lid .. " AddExceptionSet" )
|
||||||
|
|
||||||
|
if not self.ExceptionSet then
|
||||||
|
self.ExceptionSet = SET_GROUP:New()
|
||||||
|
end
|
||||||
|
|
||||||
local exceptions = self.ExceptionSet
|
local exceptions = self.ExceptionSet
|
||||||
Set:ForEachGroupAlive(
|
|
||||||
function(grp)
|
-- Cache the exception data structure for reuse
|
||||||
if not grp.Tiresias then
|
local exception_data = {
|
||||||
grp.Tiresias = { -- #TIRESIAS.Data
|
|
||||||
type = " Exception" ,
|
type = " Exception" ,
|
||||||
exception = true,
|
exception = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
local inAAASet = self.AAASet:IsIncludeObject(grp)
|
||||||
|
local inVehSet = self.VehicleSet:IsIncludeObject(grp)
|
||||||
|
local inSAMSet = self.SAMSet:IsIncludeObject(grp)
|
||||||
|
if grp:IsGround() and (not grp.Tiresias) and (not inAAASet) and (not inVehSet) and (not inSAMSet) then
|
||||||
|
grp.Tiresias = exception_data
|
||||||
exceptions:AddGroup(grp, true)
|
exceptions:AddGroup(grp, true)
|
||||||
end
|
|
||||||
BASE:T(" TIRESIAS: Added exception group: " .. grp:GetName())
|
BASE:T(" TIRESIAS: Added exception group: " .. grp:GetName())
|
||||||
end
|
end
|
||||||
|
end
|
||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Filter Function
|
--- [INTERNAL] Filter Function - Optimized with cached calls
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
-- @return #boolean isin
|
-- @return #boolean isin
|
||||||
function TIRESIAS._FilterNotAAA(Group)
|
function TIRESIAS._FilterNotAAA(Group)
|
||||||
local grp = Group -- Wrapper.Group#GROUP
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
local isaaa = grp:IsAAA()
|
-- Cache method calls to reduce overhead
|
||||||
if isaaa == true and grp:IsGround() and not grp:IsShip() then
|
local is_air = grp:IsAir()
|
||||||
return false -- remove from SET
|
local is_ship = grp:IsShip()
|
||||||
else
|
local is_AAA = grp:IsAAA()
|
||||||
|
if is_air or grp:IsShip() then -- air or ship - no AAA
|
||||||
return true -- keep in SET
|
return true -- keep in SET
|
||||||
end
|
end
|
||||||
|
return not is_AAA -- remove AAA, keep others
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Filter Function
|
--- [INTERNAL] Filter Function - Optimized with cached calls
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
-- @return #boolean isin
|
-- @return #boolean isin
|
||||||
function TIRESIAS._FilterNotSAM(Group)
|
function TIRESIAS._FilterNotSAM(Group)
|
||||||
local grp = Group -- Wrapper.Group#GROUP
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
local issam = grp:IsSAM()
|
-- Cache method calls to reduce overhead
|
||||||
if issam == true and grp:IsGround() and not grp:IsShip() then
|
local is_air = grp:IsGround()
|
||||||
return false -- remove from SET
|
local is_ship = grp:IsShip()
|
||||||
else
|
local is_SAM = grp:IsSAM()
|
||||||
|
if is_air or grp:IsShip() then
|
||||||
return true -- keep in SET
|
return true -- keep in SET
|
||||||
end
|
end
|
||||||
|
return not is_SAM -- remove SAM, keep others
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Filter Function
|
--- [INTERNAL] Filter Function - Optimized with cached calls
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
-- @return #boolean isin
|
-- @return #boolean isin
|
||||||
function TIRESIAS._FilterAAA(Group)
|
function TIRESIAS._FilterAAA(Group)
|
||||||
local grp = Group -- Wrapper.Group#GROUP
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
local isaaa = grp:IsAAA()
|
-- Cache method calls to reduce overhead
|
||||||
if isaaa == true and grp:IsGround() and not grp:IsShip() then
|
local is_ground = grp:IsGround()
|
||||||
return true -- remove from SET
|
if (not is_ground) or grp:IsShip() then
|
||||||
else
|
return false -- not AAA
|
||||||
return false -- keep in SET
|
|
||||||
end
|
end
|
||||||
|
return grp:IsAAA() -- only AAA
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Filter Function
|
--- [INTERNAL] Filter Function - Optimized with cached calls
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
-- @return #boolean isin
|
-- @return #boolean isin
|
||||||
function TIRESIAS._FilterSAM(Group)
|
function TIRESIAS._FilterSAM(Group)
|
||||||
local grp = Group -- Wrapper.Group#GROUP
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
local issam = grp:IsSAM()
|
-- Cache method calls to reduce overhead
|
||||||
if issam == true and grp:IsGround() and not grp:IsShip() then
|
local is_ground = grp:IsGround()
|
||||||
return true -- remove from SET
|
if (not is_ground) or grp:IsShip() then
|
||||||
else
|
return false -- not SAM
|
||||||
return false -- keep in SET
|
|
||||||
end
|
end
|
||||||
|
return grp:IsSAM() -- only SAM
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Init Groups
|
--- [INTERNAL] Init Groups - Optimized with reduced function calls
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:_InitGroups()
|
function TIRESIAS:_InitGroups()
|
||||||
self:T(self.lid .. " _InitGroups" )
|
self:T(self.lid .. " _InitGroups" )
|
||||||
-- Set all groups invisible/motionless
|
|
||||||
|
-- Cache frequently used values
|
||||||
local EngageRange = self.AAARange
|
local EngageRange = self.AAARange
|
||||||
local SwitchAAA = self.SwitchAAA
|
local SwitchAAA = self.SwitchAAA
|
||||||
--- AAA
|
|
||||||
self.AAASet:ForEachGroupAlive(
|
-- Pre-create data structures to avoid repeated table creation
|
||||||
function(grp)
|
local aaa_data_template = {
|
||||||
if not grp.Tiresias then
|
|
||||||
grp:OptionEngageRange(EngageRange)
|
|
||||||
grp:SetCommandInvisible(true)
|
|
||||||
if SwitchAAA then
|
|
||||||
grp:SetAIOff()
|
|
||||||
grp:EnableEmission(false)
|
|
||||||
end
|
|
||||||
grp.Tiresias = { -- #TIRESIAS.Data
|
|
||||||
type = " AAA" ,
|
type = " AAA" ,
|
||||||
invisible = true,
|
invisible = true,
|
||||||
range = EngageRange,
|
range = EngageRange,
|
||||||
exception = false,
|
exception = false,
|
||||||
AIOff = SwitchAAA,
|
AIOff = SwitchAAA,
|
||||||
}
|
}
|
||||||
end
|
|
||||||
if grp.Tiresias and (not grp.Tiresias.exception == true) then
|
local vehicle_data_template = {
|
||||||
if grp.Tiresias.invisible == false then
|
|
||||||
grp:SetCommandInvisible(true)
|
|
||||||
grp.Tiresias.invisible = true
|
|
||||||
if SwitchAAA then
|
|
||||||
grp:SetAIOff()
|
|
||||||
grp:EnableEmission(false)
|
|
||||||
grp.Tiresias.AIOff = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--BASE:I(string.format("Init/Switch off AAA %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
|
|
||||||
end
|
|
||||||
)
|
|
||||||
--- Vehicles
|
|
||||||
self.VehicleSet:ForEachGroupAlive(
|
|
||||||
function(grp)
|
|
||||||
if not grp.Tiresias then
|
|
||||||
grp:SetAIOff()
|
|
||||||
grp:SetCommandInvisible(true)
|
|
||||||
grp.Tiresias = { -- #TIRESIAS.Data
|
|
||||||
type = " Vehicle" ,
|
type = " Vehicle" ,
|
||||||
invisible = true,
|
invisible = true,
|
||||||
AIOff = true,
|
AIOff = true,
|
||||||
exception = false,
|
exception = false,
|
||||||
}
|
}
|
||||||
end
|
|
||||||
if grp.Tiresias and (not grp.Tiresias.exception == true) then
|
local sam_data_template = {
|
||||||
if grp.Tiresias and grp.Tiresias.invisible == false then
|
|
||||||
grp:SetCommandInvisible(true)
|
|
||||||
grp:SetAIOff()
|
|
||||||
grp.Tiresias.invisible = true
|
|
||||||
grp.Tiresias.AIOff = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--BASE:I(string.format("Init/Switch off Vehicle %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
|
|
||||||
end
|
|
||||||
)
|
|
||||||
--- SAM
|
|
||||||
self.SAMSet:ForEachGroupAlive(
|
|
||||||
function(grp)
|
|
||||||
if not grp.Tiresias then
|
|
||||||
grp:SetCommandInvisible(true)
|
|
||||||
grp.Tiresias = { -- #TIRESIAS.Data
|
|
||||||
type = " SAM" ,
|
type = " SAM" ,
|
||||||
invisible = true,
|
invisible = true,
|
||||||
exception = false,
|
exception = false,
|
||||||
}
|
}
|
||||||
end
|
|
||||||
if grp.Tiresias and (not grp.Tiresias.exception == true) then
|
--- AAA - Optimized loop
|
||||||
if grp.Tiresias and grp.Tiresias.invisible == false then
|
self.AAASet:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
local tiresias_data = grp.Tiresias
|
||||||
|
if not tiresias_data then
|
||||||
|
grp:OptionEngageRange(EngageRange)
|
||||||
grp:SetCommandInvisible(true)
|
grp:SetCommandInvisible(true)
|
||||||
grp.Tiresias.invisible = true
|
if SwitchAAA then
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp:EnableEmission(false)
|
||||||
|
end
|
||||||
|
grp.Tiresias = aaa_data_template
|
||||||
|
elseif not tiresias_data.exception == true then
|
||||||
|
if not tiresias_data.invisible == true then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
tiresias_data.invisible = true
|
||||||
|
if SwitchAAA == true then
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp:EnableEmission(false)
|
||||||
|
tiresias_data.AIOff = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--BASE:I(string.format("Init/Switch off SAM %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
|
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
--- Vehicles - Optimized loop
|
||||||
|
self.VehicleSet:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
local tiresias_data = grp.Tiresias
|
||||||
|
if not tiresias_data then
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp.Tiresias = vehicle_data_template
|
||||||
|
elseif not tiresias_data.exception == true then
|
||||||
|
if not tiresias_data.invisible then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp:SetAIOff()
|
||||||
|
tiresias_data.invisible = true
|
||||||
|
tiresias_data.AIOff = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
--- SAM - Optimized loop
|
||||||
|
self.SAMSet:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
local tiresias_data = grp.Tiresias
|
||||||
|
if not tiresias_data then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp.Tiresias = sam_data_template
|
||||||
|
elseif not tiresias_data.exception == true then
|
||||||
|
if not tiresias_data.invisible then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
tiresias_data.invisible = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Event handler function
|
--- [INTERNAL] Event handler function - Optimized
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:_EventHandler(EventData)
|
function TIRESIAS:_EventHandler(EventData)
|
||||||
self:T(string.format(" %s Event = %d" , self.lid, EventData.id))
|
self:T(string.format(" %s Event = %d" , self.lid, EventData.id))
|
||||||
|
|
||||||
local event = EventData -- Core.Event#EVENTDATA
|
local event = EventData -- Core.Event#EVENTDATA
|
||||||
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
|
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
|
||||||
--local _coalition = event.IniCoalition
|
|
||||||
--if _coalition ~= self.Coalition then
|
|
||||||
-- return --ignore!
|
|
||||||
--end
|
|
||||||
local unitname = event.IniUnitName or "none"
|
|
||||||
local _unit = event.IniUnit
|
|
||||||
local _group = event.IniGroup
|
local _group = event.IniGroup
|
||||||
if _group and _group:IsAlive() then
|
if _group and _group:IsAlive() then
|
||||||
local radius = self.PlaneSwitchRange
|
-- Cache the radius calculation
|
||||||
if _group:IsHelicopter() then
|
local radius = _group:IsHelicopter() and self.HeloSwitchRange or self.PlaneSwitchRange
|
||||||
radius = self.HeloSwitchRange
|
|
||||||
end
|
|
||||||
self:_SwitchOnGroups(_group, radius)
|
self:_SwitchOnGroups(_group, radius)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] Switch Groups Behaviour
|
--- [INTERNAL] Switch Groups Behaviour - Optimized with zone caching
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
-- @param Wrapper.Group#GROUP group
|
-- @param Wrapper.Group#GROUP group
|
||||||
-- @param #number radius Radius in NM
|
-- @param #number radius Radius in NM
|
||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:_SwitchOnGroups(group, radius)
|
function TIRESIAS:_SwitchOnGroups(group, radius)
|
||||||
self:T(self.lid .. " _SwitchOnGroups " .. group:GetName() .. " Radius " .. radius .. " NM" )
|
self:T(self.lid .. " _SwitchOnGroups " .. group:GetName() .. " Radius " .. radius .. " NM" )
|
||||||
local zone = ZONE_GROUP:New("Zone-"..group:GetName(),group,UTILS.NMToMeters(radius))
|
|
||||||
local ground = SET_GROUP:New():FilterCategoryGround():FilterZones({zone}):FilterOnce()
|
-- Use cached zones to reduce object creation
|
||||||
local count = ground:CountAlive()
|
local group_name = group:GetName()
|
||||||
if self.debug then
|
local cache_key = group_name .. " _" .. radius
|
||||||
local text = string.format("There are %d groups around this plane or helo!",count)
|
local zone = self._cached_zones[cache_key]
|
||||||
self:I(text)
|
local ground = self._cached_groupsets[cache_key]
|
||||||
|
|
||||||
|
if not zone then
|
||||||
|
zone = ZONE_GROUP:New(" Zone-" .. group_name, group, UTILS.NMToMeters(radius))
|
||||||
|
self._cached_zones[cache_key] = zone
|
||||||
|
else
|
||||||
|
-- Update zone center to current group position
|
||||||
|
zone:UpdateFromGroup(group)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not ground then
|
||||||
|
ground = SET_GROUP:New():FilterCategoryGround():FilterZones({zone}):FilterOnce()
|
||||||
|
self._cached_groupsets[cache_key] = ground
|
||||||
|
else
|
||||||
|
ground:FilterZones({zone},true):FilterOnce()
|
||||||
|
end
|
||||||
|
|
||||||
|
local count = ground:CountAlive()
|
||||||
|
|
||||||
|
if self.debug then
|
||||||
|
self:I(string.format(" There are %d groups around this plane or helo!" , count))
|
||||||
|
end
|
||||||
|
|
||||||
|
if count > 0 then
|
||||||
|
-- Cache values outside the loop
|
||||||
local SwitchAAA = self.SwitchAAA
|
local SwitchAAA = self.SwitchAAA
|
||||||
if ground:CountAlive() > 0 then
|
local group_coalition = group:GetCoalition()
|
||||||
|
|
||||||
ground:ForEachGroupAlive(
|
ground:ForEachGroupAlive(
|
||||||
function(grp)
|
function(grp)
|
||||||
local name = grp:GetName()
|
local tiresias_data = grp.Tiresias
|
||||||
if grp:GetCoalition() ~= group:GetCoalition()
|
if grp:GetCoalition() ~= group_coalition
|
||||||
and grp.Tiresias and grp.Tiresias.type and (not grp.Tiresias.exception == true ) then
|
and tiresias_data
|
||||||
if grp.Tiresias.invisible == true then
|
and tiresias_data.type
|
||||||
|
and not tiresias_data.exception == true then
|
||||||
|
|
||||||
|
-- Make group visible if invisible
|
||||||
|
if tiresias_data.invisible == true then
|
||||||
grp:SetCommandInvisible(false)
|
grp:SetCommandInvisible(false)
|
||||||
grp.Tiresias.invisible = false
|
tiresias_data.invisible = false
|
||||||
end
|
end
|
||||||
if grp.Tiresias.type == "Vehicle" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == true then
|
|
||||||
|
-- Handle AI activation based on type
|
||||||
|
local grp_type = tiresias_data.type
|
||||||
|
if grp_type == "Vehicle" and tiresias_data.AIOff == true then
|
||||||
grp:SetAIOn()
|
grp:SetAIOn()
|
||||||
grp.Tiresias.AIOff = false
|
tiresias_data.AIOff = false
|
||||||
end
|
elseif SwitchAAA == true and grp_type == "AAA" and tiresias_data.AIOff == true then
|
||||||
if SwitchAAA and grp.Tiresias.type == "AAA" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == true then
|
|
||||||
grp:SetAIOn()
|
grp:SetAIOn()
|
||||||
grp:EnableEmission(true)
|
grp:EnableEmission(true)
|
||||||
grp.Tiresias.AIOff = false
|
tiresias_data.AIOff = false
|
||||||
end
|
end
|
||||||
--BASE:I(string.format("TIRESIAS - Switch on %s %s (Exception %s)",tostring(grp.Tiresias.type),grp:GetName(),tostring(grp.Tiresias.exception)))
|
|
||||||
else
|
else
|
||||||
BASE:T("TIRESIAS - This group "..tostring(name).. " has not been initialized or is an exception!")
|
BASE:T("TIRESIAS - This group " .. tostring(grp:GetName()) .. " has not been initialized or is an exception!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-----
|
||||||
--
|
|
||||||
-- FSM Functions
|
|
||||||
--
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--- [INTERNAL] FSM Function
|
---
|
||||||
|
-- FSM Functions
|
||||||
|
----
|
||||||
|
|
||||||
|
--- [INTERNAL] FSM Function - Optimized initialization
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
@@ -433,29 +497,57 @@ end
|
|||||||
function TIRESIAS:onafterStart(From, Event, To)
|
function TIRESIAS:onafterStart(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
|
|
||||||
|
-- Create sets with optimized filters
|
||||||
local VehicleSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterNotAAA):FilterFunction(TIRESIAS._FilterNotSAM):FilterStart()
|
local VehicleSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterNotAAA):FilterFunction(TIRESIAS._FilterNotSAM):FilterStart()
|
||||||
local AAASet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterAAA):FilterStart()
|
local AAASet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterAAA):FilterStart()
|
||||||
local SAMSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterSAM):FilterStart()
|
local SAMSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterSAM):FilterStart()
|
||||||
local OpsGroupSet = SET_OPSGROUP:New():FilterActive(true):FilterStart()
|
local OpsGroupSet = SET_OPSGROUP:New():FilterActive(true):FilterStart()
|
||||||
self.FlightSet = SET_GROUP:New():FilterCategories({" plane" ," helicopter" }):FilterStart()
|
self.FlightSet = SET_GROUP:New():FilterCategories({" plane" ," helicopter" }):FilterStart()
|
||||||
|
|
||||||
|
-- Cache frequently used values
|
||||||
local EngageRange = self.AAARange
|
local EngageRange = self.AAARange
|
||||||
|
local SwitchAAA = self.SwitchAAA
|
||||||
local ExceptionSet = self.ExceptionSet
|
local ExceptionSet = self.ExceptionSet
|
||||||
if self.ExceptionSet then
|
|
||||||
function ExceptionSet:OnAfterAdded(From,Event,To,ObjectName,Object)
|
-- Pre-create data templates to reduce object creation
|
||||||
BASE:I("TIRESIAS: EXCEPTION Object Added: "..Object:GetName())
|
local exception_data = {
|
||||||
if Object and Object:IsAlive() then
|
|
||||||
Object.Tiresias = { -- #TIRESIAS.Data
|
|
||||||
type = " Exception" ,
|
type = " Exception" ,
|
||||||
exception = true,
|
exception = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local vehicle_data = {
|
||||||
|
type = " Vehicle" ,
|
||||||
|
invisible = true,
|
||||||
|
AIOff = true,
|
||||||
|
exception = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
local aaa_data = {
|
||||||
|
type = " AAA" ,
|
||||||
|
invisible = true,
|
||||||
|
range = EngageRange,
|
||||||
|
exception = false,
|
||||||
|
AIOff = SwitchAAA,
|
||||||
|
}
|
||||||
|
|
||||||
|
local sam_data = {
|
||||||
|
type = " SAM" ,
|
||||||
|
invisible = true,
|
||||||
|
exception = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if ExceptionSet then
|
||||||
|
function ExceptionSet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
||||||
|
BASE:I(" TIRESIAS: EXCEPTION Object Added: " .. Object:GetName())
|
||||||
|
if Object and Object:IsAlive() then
|
||||||
|
Object.Tiresias = exception_data
|
||||||
Object:SetAIOn()
|
Object:SetAIOn()
|
||||||
Object:SetCommandInvisible(false)
|
Object:SetCommandInvisible(false)
|
||||||
Object:EnableEmission(true)
|
Object:EnableEmission(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Process existing OpsGroups more efficiently
|
||||||
local OGS = OpsGroupSet:GetAliveSet()
|
local OGS = OpsGroupSet:GetAliveSet()
|
||||||
for _, _OG in pairs(OGS or {}) do
|
for _, _OG in pairs(OGS or {}) do
|
||||||
local OG = _OG -- Ops.OpsGroup#OPSGROUP
|
local OG = _OG -- Ops.OpsGroup#OPSGROUP
|
||||||
@@ -469,22 +561,16 @@ function TIRESIAS:onafterStart(From, Event, To)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Optimized event handlers with pre-created data objects
|
||||||
function VehicleSet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
function VehicleSet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
||||||
BASE:I("TIRESIAS: VEHCILE Object Added: "..Object:GetName())
|
BASE:T(" TIRESIAS: VEHICLE Object Added: " .. Object:GetName())
|
||||||
if Object and Object:IsAlive() then
|
if Object and Object:IsAlive() then
|
||||||
Object:SetAIOff()
|
Object:SetAIOff()
|
||||||
Object:SetCommandInvisible(true)
|
Object:SetCommandInvisible(true)
|
||||||
Object.Tiresias = { -- #TIRESIAS.Data
|
Object.Tiresias = vehicle_data
|
||||||
type = "Vehicle",
|
|
||||||
invisible = true,
|
|
||||||
AIOff = true,
|
|
||||||
exception = false,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local SwitchAAA = self.SwitchAAA
|
|
||||||
|
|
||||||
function AAASet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
function AAASet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
||||||
if Object and Object:IsAlive() then
|
if Object and Object:IsAlive() then
|
||||||
BASE:I(" TIRESIAS: AAA Object Added: " .. Object:GetName())
|
BASE:I(" TIRESIAS: AAA Object Added: " .. Object:GetName())
|
||||||
@@ -494,28 +580,19 @@ function TIRESIAS:onafterStart(From, Event, To)
|
|||||||
Object:SetAIOff()
|
Object:SetAIOff()
|
||||||
Object:EnableEmission(false)
|
Object:EnableEmission(false)
|
||||||
end
|
end
|
||||||
Object.Tiresias = { -- #TIRESIAS.Data
|
Object.Tiresias = aaa_data
|
||||||
type = "AAA",
|
|
||||||
invisible = true,
|
|
||||||
range = EngageRange,
|
|
||||||
exception = false,
|
|
||||||
AIOff = SwitchAAA,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SAMSet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
function SAMSet:OnAfterAdded(From, Event, To, ObjectName, Object)
|
||||||
if Object and Object:IsAlive() then
|
if Object and Object:IsAlive() then
|
||||||
BASE:I("TIRESIAS: SAM Object Added: "..Object:GetName())
|
BASE:T(" TIRESIAS: SAM Object Added: " .. Object:GetName())
|
||||||
Object:SetCommandInvisible(true)
|
Object:SetCommandInvisible(true)
|
||||||
Object.Tiresias = { -- #TIRESIAS.Data
|
Object.Tiresias = sam_data
|
||||||
type = "SAM",
|
|
||||||
invisible = true,
|
|
||||||
exception = false,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Store references
|
||||||
self.VehicleSet = VehicleSet
|
self.VehicleSet = VehicleSet
|
||||||
self.AAASet = AAASet
|
self.AAASet = AAASet
|
||||||
self.SAMSet = SAMSet
|
self.SAMSet = SAMSet
|
||||||
@@ -535,13 +612,10 @@ end
|
|||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:onbeforeStatus(From, Event, To)
|
function TIRESIAS:onbeforeStatus(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
if self:GetState() == "Stopped" then
|
return self:GetState() ~= " Stopped"
|
||||||
return false
|
|
||||||
end
|
|
||||||
return self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [INTERNAL] FSM Function
|
--- [INTERNAL] FSM Function - Optimized status processing
|
||||||
-- @param #TIRESIAS self
|
-- @param #TIRESIAS self
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
@@ -549,28 +623,36 @@ end
|
|||||||
-- @return #TIRESIAS self
|
-- @return #TIRESIAS self
|
||||||
function TIRESIAS:onafterStatus(From, Event, To)
|
function TIRESIAS:onafterStatus(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
|
|
||||||
if self.debug then
|
if self.debug then
|
||||||
local count = self.VehicleSet:CountAlive()
|
local count = self.VehicleSet:CountAlive()
|
||||||
local AAAcount = self.AAASet:CountAlive()
|
local AAAcount = self.AAASet:CountAlive()
|
||||||
local SAMcount = self.SAMSet:CountAlive()
|
local SAMcount = self.SAMSet:CountAlive()
|
||||||
local text = string.format("Overall: %d | Vehicles: %d | AAA: %d | SAM: %d",count+AAAcount+SAMcount,count,AAAcount,SAMcount)
|
self:I(string.format(" Overall: %d | Vehicles: %d | AAA: %d | SAM: %d" ,
|
||||||
self:I(text)
|
count + AAAcount + SAMcount, count, AAAcount, SAMcount))
|
||||||
end
|
end
|
||||||
|
|
||||||
self:_InitGroups()
|
self:_InitGroups()
|
||||||
if self.FlightSet:CountAlive() > 0 then
|
|
||||||
|
-- Process flight groups more efficiently
|
||||||
|
local flight_count = self.FlightSet:CountAlive()
|
||||||
|
if flight_count > 0 then
|
||||||
local Set = self.FlightSet:GetAliveSet()
|
local Set = self.FlightSet:GetAliveSet()
|
||||||
for _,_plane in pairs(Set) do
|
-- Cache range values outside loop
|
||||||
|
local helo_range = self.HeloSwitchRange
|
||||||
|
local plane_range = self.PlaneSwitchRange
|
||||||
|
|
||||||
|
for _, _plane in pairs(Set or {}) do
|
||||||
local plane = _plane -- Wrapper.Group#GROUP
|
local plane = _plane -- Wrapper.Group#GROUP
|
||||||
local radius = self.PlaneSwitchRange
|
local radius = plane:IsHelicopter() and helo_range or plane_range
|
||||||
if plane:IsHelicopter() then
|
self:_SwitchOnGroups(plane, radius)
|
||||||
radius = self.HeloSwitchRange
|
|
||||||
end
|
|
||||||
self:_SwitchOnGroups(_plane,radius)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self:GetState() ~= " Stopped" then
|
if self:GetState() ~= " Stopped" then
|
||||||
self:__Status(self.Interval)
|
self:__Status(self.Interval)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -583,11 +665,11 @@ end
|
|||||||
function TIRESIAS:onafterStop(From, Event, To)
|
function TIRESIAS:onafterStop(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
self:UnHandleEvent(EVENTS.PlayerEnterAircraft)
|
self:UnHandleEvent(EVENTS.PlayerEnterAircraft)
|
||||||
|
-- Clear zone cache on stop to free memory
|
||||||
|
self._cached_zones = {}
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-----
|
||||||
--
|
---- End
|
||||||
-- End
|
-----
|
||||||
--
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
|
||||||
@@ -159,6 +159,8 @@ AIRWING = {
|
|||||||
-- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`.
|
-- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`.
|
||||||
-- @field #number noccupied Number of flights on this patrol point.
|
-- @field #number noccupied Number of flights on this patrol point.
|
||||||
-- @field Wrapper.Marker#MARKER marker F10 marker.
|
-- @field Wrapper.Marker#MARKER marker F10 marker.
|
||||||
|
-- @field #boolean IsZonePoint flag for using a (moving) zone as point for patrol etc.
|
||||||
|
-- @field Core.Zone#ZONE_BASE patrolzone in case Patrol coordinate was handed as zone, store here.
|
||||||
|
|
||||||
--- Patrol zone.
|
--- Patrol zone.
|
||||||
-- @type AIRWING.PatrolZone
|
-- @type AIRWING.PatrolZone
|
||||||
@@ -187,13 +189,14 @@ AIRWING = {
|
|||||||
|
|
||||||
--- AIRWING class version.
|
--- AIRWING class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AIRWING.version="0.9.6"
|
AIRWING.version="0.9.7"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- TODO: Check that airbase has enough parking spots if a request is BIG.
|
-- TODO: Check that airbase has enough parking spots if a request is BIG.
|
||||||
|
-- DONE: Allow (moving) zones as base for patrol points.
|
||||||
-- DONE: Spawn in air ==> Needs WAREHOUSE update.
|
-- DONE: Spawn in air ==> Needs WAREHOUSE update.
|
||||||
-- DONE: Spawn hot.
|
-- DONE: Spawn hot.
|
||||||
-- DONE: Make special request to transfer squadrons to anther airwing (or warehouse).
|
-- DONE: Make special request to transfer squadrons to anther airwing (or warehouse).
|
||||||
@@ -807,21 +810,30 @@ function AIRWING:_PatrolPointMarkerText(point)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Update marker of the patrol point.
|
--- Update marker of the patrol point.
|
||||||
|
-- @param #AIRWING self
|
||||||
-- @param #AIRWING.PatrolData point Patrol point table.
|
-- @param #AIRWING.PatrolData point Patrol point table.
|
||||||
function AIRWING:UpdatePatrolPointMarker(point)
|
function AIRWING:UpdatePatrolPointMarker(point)
|
||||||
if self.markpoints then -- sometimes there's a direct call from #OPSGROUP
|
|
||||||
|
if self and self.markpoints then -- sometimes there's a direct call from #OPSGROUP
|
||||||
local text=string.format("%s Occupied=%d\nheading=%03d, leg=%d NM, alt=%d ft, speed=%d kts",
|
local text=string.format("%s Occupied=%d\nheading=%03d, leg=%d NM, alt=%d ft, speed=%d kts",
|
||||||
point.type, point.noccupied, point.heading, point.leg, point.altitude, point.speed)
|
point.type, point.noccupied, point.heading, point.leg, point.altitude, point.speed)
|
||||||
|
|
||||||
|
if point.IsZonePoint and point.IsZonePoint == true and point.patrolzone then
|
||||||
|
-- update position
|
||||||
|
local Coordinate = point.patrolzone:GetCoordinate()
|
||||||
|
point.marker:UpdateCoordinate(Coordinate)
|
||||||
|
point.marker:UpdateText(text, 1.5)
|
||||||
|
else
|
||||||
point.marker:UpdateText(text, 1)
|
point.marker:UpdateText(text, 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Create a new generic patrol point.
|
--- Create a new generic patrol point.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #string Type Patrol point type, e.g. "CAP" or "AWACS". Default "Unknown".
|
-- @param #string Type Patrol point type, e.g. "CAP" or "AWACS". Default "Unknown".
|
||||||
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Default 10-15 NM away from the location of the airwing.
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Default 10-15 NM away from the location of the airwing. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Orbit altitude in feet. Default random between Angels 10 and 20.
|
-- @param #number Altitude Orbit altitude in feet. Default random between Angels 10 and 20.
|
||||||
-- @param #number Heading Heading in degrees. Default random (0, 360] degrees.
|
-- @param #number Heading Heading in degrees. Default random (0, 360] degrees.
|
||||||
-- @param #number LegLength Length of race-track orbit in NM. Default 15 NM.
|
-- @param #number LegLength Length of race-track orbit in NM. Default 15 NM.
|
||||||
@@ -830,14 +842,16 @@ end
|
|||||||
-- @return #AIRWING.PatrolData Patrol point table.
|
-- @return #AIRWING.PatrolData Patrol point table.
|
||||||
function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegLength, RefuelSystem)
|
function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegLength, RefuelSystem)
|
||||||
|
|
||||||
-- Check if a zone was passed instead of a coordinate.
|
|
||||||
if Coordinate and Coordinate:IsInstanceOf("ZONE_BASE") then
|
|
||||||
Coordinate=Coordinate:GetCoordinate()
|
|
||||||
end
|
|
||||||
|
|
||||||
local patrolpoint={} --#AIRWING.PatrolData
|
local patrolpoint={} --#AIRWING.PatrolData
|
||||||
patrolpoint.type=Type or "Unknown"
|
patrolpoint.type=Type or "Unknown"
|
||||||
patrolpoint.coord=Coordinate or self:GetCoordinate():Translate(UTILS.NMToMeters(math.random(10, 15)), math.random(360))
|
patrolpoint.coord=Coordinate or self:GetCoordinate():Translate(UTILS.NMToMeters(math.random(10, 15)), math.random(360))
|
||||||
|
if Coordinate:IsInstanceOf("ZONE_BASE") then
|
||||||
|
patrolpoint.IsZonePoint = true
|
||||||
|
patrolpoint.patrolzone = Coordinate
|
||||||
|
patrolpoint.coord = patrolpoint.patrolzone:GetCoordinate()
|
||||||
|
else
|
||||||
|
patrolpoint.IsZonePoint = false
|
||||||
|
end
|
||||||
patrolpoint.heading=Heading or math.random(360)
|
patrolpoint.heading=Heading or math.random(360)
|
||||||
patrolpoint.leg=LegLength or 15
|
patrolpoint.leg=LegLength or 15
|
||||||
patrolpoint.altitude=Altitude or math.random(10,20)*1000
|
patrolpoint.altitude=Altitude or math.random(10,20)*1000
|
||||||
@@ -847,7 +861,7 @@ function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegL
|
|||||||
|
|
||||||
if self.markpoints then
|
if self.markpoints then
|
||||||
patrolpoint.marker=MARKER:New(Coordinate, "New Patrol Point"):ToAll()
|
patrolpoint.marker=MARKER:New(Coordinate, "New Patrol Point"):ToAll()
|
||||||
AIRWING.UpdatePatrolPointMarker(patrolpoint)
|
self:UpdatePatrolPointMarker(patrolpoint)
|
||||||
end
|
end
|
||||||
|
|
||||||
return patrolpoint
|
return patrolpoint
|
||||||
@@ -855,7 +869,7 @@ end
|
|||||||
|
|
||||||
--- Add a patrol Point for CAP missions.
|
--- Add a patrol Point for CAP missions.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Orbit altitude in feet.
|
-- @param #number Altitude Orbit altitude in feet.
|
||||||
-- @param #number Speed Orbit speed in knots.
|
-- @param #number Speed Orbit speed in knots.
|
||||||
-- @param #number Heading Heading in degrees.
|
-- @param #number Heading Heading in degrees.
|
||||||
@@ -872,7 +886,7 @@ end
|
|||||||
|
|
||||||
--- Add a patrol Point for RECON missions.
|
--- Add a patrol Point for RECON missions.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Orbit altitude in feet.
|
-- @param #number Altitude Orbit altitude in feet.
|
||||||
-- @param #number Speed Orbit speed in knots.
|
-- @param #number Speed Orbit speed in knots.
|
||||||
-- @param #number Heading Heading in degrees.
|
-- @param #number Heading Heading in degrees.
|
||||||
@@ -889,7 +903,7 @@ end
|
|||||||
|
|
||||||
--- Add a patrol Point for TANKER missions.
|
--- Add a patrol Point for TANKER missions.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Orbit altitude in feet.
|
-- @param #number Altitude Orbit altitude in feet.
|
||||||
-- @param #number Speed Orbit speed in knots.
|
-- @param #number Speed Orbit speed in knots.
|
||||||
-- @param #number Heading Heading in degrees.
|
-- @param #number Heading Heading in degrees.
|
||||||
@@ -907,7 +921,7 @@ end
|
|||||||
|
|
||||||
--- Add a patrol Point for AWACS missions.
|
--- Add a patrol Point for AWACS missions.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Orbit altitude in feet.
|
-- @param #number Altitude Orbit altitude in feet.
|
||||||
-- @param #number Speed Orbit speed in knots.
|
-- @param #number Speed Orbit speed in knots.
|
||||||
-- @param #number Heading Heading in degrees.
|
-- @param #number Heading Heading in degrees.
|
||||||
@@ -1176,6 +1190,10 @@ function AIRWING:_GetPatrolData(PatrolPoints, RefuelSystem)
|
|||||||
|
|
||||||
for _,_patrolpoint in pairs(PatrolPoints) do
|
for _,_patrolpoint in pairs(PatrolPoints) do
|
||||||
local patrolpoint=_patrolpoint --#AIRWING.PatrolData
|
local patrolpoint=_patrolpoint --#AIRWING.PatrolData
|
||||||
|
if patrolpoint.IsZonePoint and patrolpoint.IsZonePoint == true and patrolpoint.patrolzone then
|
||||||
|
-- update
|
||||||
|
patrolpoint.coord = patrolpoint.patrolzone:GetCoordinate()
|
||||||
|
end
|
||||||
if (RefuelSystem and patrolpoint.refuelsystem and RefuelSystem==patrolpoint.refuelsystem) or RefuelSystem==nil or patrolpoint.refuelsystem==nil then
|
if (RefuelSystem and patrolpoint.refuelsystem and RefuelSystem==patrolpoint.refuelsystem) or RefuelSystem==nil or patrolpoint.refuelsystem==nil then
|
||||||
return patrolpoint
|
return patrolpoint
|
||||||
end
|
end
|
||||||
@@ -1235,7 +1253,7 @@ function AIRWING:CheckCAP()
|
|||||||
|
|
||||||
patrol.noccupied=patrol.noccupied+1
|
patrol.noccupied=patrol.noccupied+1
|
||||||
|
|
||||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
|
||||||
|
|
||||||
self:AddMission(missionCAP)
|
self:AddMission(missionCAP)
|
||||||
|
|
||||||
@@ -1287,7 +1305,7 @@ function AIRWING:CheckRECON()
|
|||||||
|
|
||||||
patrol.noccupied=patrol.noccupied+1
|
patrol.noccupied=patrol.noccupied+1
|
||||||
|
|
||||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
|
||||||
|
|
||||||
self:AddMission(missionRECON)
|
self:AddMission(missionRECON)
|
||||||
|
|
||||||
@@ -1332,7 +1350,7 @@ function AIRWING:CheckTANKER()
|
|||||||
|
|
||||||
patrol.noccupied=patrol.noccupied+1
|
patrol.noccupied=patrol.noccupied+1
|
||||||
|
|
||||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
|
||||||
|
|
||||||
self:AddMission(mission)
|
self:AddMission(mission)
|
||||||
|
|
||||||
@@ -1351,7 +1369,7 @@ function AIRWING:CheckTANKER()
|
|||||||
|
|
||||||
patrol.noccupied=patrol.noccupied+1
|
patrol.noccupied=patrol.noccupied+1
|
||||||
|
|
||||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
|
||||||
|
|
||||||
self:AddMission(mission)
|
self:AddMission(mission)
|
||||||
|
|
||||||
@@ -1389,7 +1407,7 @@ function AIRWING:CheckAWACS()
|
|||||||
|
|
||||||
patrol.noccupied=patrol.noccupied+1
|
patrol.noccupied=patrol.noccupied+1
|
||||||
|
|
||||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
|
||||||
|
|
||||||
self:AddMission(mission)
|
self:AddMission(mission)
|
||||||
|
|
||||||
|
|||||||
@@ -2412,6 +2412,16 @@ end
|
|||||||
-- USER API Functions
|
-- USER API Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set the carrier illumination mode.
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #number Mode Options are: -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:SetCarrierIllumination(Mode)
|
||||||
|
self.carrier:SetCarrierIlluminationMode(Mode)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set welcome messages for players.
|
--- Set welcome messages for players.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #boolean Switch If true, display welcome message to player.
|
-- @param #boolean Switch If true, display welcome message to player.
|
||||||
|
|||||||
@@ -1727,7 +1727,7 @@ function AUFTRAG:NewSEADInZone(TargetZone, Altitude, TargetTypes, Duration)
|
|||||||
|
|
||||||
local mission=AUFTRAG:New(AUFTRAG.Type.SEAD)
|
local mission=AUFTRAG:New(AUFTRAG.Type.SEAD)
|
||||||
|
|
||||||
mission:_TargetFromObject(TargetZone)
|
--mission:_TargetFromObject(TargetZone)
|
||||||
|
|
||||||
-- DCS Task options:
|
-- DCS Task options:
|
||||||
mission.engageWeaponType=ENUMS.WeaponFlag.Auto
|
mission.engageWeaponType=ENUMS.WeaponFlag.Auto
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Last Update May 2025
|
-- Last Update July 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
@@ -1199,7 +1199,7 @@ function CSAR:_EventHandler(EventData)
|
|||||||
-- all checks passed, get going.
|
-- all checks passed, get going.
|
||||||
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
|
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
|
||||||
local _freq = self:_GenerateADFFrequency()
|
local _freq = self:_GenerateADFFrequency()
|
||||||
self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none")
|
self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, self.suppressmessages, "none")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1264,7 +1264,7 @@ function CSAR:_EventHandler(EventData)
|
|||||||
if _coalition == self.coalition then
|
if _coalition == self.coalition then
|
||||||
local _freq = self:_GenerateADFFrequency()
|
local _freq = self:_GenerateADFFrequency()
|
||||||
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
|
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
|
||||||
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, false, "none")--shagrat add CSAR at Parachute location.
|
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, self.suppressmessages, "none")--shagrat add CSAR at Parachute location.
|
||||||
|
|
||||||
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
|
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
|
||||||
end
|
end
|
||||||
@@ -3006,7 +3006,7 @@ function CSAR:onafterLoad(From, Event, To, path, filename)
|
|||||||
local unitName = dataset[9]
|
local unitName = dataset[9]
|
||||||
local freq = tonumber(dataset[10])
|
local freq = tonumber(dataset[10])
|
||||||
|
|
||||||
self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, nil, description, nil)
|
self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, false, description, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -867,6 +867,7 @@ do
|
|||||||
-- my_ctld.TroopUnloadDistHoverHook = 5 -- When hovering, unload troops this far behind the Chinook
|
-- my_ctld.TroopUnloadDistHoverHook = 5 -- When hovering, unload troops this far behind the Chinook
|
||||||
-- my_ctld.showstockinmenuitems = false -- When set to true, the menu lines will also show the remaining items in stock (that is, if you set any), downside is that the menu for all will be build every 30 seconds anew.
|
-- my_ctld.showstockinmenuitems = false -- When set to true, the menu lines will also show the remaining items in stock (that is, if you set any), downside is that the menu for all will be build every 30 seconds anew.
|
||||||
-- my_ctld.onestepmenu = false -- When set to true, the menu will create Drop and build, Get and load, Pack and remove, Pack and load, Pack. it will be a 1 step solution.
|
-- my_ctld.onestepmenu = false -- When set to true, the menu will create Drop and build, Get and load, Pack and remove, Pack and load, Pack. it will be a 1 step solution.
|
||||||
|
-- my_ctld.VehicleMoveFormation = AI.Task.VehicleFormation.VEE -- When a group moves to a MOVE zone, then it takes this formation. Can be a table of formations, which are then randomly chosen. Defaults to "Vee".
|
||||||
--
|
--
|
||||||
-- ## 2.1 CH-47 Chinook support
|
-- ## 2.1 CH-47 Chinook support
|
||||||
--
|
--
|
||||||
@@ -1294,6 +1295,7 @@ CTLD = {
|
|||||||
LoadedGroupsTable = {},
|
LoadedGroupsTable = {},
|
||||||
keeploadtable = true,
|
keeploadtable = true,
|
||||||
allowCATransport = false,
|
allowCATransport = false,
|
||||||
|
VehicleMoveFormation = AI.Task.VehicleFormation.VEE,
|
||||||
}
|
}
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
@@ -1414,7 +1416,7 @@ CTLD.FixedWingTypes = {
|
|||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="1.3.36"
|
CTLD.version="1.3.37"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@@ -1554,6 +1556,8 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
self.movetroopsdistance = 5000
|
self.movetroopsdistance = 5000
|
||||||
self.troopdropzoneradius = 100
|
self.troopdropzoneradius = 100
|
||||||
|
|
||||||
|
self.VehicleMoveFormation = AI.Task.VehicleFormation.VEE
|
||||||
|
|
||||||
-- added support Hercules Mod
|
-- added support Hercules Mod
|
||||||
self.enableHercules = false -- deprecated
|
self.enableHercules = false -- deprecated
|
||||||
self.enableFixedWing = false
|
self.enableFixedWing = false
|
||||||
@@ -4197,6 +4201,17 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation,Mult
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to get a vehicle formation for a moving group
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @return #string Formation
|
||||||
|
function CTLD:_GetVehicleFormation()
|
||||||
|
local VehicleMoveFormation = self.VehicleMoveFormation or AI.Task.VehicleFormation.VEE
|
||||||
|
if type(self.VehicleMoveFormation)=="table" then
|
||||||
|
VehicleMoveFormation = self.VehicleMoveFormation[math.random(1,#self.VehicleMoveFormation)]
|
||||||
|
end
|
||||||
|
return VehicleMoveFormation
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Function to move group to WP zone.
|
--- (Internal) Function to move group to WP zone.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @param Wrapper.Group#GROUP Group The Group to move.
|
-- @param Wrapper.Group#GROUP Group The Group to move.
|
||||||
@@ -4211,18 +4226,20 @@ function CTLD:_MoveGroupToZone(Group)
|
|||||||
-- yes, we can ;)
|
-- yes, we can ;)
|
||||||
local groupname = Group:GetName()
|
local groupname = Group:GetName()
|
||||||
local zonecoord = zone:GetRandomCoordinate(20,125) -- Core.Point#COORDINATE
|
local zonecoord = zone:GetRandomCoordinate(20,125) -- Core.Point#COORDINATE
|
||||||
local coordinate = zonecoord:GetVec2()
|
local formation = self:_GetVehicleFormation()
|
||||||
|
--local coordinate = zonecoord:GetVec2()
|
||||||
Group:SetAIOn()
|
Group:SetAIOn()
|
||||||
Group:OptionAlarmStateAuto()
|
Group:OptionAlarmStateAuto()
|
||||||
Group:OptionDisperseOnAttack(30)
|
Group:OptionDisperseOnAttack(30)
|
||||||
Group:OptionROEOpenFirePossible()
|
Group:OptionROEOpenFire()
|
||||||
Group:RouteToVec2(coordinate,5)
|
Group:RouteGroundTo(zonecoord,25,formation)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Housekeeping - Cleanup crates when build
|
--- (Internal) Housekeeping - Cleanup crates when build
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
|
--
|
||||||
-- @param #table Crates Table of #CTLD_CARGO objects near the unit.
|
-- @param #table Crates Table of #CTLD_CARGO objects near the unit.
|
||||||
-- @param #CTLD.Buildable Build Table build object.
|
-- @param #CTLD.Buildable Build Table build object.
|
||||||
-- @param #number Number Number of objects in Crates (found) to limit search.
|
-- @param #number Number Number of objects in Crates (found) to limit search.
|
||||||
@@ -7134,6 +7151,16 @@ end
|
|||||||
local filepath = self.filepath
|
local filepath = self.filepath
|
||||||
self:__Save(interval,filepath,filename)
|
self:__Save(interval,filepath,filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type(self.VehicleMoveFormation) == "table" then
|
||||||
|
local Formations = {}
|
||||||
|
for _,_formation in pairs(self.VehicleMoveFormation) do
|
||||||
|
table.insert(Formations,_formation)
|
||||||
|
end
|
||||||
|
self.VehicleMoveFormation = nil
|
||||||
|
self.VehicleMoveFormation = Formations
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- Easy CAP/GCI Class, based on OPS classes
|
-- Easy CAP/GCI Class, based on OPS classes
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- Documentation
|
--
|
||||||
|
-- ## Documentation:
|
||||||
--
|
--
|
||||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Ops.EasyGCICAP.html
|
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Ops.EasyGCICAP.html
|
||||||
--
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Ops/EasyGCICAP).
|
||||||
|
--
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- Date: September 2023
|
-- Date: September 2023
|
||||||
-- Last Update: July 2024
|
-- Last Update: Aug 2025
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--
|
--
|
||||||
--- **Ops** - Easy GCI & CAP Manager
|
--- **Ops** - Easy GCI & CAP Manager
|
||||||
@@ -71,6 +76,9 @@
|
|||||||
-- @field #boolean DespawnAfterHolding
|
-- @field #boolean DespawnAfterHolding
|
||||||
-- @field #list<Ops.Auftrag#AUFTRAG> ListOfAuftrag
|
-- @field #list<Ops.Auftrag#AUFTRAG> ListOfAuftrag
|
||||||
-- @field #string defaulttakeofftype Take off type
|
-- @field #string defaulttakeofftype Take off type
|
||||||
|
-- @field #number FuelLowThreshold
|
||||||
|
-- @field #number FuelCriticalThreshold
|
||||||
|
-- @field #boolean showpatrolpointmarks
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
|
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
|
||||||
@@ -226,6 +234,9 @@ EASYGCICAP = {
|
|||||||
DespawnAfterHolding = true,
|
DespawnAfterHolding = true,
|
||||||
ListOfAuftrag = {},
|
ListOfAuftrag = {},
|
||||||
defaulttakeofftype = "hot",
|
defaulttakeofftype = "hot",
|
||||||
|
FuelLowThreshold = 25,
|
||||||
|
FuelCriticalThreshold = 10,
|
||||||
|
showpatrolpointmarks = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Internal Squadron data type
|
--- Internal Squadron data type
|
||||||
@@ -258,10 +269,11 @@ EASYGCICAP = {
|
|||||||
-- @field #number Speed
|
-- @field #number Speed
|
||||||
-- @field #number Heading
|
-- @field #number Heading
|
||||||
-- @field #number LegLength
|
-- @field #number LegLength
|
||||||
|
-- @field Core.Zone#ZONE_BASE Zone
|
||||||
|
|
||||||
--- EASYGCICAP class version.
|
--- EASYGCICAP class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
EASYGCICAP.version="0.1.23"
|
EASYGCICAP.version="0.1.27"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -315,6 +327,9 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
|
|||||||
self.DespawnAfterHolding = true
|
self.DespawnAfterHolding = true
|
||||||
self.ListOfAuftrag = {}
|
self.ListOfAuftrag = {}
|
||||||
self.defaulttakeofftype = "hot"
|
self.defaulttakeofftype = "hot"
|
||||||
|
self.FuelLowThreshold = 25
|
||||||
|
self.FuelCriticalThreshold = 10
|
||||||
|
self.showpatrolpointmarks = false
|
||||||
|
|
||||||
-- Set some string id for output to DCS.log file.
|
-- Set some string id for output to DCS.log file.
|
||||||
self.lid=string.format("EASYGCICAP %s | ", self.alias)
|
self.lid=string.format("EASYGCICAP %s | ", self.alias)
|
||||||
@@ -339,6 +354,63 @@ end
|
|||||||
-- Functions
|
-- Functions
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Get a specific managed AirWing by name
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param #string AirbaseName Airbase name of the home of this wing.
|
||||||
|
-- @return Ops.AirWing#AIRWING Airwing or nil if not found
|
||||||
|
function EASYGCICAP:GetAirwing(AirbaseName)
|
||||||
|
self:T(self.lid.."GetAirwing")
|
||||||
|
if self.wings[AirbaseName] then
|
||||||
|
return self.wings[AirbaseName][1]
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a table of all managed AirWings
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @return #table Table of Ops.AirWing#AIRWING Airwings
|
||||||
|
function EASYGCICAP:GetAirwingTable()
|
||||||
|
self:T(self.lid.."GetAirwingTable")
|
||||||
|
local Wingtable = {}
|
||||||
|
for _,_object in pairs(self.wings or {}) do
|
||||||
|
table.insert(Wingtable,_object[1])
|
||||||
|
end
|
||||||
|
return Wingtable
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set "fuel low" threshold for CAP and INTERCEPT flights.
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param #number Percent RTB if fuel at this percent. Values: 1..100, defaults to 25.
|
||||||
|
-- @return #EASYGCICAP self
|
||||||
|
function EASYGCICAP:SetFuelLow(Percent)
|
||||||
|
self:T(self.lid.."SetFuelLow")
|
||||||
|
self.FuelLowThreshold = Percent or 25
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set markers on the map for Patrol Points.
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param #boolean onoff Set to true to switch markers on.
|
||||||
|
-- @return #EASYGCICAP self
|
||||||
|
function EASYGCICAP:ShowPatrolPointMarkers(onoff)
|
||||||
|
if onoff then
|
||||||
|
self.showpatrolpointmarks = true
|
||||||
|
else
|
||||||
|
self.showpatrolpointmarks = false
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set "fuel critical" threshold for CAP and INTERCEPT flights.
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param #number Percent RTB if fuel at this percent. Values: 1..100, defaults to 10.
|
||||||
|
-- @return #EASYGCICAP self
|
||||||
|
function EASYGCICAP:SetFuelCritical(Percent)
|
||||||
|
self:T(self.lid.."SetFuelCritical")
|
||||||
|
self.FuelCriticalThreshold = Percent or 10
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set CAP formation.
|
--- Set CAP formation.
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #number Formation Formation to fly, defaults to ENUMS.Formation.FixedWing.FingerFour.Group
|
-- @param #number Formation Formation to fly, defaults to ENUMS.Formation.FixedWing.FingerFour.Group
|
||||||
@@ -359,7 +431,7 @@ function EASYGCICAP:SetTankerAndAWACSInvisible(Switch)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Count alive missions in our internal stack.
|
--- (internal) Count alive missions in our internal stack.
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @return #number count
|
-- @return #number count
|
||||||
function EASYGCICAP:_CountAliveAuftrags()
|
function EASYGCICAP:_CountAliveAuftrags()
|
||||||
@@ -583,7 +655,7 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
local DespawnAfterHolding = self.DespawnAfterHolding
|
local DespawnAfterHolding = self.DespawnAfterHolding
|
||||||
|
|
||||||
-- Check STATIC name
|
-- Check STATIC name
|
||||||
local check = STATIC:FindByName(Airbasename,false)
|
local check = STATIC:FindByName(Airbasename,false) or UNIT:FindByName(Airbasename)
|
||||||
if check == nil then
|
if check == nil then
|
||||||
MESSAGE:New(self.lid.."There's no warehouse static on the map (wrong naming?) for airbase "..tostring(Airbasename).."!",30,"CHECK"):ToAllIf(self.debug):ToLog()
|
MESSAGE:New(self.lid.."There's no warehouse static on the map (wrong naming?) for airbase "..tostring(Airbasename).."!",30,"CHECK"):ToAllIf(self.debug):ToLog()
|
||||||
return
|
return
|
||||||
@@ -599,6 +671,10 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
CAP_Wing:SetNumberCAP(self.capgrouping)
|
CAP_Wing:SetNumberCAP(self.capgrouping)
|
||||||
CAP_Wing:SetCapCloseRaceTrack(true)
|
CAP_Wing:SetCapCloseRaceTrack(true)
|
||||||
|
|
||||||
|
if self.showpatrolpointmarks then
|
||||||
|
CAP_Wing:ShowPatrolPointMarkers(true)
|
||||||
|
end
|
||||||
|
|
||||||
if self.capOptionVaryStartTime then
|
if self.capOptionVaryStartTime then
|
||||||
CAP_Wing:SetCapStartTimeVariation(self.capOptionVaryStartTime,self.capOptionVaryEndTime)
|
CAP_Wing:SetCapStartTimeVariation(self.capOptionVaryStartTime,self.capOptionVaryEndTime)
|
||||||
end
|
end
|
||||||
@@ -628,6 +704,8 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
local engagerange = self.engagerange
|
local engagerange = self.engagerange
|
||||||
local GoZoneSet = self.GoZoneSet
|
local GoZoneSet = self.GoZoneSet
|
||||||
local NoGoZoneSet = self.NoGoZoneSet
|
local NoGoZoneSet = self.NoGoZoneSet
|
||||||
|
local FuelLow = self.FuelLowThreshold or 25
|
||||||
|
local FuelCritical = self.FuelCriticalThreshold or 10
|
||||||
|
|
||||||
function CAP_Wing:onbeforeFlightOnMission(From, Event, To, Flightgroup, Mission)
|
function CAP_Wing:onbeforeFlightOnMission(From, Event, To, Flightgroup, Mission)
|
||||||
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
|
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
|
||||||
@@ -639,10 +717,15 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
flightgroup:SetDestinationbase(AIRBASE:FindByName(Airbasename))
|
flightgroup:SetDestinationbase(AIRBASE:FindByName(Airbasename))
|
||||||
flightgroup:GetGroup():CommandEPLRS(true,5)
|
flightgroup:GetGroup():CommandEPLRS(true,5)
|
||||||
flightgroup:GetGroup():SetOptionRadarUsingForContinousSearch()
|
flightgroup:GetGroup():SetOptionRadarUsingForContinousSearch()
|
||||||
|
flightgroup:GetGroup():SetOptionLandingOverheadBreak()
|
||||||
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
|
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
|
||||||
flightgroup:SetDetection(true)
|
flightgroup:SetDetection(true)
|
||||||
flightgroup:SetEngageDetectedOn(engagerange,{"Air"},GoZoneSet,NoGoZoneSet)
|
flightgroup:SetEngageDetectedOn(engagerange,{"Air"},GoZoneSet,NoGoZoneSet)
|
||||||
flightgroup:SetOutOfAAMRTB()
|
flightgroup:SetOutOfAAMRTB()
|
||||||
|
flightgroup:SetFuelLowRTB(true)
|
||||||
|
flightgroup:SetFuelLowThreshold(FuelLow)
|
||||||
|
flightgroup:SetFuelCriticalRTB(true)
|
||||||
|
flightgroup:SetFuelCriticalThreshold(FuelCritical)
|
||||||
if CapFormation then
|
if CapFormation then
|
||||||
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
|
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
|
||||||
end
|
end
|
||||||
@@ -681,24 +764,30 @@ end
|
|||||||
--- Add a CAP patrol point to a Wing
|
--- Add a CAP patrol point to a Wing
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #string AirbaseName Name of the Wing's airbase
|
-- @param #string AirbaseName Name of the Wing's airbase
|
||||||
-- @param Core.Point#COORDINATE Coordinate.
|
-- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Defaults to 25000 feet ASL.
|
-- @param #number Altitude Defaults to 25000 feet ASL.
|
||||||
-- @param #number Speed Defaults to 300 knots TAS.
|
-- @param #number Speed Defaults to 300 knots TAS.
|
||||||
-- @param #number Heading Defaults to 90 degrees (East).
|
-- @param #number Heading Defaults to 90 degrees (East).
|
||||||
-- @param #number LegLength Defaults to 15 NM.
|
-- @param #number LegLength Defaults to 15 NM.
|
||||||
-- @return #EASYGCICAP self
|
-- @return #EASYGCICAP self
|
||||||
function EASYGCICAP:AddPatrolPointCAP(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength)
|
function EASYGCICAP:AddPatrolPointCAP(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength)
|
||||||
self:T(self.lid.."AddPatrolPointCAP "..Coordinate:ToStringLLDDM())
|
self:T(self.lid.."AddPatrolPointCAP")--..Coordinate:ToStringLLDDM())
|
||||||
|
local coordinate = Coordinate
|
||||||
local EntryCAP = {} -- #EASYGCICAP.CapPoint
|
local EntryCAP = {} -- #EASYGCICAP.CapPoint
|
||||||
|
if Coordinate:IsInstanceOf("ZONE_BASE") then
|
||||||
|
-- adjust coordinate and get the coordinate from the zone
|
||||||
|
coordinate = Coordinate:GetCoordinate()
|
||||||
|
EntryCAP.Zone = Coordinate
|
||||||
|
end
|
||||||
EntryCAP.AirbaseName = AirbaseName
|
EntryCAP.AirbaseName = AirbaseName
|
||||||
EntryCAP.Coordinate = Coordinate
|
EntryCAP.Coordinate = coordinate
|
||||||
EntryCAP.Altitude = Altitude or 25000
|
EntryCAP.Altitude = Altitude or 25000
|
||||||
EntryCAP.Speed = Speed or 300
|
EntryCAP.Speed = Speed or 300
|
||||||
EntryCAP.Heading = Heading or 90
|
EntryCAP.Heading = Heading or 90
|
||||||
EntryCAP.LegLength = LegLength or 15
|
EntryCAP.LegLength = LegLength or 15
|
||||||
self.ManagedCP[#self.ManagedCP+1] = EntryCAP
|
self.ManagedCP[#self.ManagedCP+1] = EntryCAP
|
||||||
if self.debug then
|
if self.debug then
|
||||||
local mark = MARKER:New(Coordinate,self.lid.."Patrol Point"):ToAll()
|
local mark = MARKER:New(coordinate,self.lid.."Patrol Point"):ToAll()
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -706,7 +795,7 @@ end
|
|||||||
--- Add a RECON patrol point to a Wing
|
--- Add a RECON patrol point to a Wing
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #string AirbaseName Name of the Wing's airbase
|
-- @param #string AirbaseName Name of the Wing's airbase
|
||||||
-- @param Core.Point#COORDINATE Coordinate.
|
-- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Defaults to 25000 feet.
|
-- @param #number Altitude Defaults to 25000 feet.
|
||||||
-- @param #number Speed Defaults to 300 knots.
|
-- @param #number Speed Defaults to 300 knots.
|
||||||
-- @param #number Heading Defaults to 90 degrees (East).
|
-- @param #number Heading Defaults to 90 degrees (East).
|
||||||
@@ -731,7 +820,7 @@ end
|
|||||||
--- Add a TANKER patrol point to a Wing
|
--- Add a TANKER patrol point to a Wing
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #string AirbaseName Name of the Wing's airbase
|
-- @param #string AirbaseName Name of the Wing's airbase
|
||||||
-- @param Core.Point#COORDINATE Coordinate.
|
-- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Defaults to 25000 feet.
|
-- @param #number Altitude Defaults to 25000 feet.
|
||||||
-- @param #number Speed Defaults to 300 knots.
|
-- @param #number Speed Defaults to 300 knots.
|
||||||
-- @param #number Heading Defaults to 90 degrees (East).
|
-- @param #number Heading Defaults to 90 degrees (East).
|
||||||
@@ -756,7 +845,7 @@ end
|
|||||||
--- Add an AWACS patrol point to a Wing
|
--- Add an AWACS patrol point to a Wing
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #string AirbaseName Name of the Wing's airbase
|
-- @param #string AirbaseName Name of the Wing's airbase
|
||||||
-- @param Core.Point#COORDINATE Coordinate.
|
-- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
|
||||||
-- @param #number Altitude Defaults to 25000 feet.
|
-- @param #number Altitude Defaults to 25000 feet.
|
||||||
-- @param #number Speed Defaults to 300 knots.
|
-- @param #number Speed Defaults to 300 knots.
|
||||||
-- @param #number Heading Defaults to 90 degrees (East).
|
-- @param #number Heading Defaults to 90 degrees (East).
|
||||||
@@ -844,8 +933,13 @@ function EASYGCICAP:_SetCAPPatrolPoints()
|
|||||||
local Speed = data.Speed
|
local Speed = data.Speed
|
||||||
local Heading = data.Heading
|
local Heading = data.Heading
|
||||||
local LegLength = data.LegLength
|
local LegLength = data.LegLength
|
||||||
|
local Zone = _data.Zone
|
||||||
|
if Zone then
|
||||||
|
Wing:AddPatrolPointCAP(Zone,Altitude,Speed,Heading,LegLength)
|
||||||
|
else
|
||||||
Wing:AddPatrolPointCAP(Coordinate,Altitude,Speed,Heading,LegLength)
|
Wing:AddPatrolPointCAP(Coordinate,Altitude,Speed,Heading,LegLength)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1199,19 +1293,19 @@ end
|
|||||||
-- @return #boolean assigned
|
-- @return #boolean assigned
|
||||||
-- @return #number leftover
|
-- @return #number leftover
|
||||||
function EASYGCICAP:_TryAssignIntercept(ReadyFlightGroups,InterceptAuftrag,Group,WingSize)
|
function EASYGCICAP:_TryAssignIntercept(ReadyFlightGroups,InterceptAuftrag,Group,WingSize)
|
||||||
self:I("_TryAssignIntercept for size "..WingSize or 1)
|
self:T("_TryAssignIntercept for size "..WingSize or 1)
|
||||||
local assigned = false
|
local assigned = false
|
||||||
local wingsize = WingSize or 1
|
local wingsize = WingSize or 1
|
||||||
local mindist = 0
|
local mindist = 0
|
||||||
local disttable = {}
|
local disttable = {}
|
||||||
if Group and Group:IsAlive() then
|
if Group and Group:IsAlive() then
|
||||||
local gcoord = Group:GetCoordinate() or COORDINATE:New(0,0,0)
|
local gcoord = Group:GetCoordinate() or COORDINATE:New(0,0,0)
|
||||||
self:I(self.lid..string.format("Assignment for %s",Group:GetName()))
|
self:T(self.lid..string.format("Assignment for %s",Group:GetName()))
|
||||||
for _name,_FG in pairs(ReadyFlightGroups or {}) do
|
for _name,_FG in pairs(ReadyFlightGroups or {}) do
|
||||||
local FG = _FG -- Ops.FlightGroup#FLIGHTGROUP
|
local FG = _FG -- Ops.FlightGroup#FLIGHTGROUP
|
||||||
local fcoord = FG:GetCoordinate()
|
local fcoord = FG:GetCoordinate()
|
||||||
local dist = math.floor(UTILS.Round(fcoord:Get2DDistance(gcoord)/1000,1))
|
local dist = math.floor(UTILS.Round(fcoord:Get2DDistance(gcoord)/1000,1))
|
||||||
self:I(self.lid..string.format("FG %s Distance %dkm",_name,dist))
|
self:T(self.lid..string.format("FG %s Distance %dkm",_name,dist))
|
||||||
disttable[#disttable+1] = { FG=FG, dist=dist}
|
disttable[#disttable+1] = { FG=FG, dist=dist}
|
||||||
if dist>mindist then mindist=dist end
|
if dist>mindist then mindist=dist end
|
||||||
end
|
end
|
||||||
@@ -1228,7 +1322,7 @@ function EASYGCICAP:_TryAssignIntercept(ReadyFlightGroups,InterceptAuftrag,Group
|
|||||||
local cm = FG:GetMissionCurrent()
|
local cm = FG:GetMissionCurrent()
|
||||||
if cm then cm:Cancel() end
|
if cm then cm:Cancel() end
|
||||||
wingsize = wingsize - 1
|
wingsize = wingsize - 1
|
||||||
self:I(self.lid..string.format("Assigned to FG %s Distance %dkm",FG:GetName(),_entry.dist))
|
self:T(self.lid..string.format("Assigned to FG %s Distance %dkm",FG:GetName(),_entry.dist))
|
||||||
if wingsize == 0 then
|
if wingsize == 0 then
|
||||||
assigned = true
|
assigned = true
|
||||||
break
|
break
|
||||||
@@ -1303,6 +1397,10 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
|||||||
local data = _data -- #EASYGCICAP.CapPoint
|
local data = _data -- #EASYGCICAP.CapPoint
|
||||||
local name = data.AirbaseName
|
local name = data.AirbaseName
|
||||||
local zonecoord = data.Coordinate
|
local zonecoord = data.Coordinate
|
||||||
|
if data.Zone then
|
||||||
|
-- refresh coordinate in case we have a (moving) zone
|
||||||
|
zonecoord = data.Zone:GetCoordinate()
|
||||||
|
end
|
||||||
local airwing = wings[name][1]
|
local airwing = wings[name][1]
|
||||||
local coa = AIRBASE:FindByName(name):GetCoalition()
|
local coa = AIRBASE:FindByName(name):GetCoalition()
|
||||||
local samecoalitionab = coa == self.coalition and true or false
|
local samecoalitionab = coa == self.coalition and true or false
|
||||||
@@ -1404,7 +1502,7 @@ function EASYGCICAP:_StartIntel()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- FSM Functions
|
-- TODO FSM Functions
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
--- (Internal) FSM Function onafterStart
|
--- (Internal) FSM Function onafterStart
|
||||||
@@ -1500,7 +1598,7 @@ function EASYGCICAP:onafterStatus(From,Event,To)
|
|||||||
local engage = FG:IsEngaging()
|
local engage = FG:IsEngaging()
|
||||||
local hasmissiles = FG:IsOutOfMissiles() == nil and true or false
|
local hasmissiles = FG:IsOutOfMissiles() == nil and true or false
|
||||||
local ready = hasmissiles and FG:IsFuelGood() and FG:IsAirborne()
|
local ready = hasmissiles and FG:IsFuelGood() and FG:IsAirborne()
|
||||||
--self:I(string.format("Flightgroup %s Engaging = %s Ready = %s",tostring(name),tostring(engage),tostring(ready)))
|
--self:T(string.format("Flightgroup %s Engaging = %s Ready = %s",tostring(name),tostring(engage),tostring(ready)))
|
||||||
if ready then
|
if ready then
|
||||||
self.ReadyFlightGroups[name] = FG
|
self.ReadyFlightGroups[name] = FG
|
||||||
end
|
end
|
||||||
@@ -1535,5 +1633,8 @@ end
|
|||||||
function EASYGCICAP:onafterStop(From,Event,To)
|
function EASYGCICAP:onafterStop(From,Event,To)
|
||||||
self:T({From,Event,To})
|
self:T({From,Event,To})
|
||||||
self.Intel:Stop()
|
self.Intel:Stop()
|
||||||
|
for _,_wing in pairs(self.wings or {}) do
|
||||||
|
_wing:Stop()
|
||||||
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2464,7 +2464,7 @@ end
|
|||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Payer Menu
|
-- Player Menu
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Create player menu.
|
--- Create player menu.
|
||||||
|
|||||||
@@ -4667,12 +4667,14 @@ function FLIGHTGROUP:GetParking(airbase)
|
|||||||
local coords={}
|
local coords={}
|
||||||
for clientname, client in pairs(clients) do
|
for clientname, client in pairs(clients) do
|
||||||
local template=_DATABASE:GetGroupTemplateFromUnitName(clientname)
|
local template=_DATABASE:GetGroupTemplateFromUnitName(clientname)
|
||||||
|
if template then
|
||||||
local units=template.units
|
local units=template.units
|
||||||
for i,unit in pairs(units) do
|
for i,unit in pairs(units) do
|
||||||
local coord=COORDINATE:New(unit.x, unit.alt, unit.y)
|
local coord=COORDINATE:New(unit.x, unit.alt, unit.y)
|
||||||
coords[unit.name]=coord
|
coords[unit.name]=coord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return coords
|
return coords
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5730,7 +5730,7 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
|
|||||||
-- Decrease patrol data.
|
-- Decrease patrol data.
|
||||||
if Mission.patroldata then
|
if Mission.patroldata then
|
||||||
Mission.patroldata.noccupied=Mission.patroldata.noccupied-1
|
Mission.patroldata.noccupied=Mission.patroldata.noccupied-1
|
||||||
AIRWING.UpdatePatrolPointMarker(Mission.patroldata)
|
AIRWING.UpdatePatrolPointMarker(self,Mission.patroldata)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Switch auto engage detected off. This IGNORES that engage detected had been activated for the group!
|
-- Switch auto engage detected off. This IGNORES that engage detected had been activated for the group!
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ end
|
|||||||
|
|
||||||
--- Checks if a point is contained within the circle.
|
--- Checks if a point is contained within the circle.
|
||||||
-- @param #table point The point to check
|
-- @param #table point The point to check
|
||||||
-- @return #bool True if the point is contained, false otherwise
|
-- @return #boolean True if the point is contained, false otherwise
|
||||||
function CIRCLE:ContainsPoint(point)
|
function CIRCLE:ContainsPoint(point)
|
||||||
if ((point.x - self.CenterVec2.x) ^ 2 + (point.y - self.CenterVec2.y) ^ 2) ^ 0.5 <= self.Radius then
|
if ((point.x - self.CenterVec2.x) ^ 2 + (point.y - self.CenterVec2.y) ^ 2) ^ 0.5 <= self.Radius then
|
||||||
return true
|
return true
|
||||||
@@ -226,6 +226,11 @@ end
|
|||||||
--- Returns a random Vec2 within the circle.
|
--- Returns a random Vec2 within the circle.
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function CIRCLE:GetRandomVec2()
|
function CIRCLE:GetRandomVec2()
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
local angle = math.random() * 2 * math.pi
|
local angle = math.random() * 2 * math.pi
|
||||||
|
|
||||||
local rx = math.random(0, self.Radius) * math.cos(angle) + self.CenterVec2.x
|
local rx = math.random(0, self.Radius) * math.cos(angle) + self.CenterVec2.x
|
||||||
@@ -237,6 +242,11 @@ end
|
|||||||
--- Returns a random Vec2 on the border of the circle.
|
--- Returns a random Vec2 on the border of the circle.
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function CIRCLE:GetRandomVec2OnBorder()
|
function CIRCLE:GetRandomVec2OnBorder()
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
local angle = math.random() * 2 * math.pi
|
local angle = math.random() * 2 * math.pi
|
||||||
|
|
||||||
local rx = self.Radius * math.cos(angle) + self.CenterVec2.x
|
local rx = self.Radius * math.cos(angle) + self.CenterVec2.x
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ end
|
|||||||
--- Returns a random Vec2 within the polygon. The Vec2 is weighted by the areas of the triangles that make up the polygon.
|
--- Returns a random Vec2 within the polygon. The Vec2 is weighted by the areas of the triangles that make up the polygon.
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function POLYGON:GetRandomVec2()
|
function POLYGON:GetRandomVec2()
|
||||||
|
|
||||||
local weights = {}
|
local weights = {}
|
||||||
for _, triangle in pairs(self.Triangles) do
|
for _, triangle in pairs(self.Triangles) do
|
||||||
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ end
|
|||||||
-- @param #table points The points of the triangle, or 3 other points if you're just using the TRIANGLE class without an object of it
|
-- @param #table points The points of the triangle, or 3 other points if you're just using the TRIANGLE class without an object of it
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function TRIANGLE:GetRandomVec2(points)
|
function TRIANGLE:GetRandomVec2(points)
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
points = points or self.Points
|
points = points or self.Points
|
||||||
local pt = {math.random(), math.random()}
|
local pt = {math.random(), math.random()}
|
||||||
table.sort(pt)
|
table.sort(pt)
|
||||||
|
|||||||
@@ -443,28 +443,32 @@ MSRS.Voices = {
|
|||||||
["en_AU_Standard_B"] = 'en-AU-Standard-B', -- [2] MALE
|
["en_AU_Standard_B"] = 'en-AU-Standard-B', -- [2] MALE
|
||||||
["en_AU_Standard_C"] = 'en-AU-Standard-C', -- [3] FEMALE
|
["en_AU_Standard_C"] = 'en-AU-Standard-C', -- [3] FEMALE
|
||||||
["en_AU_Standard_D"] = 'en-AU-Standard-D', -- [4] MALE
|
["en_AU_Standard_D"] = 'en-AU-Standard-D', -- [4] MALE
|
||||||
["en_IN_Standard_A"] = 'en-IN-Standard-A', -- [5] FEMALE
|
-- IN
|
||||||
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- [6] MALE
|
["en_IN_Standard_A"] = 'en-IN-Standard-A', -- Female
|
||||||
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- [7] MALE
|
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- Male
|
||||||
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- [8] FEMALE
|
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- Male
|
||||||
|
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- Female
|
||||||
|
["en_IN_Standard_E"] = 'en-IN-Standard-E', -- Female
|
||||||
|
["en_IN_Standard_F"] = 'en-IN-Standard-F', -- Male
|
||||||
-- 2025 changes
|
-- 2025 changes
|
||||||
["en_GB_Standard_A"] = 'en-GB-Standard-N', -- [9] FEMALE
|
["en_GB_Standard_A"] = 'en-GB-Standard-A', -- Female
|
||||||
["en_GB_Standard_B"] = 'en-GB-Standard-O', -- [10] MALE
|
["en_GB_Standard_B"] = 'en-GB-Standard-B', -- Male
|
||||||
["en_GB_Standard_C"] = 'en-GB-Standard-N', -- [11] FEMALE
|
["en_GB_Standard_C"] = 'en-GB-Standard-C', -- Female
|
||||||
["en_GB_Standard_D"] = 'en-GB-Standard-O', -- [12] MALE
|
["en_GB_Standard_D"] = 'en-GB-Standard-D', -- Male
|
||||||
["en_GB_Standard_F"] = 'en-GB-Standard-N', -- [13] FEMALE
|
["en_GB_Standard_F"] = 'en-GB-Standard-F', -- Female
|
||||||
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- [12] MALE
|
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- Female
|
||||||
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- [13] FEMALE
|
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- Male
|
||||||
["en_US_Standard_A"] = 'en-US-Standard-A', -- [14] MALE
|
-- US
|
||||||
["en_US_Standard_B"] = 'en-US-Standard-B', -- [15] MALE
|
["en_US_Standard_A"] = 'en-US-Standard-A', -- Male
|
||||||
["en_US_Standard_C"] = 'en-US-Standard-C', -- [16] FEMALE
|
["en_US_Standard_B"] = 'en-US-Standard-B', -- Male
|
||||||
["en_US_Standard_D"] = 'en-US-Standard-D', -- [17] MALE
|
["en_US_Standard_C"] = 'en-US-Standard-C', -- Female
|
||||||
["en_US_Standard_E"] = 'en-US-Standard-E', -- [18] FEMALE
|
["en_US_Standard_D"] = 'en-US-Standard-D', -- Male
|
||||||
["en_US_Standard_F"] = 'en-US-Standard-F', -- [19] FEMALE
|
["en_US_Standard_E"] = 'en-US-Standard-E', -- Female
|
||||||
["en_US_Standard_G"] = 'en-US-Standard-G', -- [20] FEMALE
|
["en_US_Standard_F"] = 'en-US-Standard-F', -- Female
|
||||||
["en_US_Standard_H"] = 'en-US-Standard-H', -- [21] FEMALE
|
["en_US_Standard_G"] = 'en-US-Standard-G', -- Female
|
||||||
["en_US_Standard_I"] = 'en-US-Standard-I', -- [22] MALE
|
["en_US_Standard_H"] = 'en-US-Standard-H', -- Female
|
||||||
["en_US_Standard_J"] = 'en-US-Standard-J', -- [23] MALE
|
["en_US_Standard_I"] = 'en-US-Standard-I', -- Male
|
||||||
|
["en_US_Standard_J"] = 'en-US-Standard-J', -- Male
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["fr_FR_Standard_A"] = "fr-FR-Standard-F", -- Female
|
["fr_FR_Standard_A"] = "fr-FR-Standard-F", -- Female
|
||||||
["fr_FR_Standard_B"] = "fr-FR-Standard-G", -- Male
|
["fr_FR_Standard_B"] = "fr-FR-Standard-G", -- Male
|
||||||
@@ -474,14 +478,15 @@ MSRS.Voices = {
|
|||||||
["fr_FR_Standard_G"] = "fr-FR-Standard-G", -- Male
|
["fr_FR_Standard_G"] = "fr-FR-Standard-G", -- Male
|
||||||
["fr_FR_Standard_F"] = "fr-FR-Standard-F", -- Female
|
["fr_FR_Standard_F"] = "fr-FR-Standard-F", -- Female
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["de_DE_Standard_A"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_A"] = 'de-DE-Standard-A', -- Female
|
||||||
["de_DE_Standard_B"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_B"] = 'de-DE-Standard-B', -- Male
|
||||||
["de_DE_Standard_C"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_C"] = 'de-DE-Standard-C', -- Female
|
||||||
["de_DE_Standard_D"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_D"] = 'de-DE-Standard-D', -- Male
|
||||||
["de_DE_Standard_E"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_E"] = 'de-DE-Standard-E', -- Male
|
||||||
["de_DE_Standard_F"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_F"] = 'de-DE-Standard-F', -- Female
|
||||||
["de_DE_Standard_H"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_G"] = 'de-DE-Standard-G', -- Female
|
||||||
["de_DE_Standard_G"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_H"] = 'de-DE-Standard-H', -- Male
|
||||||
|
-- ES
|
||||||
["es_ES_Standard_A"] = "es-ES-Standard-E", -- Female
|
["es_ES_Standard_A"] = "es-ES-Standard-E", -- Female
|
||||||
["es_ES_Standard_B"] = "es-ES-Standard-F", -- Male
|
["es_ES_Standard_B"] = "es-ES-Standard-F", -- Male
|
||||||
["es_ES_Standard_C"] = "es-ES-Standard-E", -- Female
|
["es_ES_Standard_C"] = "es-ES-Standard-E", -- Female
|
||||||
@@ -497,32 +502,36 @@ MSRS.Voices = {
|
|||||||
["it_IT_Standard_F"] = "it-IT-Standard-F", -- Male
|
["it_IT_Standard_F"] = "it-IT-Standard-F", -- Male
|
||||||
},
|
},
|
||||||
Wavenet = {
|
Wavenet = {
|
||||||
["en_AU_Wavenet_A"] = 'en-AU-Wavenet-A', -- [1] FEMALE
|
["en_AU_Wavenet_A"] = 'en-AU-Wavenet-A', -- Female
|
||||||
["en_AU_Wavenet_B"] = 'en-AU-Wavenet-B', -- [2] MALE
|
["en_AU_Wavenet_B"] = 'en-AU-Wavenet-B', -- Male
|
||||||
["en_AU_Wavenet_C"] = 'en-AU-Wavenet-C', -- [3] FEMALE
|
["en_AU_Wavenet_C"] = 'en-AU-Wavenet-C', -- Female
|
||||||
["en_AU_Wavenet_D"] = 'en-AU-Wavenet-D', -- [4] MALE
|
["en_AU_Wavenet_D"] = 'en-AU-Wavenet-D', -- Male
|
||||||
["en_IN_Wavenet_A"] = 'en-IN-Wavenet-A', -- [5] FEMALE
|
-- IN
|
||||||
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- [6] MALE
|
["en_IN_Wavenet_A"] = 'en-IN-Wavenet-A', -- Female
|
||||||
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- [7] MALE
|
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- Male
|
||||||
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- [8] FEMALE
|
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- Male
|
||||||
|
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- Female
|
||||||
|
["en_IN_Wavenet_E"] = 'en-IN-Wavenet-E', -- Female
|
||||||
|
["en_IN_Wavenet_F"] = 'en-IN-Wavenet-F', -- Male
|
||||||
-- 2025 changes
|
-- 2025 changes
|
||||||
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-N', -- [9] FEMALE
|
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-A', -- [9] FEMALE
|
||||||
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-O', -- [10] MALE
|
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-B', -- [10] MALE
|
||||||
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-N', -- [11] FEMALE
|
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-C', -- [11] FEMALE
|
||||||
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-O', -- [12] MALE
|
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-D', -- [12] MALE
|
||||||
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-F', -- [13] FEMALE
|
||||||
["en_GB_Wavenet_O"] = 'en-GB-Wavenet-O', -- [12] MALE
|
["en_GB_Wavenet_O"] = 'en-GB-Wavenet-O', -- [12] MALE
|
||||||
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
||||||
["en_US_Wavenet_A"] = 'en-US-Wavenet-A', -- [14] MALE
|
-- US
|
||||||
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- [15] MALE
|
["en_US_Wavenet_A"] = 'en-US-Wavenet-A', -- Male
|
||||||
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- [16] FEMALE
|
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- Male
|
||||||
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- [17] MALE
|
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- Female
|
||||||
["en_US_Wavenet_E"] = 'en-US-Wavenet-E', -- [18] FEMALE
|
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- Male
|
||||||
["en_US_Wavenet_F"] = 'en-US-Wavenet-F', -- [19] FEMALE
|
["en_US_Wavenet_E"] = 'en-US-Wavenet-E', -- Female
|
||||||
["en_US_Wavenet_G"] = 'en-US-Wavenet-G', -- [20] FEMALE
|
["en_US_Wavenet_F"] = 'en-US-Wavenet-F', -- Female
|
||||||
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- [21] FEMALE
|
["en_US_Wavenet_G"] = 'en-US-Wavenet-G', -- Female
|
||||||
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- [22] MALE
|
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- Female
|
||||||
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- [23] MALE
|
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- Male
|
||||||
|
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- Male
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-F", -- Female
|
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-F", -- Female
|
||||||
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-G", -- Male
|
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-G", -- Male
|
||||||
@@ -532,14 +541,15 @@ MSRS.Voices = {
|
|||||||
["fr_FR_Wavenet_G"] = "fr-FR-Wavenet-G", -- Male
|
["fr_FR_Wavenet_G"] = "fr-FR-Wavenet-G", -- Male
|
||||||
["fr_FR_Wavenet_F"] = "fr-FR-Wavenet-F", -- Female
|
["fr_FR_Wavenet_F"] = "fr-FR-Wavenet-F", -- Female
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["de_DE_Wavenet_A"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_A"] = 'de-DE-Wavenet-A', -- Female
|
||||||
["de_DE_Wavenet_B"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_B"] = 'de-DE-Wavenet-B', -- Male
|
||||||
["de_DE_Wavenet_C"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_C"] = 'de-DE-Wavenet-C', -- Female
|
||||||
["de_DE_Wavenet_D"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_D"] = 'de-DE-Wavenet-D', -- Male
|
||||||
["de_DE_Wavenet_E"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_E"] = 'de-DE-Wavenet-E', -- Male
|
||||||
["de_DE_Wavenet_F"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_F"] = 'de-DE-Wavenet-F', -- Female
|
||||||
["de_DE_Wavenet_H"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_G"] = 'de-DE-Wavenet-G', -- Female
|
||||||
["de_DE_Wavenet_G"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_H"] = 'de-DE-Wavenet-H', -- Male
|
||||||
|
-- ES
|
||||||
["es_ES_Wavenet_B"] = "es-ES-Wavenet-E", -- Male
|
["es_ES_Wavenet_B"] = "es-ES-Wavenet-E", -- Male
|
||||||
["es_ES_Wavenet_C"] = "es-ES-Wavenet-F", -- Female
|
["es_ES_Wavenet_C"] = "es-ES-Wavenet-F", -- Female
|
||||||
["es_ES_Wavenet_D"] = "es-ES-Wavenet-E", -- Female
|
["es_ES_Wavenet_D"] = "es-ES-Wavenet-E", -- Female
|
||||||
@@ -553,6 +563,134 @@ MSRS.Voices = {
|
|||||||
["it_IT_Wavenet_E"] = "it-IT-Wavenet-E", -- Female
|
["it_IT_Wavenet_E"] = "it-IT-Wavenet-E", -- Female
|
||||||
["it_IT_Wavenet_F"] = "it-IT-Wavenet-F", -- Male
|
["it_IT_Wavenet_F"] = "it-IT-Wavenet-F", -- Male
|
||||||
} ,
|
} ,
|
||||||
|
Chirp3HD = {
|
||||||
|
["en_GB_Chirp3_HD_Aoede"] = 'en-GB-Chirp3-HD-Aoede', -- Female
|
||||||
|
["en_GB_Chirp3_HD_Charon"] = 'en-GB-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Fenrir"] = 'en-GB-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Kore"] = 'en-GB-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_GB_Chirp3_HD_Leda"] = 'en-GB-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_GB_Chirp3_HD_Orus"] = 'en-GB-Chirp3-HD-Orus', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Puck"] = 'en-GB-Chirp3-HD-Puck', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Zephyr"] = 'en-GB-Chirp3-HD-Zephyr', -- Female
|
||||||
|
--["de_DE_Chirp3_HD_Aoede"] = 'de-DE-Chirp3-HD-Aoede', -- Female (Datenfehler im Original)
|
||||||
|
["en_US_Chirp3_HD_Charon"] = 'en-US-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_US_Chirp3_HD_Fenrir"] = 'en-US-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_US_Chirp3_HD_Kore"] = 'en-US-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_US_Chirp3_HD_Leda"] = 'en-US-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_US_Chirp3_HD_Orus"] = 'en-US-Chirp3-HD-Orus', -- Male
|
||||||
|
["en_US_Chirp3_HD_Puck"] = 'en-US-Chirp3-HD-Puck', -- Male
|
||||||
|
--["de_DE_Chirp3_HD_Zephyr"] = 'de-DE-Chirp3-HD-Zephyr', -- Female (Datenfehler im Original)
|
||||||
|
-- DE
|
||||||
|
["de_DE_Chirp3_HD_Aoede"] = 'de-DE-Chirp3-HD-Aoede', -- Female
|
||||||
|
["de_DE_Chirp3_HD_Charon"] = 'de-DE-Chirp3-HD-Charon', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Fenrir"] = 'de-DE-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Kore"] = 'de-DE-Chirp3-HD-Kore', -- Female
|
||||||
|
["de_DE_Chirp3_HD_Leda"] = 'de-DE-Chirp3-HD-Leda', -- Female
|
||||||
|
["de_DE_Chirp3_HD_Orus"] = 'de-DE-Chirp3-HD-Orus', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Puck"] = 'de-DE-Chirp3-HD-Puck', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Zephyr"] = 'de-DE-Chirp3-HD-Zephyr', -- Female
|
||||||
|
-- AU
|
||||||
|
["en_AU_Chirp3_HD_Aoede"] = 'en-AU-Chirp3-HD-Aoede', -- Female
|
||||||
|
["en_AU_Chirp3_HD_Charon"] = 'en-AU-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Fenrir"] = 'en-AU-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Kore"] = 'en-AU-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_AU_Chirp3_HD_Leda"] = 'en-AU-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_AU_Chirp3_HD_Orus"] = 'en-AU-Chirp3-HD-Orus', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Puck"] = 'en-AU-Chirp3-HD-Puck', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Zephyr"] = 'en-AU-Chirp3-HD-Zephyr', -- Female
|
||||||
|
-- IN
|
||||||
|
["en_IN_Chirp3_HD_Aoede"] = 'en-IN-Chirp3-HD-Aoede', -- Female
|
||||||
|
["en_IN_Chirp3_HD_Charon"] = 'en-IN-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_IN_Chirp3_HD_Fenrir"] = 'en-IN-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_IN_Chirp3_HD_Kore"] = 'en-IN-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_IN_Chirp3_HD_Leda"] = 'en-IN-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_IN_Chirp3_HD_Orus"] = 'en-IN-Chirp3-HD-Orus', -- Male
|
||||||
|
},
|
||||||
|
ChirpHD = {
|
||||||
|
["en_US_Chirp_HD_D"] = 'en-US-Chirp-HD-D', -- Male
|
||||||
|
["en_US_Chirp_HD_F"] = 'en-US-Chirp-HD-F', -- Female
|
||||||
|
["en_US_Chirp_HD_O"] = 'en-US-Chirp-HD-O', -- Female
|
||||||
|
-- DE
|
||||||
|
["de_DE_Chirp_HD_D"] = 'de-DE-Chirp-HD-D', -- Male
|
||||||
|
["de_DE_Chirp_HD_F"] = 'de-DE-Chirp-HD-F', -- Female
|
||||||
|
["de_DE_Chirp_HD_O"] = 'de-DE-Chirp-HD-O', -- Female
|
||||||
|
-- AU
|
||||||
|
["en_AU_Chirp_HD_D"] = 'en-AU-Chirp-HD-D', -- Male
|
||||||
|
["en_AU_Chirp_HD_F"] = 'en-AU-Chirp-HD-F', -- Female
|
||||||
|
["en_AU_Chirp_HD_O"] = 'en-AU-Chirp-HD-O', -- Female
|
||||||
|
-- IN
|
||||||
|
["en_IN_Chirp_HD_D"] = 'en-IN-Chirp-HD-D', -- Male
|
||||||
|
["en_IN_Chirp_HD_F"] = 'en-IN-Chirp-HD-F', -- Female
|
||||||
|
["en_IN_Chirp_HD_O"] = 'en-IN-Chirp-HD-O', -- Female
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Neural2 = {
|
||||||
|
["en_GB_Neural2_A"] = 'en-GB-Neural2-A', -- Female
|
||||||
|
["en_GB_Neural2_B"] = 'en-GB-Neural2-B', -- Male
|
||||||
|
["en_GB_Neural2_C"] = 'en-GB-Neural2-C', -- Female
|
||||||
|
["en_GB_Neural2_D"] = 'en-GB-Neural2-D', -- Male
|
||||||
|
["en_GB_Neural2_F"] = 'en-GB-Neural2-F', -- Female
|
||||||
|
["en_GB_Neural2_N"] = 'en-GB-Neural2-N', -- Female
|
||||||
|
["en_GB_Neural2_O"] = 'en-GB-Neural2-O', -- Male
|
||||||
|
-- US
|
||||||
|
["en_US_Neural2_A"] = 'en-US-Neural2-A', -- Male
|
||||||
|
["en_US_Neural2_C"] = 'en-US-Neural2-C', -- Female
|
||||||
|
["en_US_Neural2_D"] = 'en-US-Neural2-D', -- Male
|
||||||
|
["en_US_Neural2_E"] = 'en-US-Neural2-E', -- Female
|
||||||
|
["en_US_Neural2_F"] = 'en-US-Neural2-F', -- Female
|
||||||
|
["en_US_Neural2_G"] = 'en-US-Neural2-G', -- Female
|
||||||
|
["en_US_Neural2_H"] = 'en-US-Neural2-H', -- Female
|
||||||
|
["en_US_Neural2_I"] = 'en-US-Neural2-I', -- Male
|
||||||
|
["en_US_Neural2_J"] = 'en-US-Neural2-J', -- Male
|
||||||
|
-- DE
|
||||||
|
["de_DE_Neural2_G"] = 'de-DE-Neural2-G', -- Female
|
||||||
|
["de_DE_Neural2_H"] = 'de-DE-Neural2-H', -- Male
|
||||||
|
-- AU
|
||||||
|
["en_AU_Neural2_A"] = 'en-AU-Neural2-A', -- Female
|
||||||
|
["en_AU_Neural2_B"] = 'en-AU-Neural2-B', -- Male
|
||||||
|
["en_AU_Neural2_C"] = 'en-AU-Neural2-C', -- Female
|
||||||
|
["en_AU_Neural2_D"] = 'en-AU-Neural2-D', -- Male
|
||||||
|
-- IN
|
||||||
|
["en_IN_Neural2_A"] = 'en-IN-Neural2-A', -- Female
|
||||||
|
["en_IN_Neural2_B"] = 'en-IN-Neural2-B', -- Male
|
||||||
|
["en_IN_Neural2_C"] = 'en-IN-Neural2-C', -- Male
|
||||||
|
["en_IN_Neural2_D"] = 'en-IN-Neural2-D', -- Female
|
||||||
|
},
|
||||||
|
News = {
|
||||||
|
["en_GB_News_G"] = 'en-GB-News-G', -- Female
|
||||||
|
["en_GB_News_H"] = 'en-GB-News-H', -- Female
|
||||||
|
["en_GB_News_I"] = 'en-GB-News-I', -- Female
|
||||||
|
["en_GB_News_J"] = 'en-GB-News-J', -- Male
|
||||||
|
["en_GB_News_K"] = 'en-GB-News-K', -- Male
|
||||||
|
["en_GB_News_L"] = 'en-GB-News-L', -- Male
|
||||||
|
["en_GB_News_M"] = 'en-GB-News-M', -- Male
|
||||||
|
-- US
|
||||||
|
["en_US_News_K"] = 'en-US-News-K', -- Female
|
||||||
|
["en_US_News_L"] = 'en-US-News-L', -- Female
|
||||||
|
["en_US_News_N"] = 'en-US-News-N', -- Male
|
||||||
|
-- AU
|
||||||
|
["en_AU_News_E"] = 'en-AU-News-E', -- Female
|
||||||
|
["en_AU_News_F"] = 'en-AU-News-F', -- Female
|
||||||
|
["en_AU_News_G"] = 'en-AU-News-G', -- Male
|
||||||
|
},
|
||||||
|
Casual = {
|
||||||
|
["en_US_Casual_K"] = 'en-US-Casual-K', -- Male
|
||||||
|
},
|
||||||
|
Polyglot = {
|
||||||
|
["en_US_Polyglot_1"] = 'en-US-Polyglot-1', -- Male
|
||||||
|
["de_DE_Polyglot_1"] = 'de-DE-Polyglot-1', -- Male
|
||||||
|
["en_AU_Polyglot_1"] = 'en-AU-Polyglot-1', -- Male
|
||||||
|
},
|
||||||
|
Studio = {
|
||||||
|
-- Englisch (UK) - Studio
|
||||||
|
["en_GB_Studio_B"] = 'en-GB-Studio-B', -- Male
|
||||||
|
["en_GB_Studio_C"] = 'en-GB-Studio-C', -- Female
|
||||||
|
-- Englisch (USA) - Studio
|
||||||
|
["en_US_Studio_O"] = 'en-US-Studio-O', -- Female
|
||||||
|
["en_US_Studio_Q"] = 'en-US-Studio-Q', -- Male
|
||||||
|
-- DE
|
||||||
|
["de_DE_Studio_B"] = 'de-DE-Studio-B', -- Male
|
||||||
|
["de_DE_Studio_C"] = 'de-DE-Studio-C', -- Female
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4593,13 +4593,166 @@ function UTILS.GetEnvZone(name)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- net.dostring_in
|
||||||
|
function UTILS.DoStringIn(State,DoString)
|
||||||
|
return net.dostring_in(State,DoString)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to all
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToAll(FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture(\"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Coalition
|
||||||
|
-- @param #number Coalition Coalition ID, can be coalition.side.BLUE, coalition.side.RED or coalition.side.NEUTRAL
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToCoalition(Coalition, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
local coalName = string.lower(UTILS.GetCoalitionName(Coalition))
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_s(\"%s\", \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", coalName, FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Country
|
||||||
|
-- @param #number Country Country ID, can be country.id.USA, country.id.RUSSIA, etc.
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToCountry(Country, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_c(%d, \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", Country, FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Group
|
||||||
|
-- @param Wrapper.Group#GROUP Group Group to show the picture to
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToGroup(Group, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_g(%d, \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", Group:GetID(), FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Unit
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit Unit to show the picture to
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToUnit(Unit, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_u(%d, \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", Unit:GetID(), FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Load a mission file. This will replace the current mission with the one given carrying along the online clients.
|
||||||
|
-- @param #string FileName Mission filename
|
||||||
|
function UTILS.LoadMission(FileName)
|
||||||
|
net.dostring_in("mission", string.format("a_load_mission(\"%s\")", FileName))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the mission briefing for a coalition.
|
||||||
|
-- @param #number Coalition Briefing coalition ID, can be coalition.side.BLUE, coalition.side.RED or coalition.side.NEUTRAL
|
||||||
|
-- @param #string Text Briefing text, can contain newlines, will be converted formatted properly for DCS
|
||||||
|
-- @param #string Picture Picture file path, can be a file in the DEFAULT folder inside the .miz
|
||||||
|
function UTILS.SetMissionBriefing(Coalition, Text, Picture)
|
||||||
|
Text = Text or ""
|
||||||
|
Text = Text:gsub("\n", "\\n")
|
||||||
|
Picture = Picture or ""
|
||||||
|
local coalName = string.lower(UTILS.GetCoalitionName(Coalition))
|
||||||
|
net.dostring_in("mission", string.format("a_set_briefing(\"%s\", \"%s\", \"%s\")", coalName, Picture, Text))
|
||||||
|
end
|
||||||
|
|
||||||
--- Show a helper gate at a DCS#Vec3 position
|
--- Show a helper gate at a DCS#Vec3 position
|
||||||
-- @param DCS#Vec3 pos The position
|
-- @param DCS#Vec3 pos The position
|
||||||
-- @param number heading Heading in degrees, can be 0..359 degrees
|
-- @param #number heading Heading in degrees, can be 0..359 degrees
|
||||||
function UTILS.ShowHelperGate(pos, heading)
|
function UTILS.ShowHelperGate(pos, heading)
|
||||||
net.dostring_in("mission",string.format("a_show_helper_gate(%s, %s, %s, %f)", pos.x, pos.y, pos.z, math.rad(heading)))
|
net.dostring_in("mission",string.format("a_show_helper_gate(%s, %s, %s, %f)", pos.x, pos.y, pos.z, math.rad(heading)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Show a helper gate for a unit.
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The unit to show the gate for
|
||||||
|
-- @param #number Flag Helper gate flag
|
||||||
|
function UTILS.ShowHelperGateForUnit(Unit, Flag)
|
||||||
|
net.dostring_in("mission",string.format("a_show_route_gates_for_unit(%d, \"%d\")", Unit:GetID(), Flag))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the carrier illumination mode. -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
-- @param #number UnitID Carrier unit ID ( UNIT:GetID() )
|
||||||
|
-- @param #number Mode Illumination mode, can be -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
function UTILS.SetCarrierIlluminationMode(UnitID, Mode)
|
||||||
|
net.dostring_in("mission",string.format("a_set_carrier_illumination_mode(%d, %d)", UnitID, Mode))
|
||||||
|
end
|
||||||
|
|
||||||
--- Shell a zone, zone must ME created
|
--- Shell a zone, zone must ME created
|
||||||
-- @param #string name The name of the ME created zone
|
-- @param #string name The name of the ME created zone
|
||||||
-- @param #number power Equals kg of TNT, e.g. 75
|
-- @param #number power Equals kg of TNT, e.g. 75
|
||||||
|
|||||||
@@ -736,15 +736,19 @@ AIRBASE.SouthAtlantic={
|
|||||||
-- * AIRBASE.Sinai.Kibrit_Air_Base
|
-- * AIRBASE.Sinai.Kibrit_Air_Base
|
||||||
-- * AIRBASE.Sinai.Kom_Awshim
|
-- * AIRBASE.Sinai.Kom_Awshim
|
||||||
-- * AIRBASE.Sinai.Melez
|
-- * AIRBASE.Sinai.Melez
|
||||||
|
-- * AIRBASE.Sinai.Mezzeh_Air_Base
|
||||||
-- * AIRBASE.Sinai.Nevatim
|
-- * AIRBASE.Sinai.Nevatim
|
||||||
-- * AIRBASE.Sinai.Ovda
|
-- * AIRBASE.Sinai.Ovda
|
||||||
-- * AIRBASE.Sinai.Palmachim
|
-- * AIRBASE.Sinai.Palmachim
|
||||||
-- * AIRBASE.Sinai.Quwaysina
|
-- * AIRBASE.Sinai.Quwaysina
|
||||||
|
-- * AIRBASE.Sinai.Rafic_Hariri_Intl
|
||||||
|
-- * AIRBASE.Sinai.Ramat_David
|
||||||
-- * AIRBASE.Sinai.Ramon_Airbase
|
-- * AIRBASE.Sinai.Ramon_Airbase
|
||||||
-- * AIRBASE.Sinai.Ramon_International_Airport
|
-- * AIRBASE.Sinai.Ramon_International_Airport
|
||||||
-- * AIRBASE.Sinai.Sde_Dov
|
-- * AIRBASE.Sinai.Sde_Dov
|
||||||
-- * AIRBASE.Sinai.Sharm_El_Sheikh_International_Airport
|
-- * AIRBASE.Sinai.Sharm_El_Sheikh_International_Airport
|
||||||
-- * AIRBASE.Sinai.St_Catherine
|
-- * AIRBASE.Sinai.St_Catherine
|
||||||
|
-- * AIRBASE.Sinai.Tabuk
|
||||||
-- * AIRBASE.Sinai.Tel_Nof
|
-- * AIRBASE.Sinai.Tel_Nof
|
||||||
-- * AIRBASE.Sinai.Wadi_Abu_Rish
|
-- * AIRBASE.Sinai.Wadi_Abu_Rish
|
||||||
-- * AIRBASE.Sinai.Wadi_al_Jandali
|
-- * AIRBASE.Sinai.Wadi_al_Jandali
|
||||||
@@ -784,15 +788,19 @@ AIRBASE.Sinai = {
|
|||||||
["Kibrit_Air_Base"] = "Kibrit Air Base",
|
["Kibrit_Air_Base"] = "Kibrit Air Base",
|
||||||
["Kom_Awshim"] = "Kom Awshim",
|
["Kom_Awshim"] = "Kom Awshim",
|
||||||
["Melez"] = "Melez",
|
["Melez"] = "Melez",
|
||||||
|
["Mezzeh_Air_Base"] = "Mezzeh Air Base",
|
||||||
["Nevatim"] = "Nevatim",
|
["Nevatim"] = "Nevatim",
|
||||||
["Ovda"] = "Ovda",
|
["Ovda"] = "Ovda",
|
||||||
["Palmachim"] = "Palmachim",
|
["Palmachim"] = "Palmachim",
|
||||||
["Quwaysina"] = "Quwaysina",
|
["Quwaysina"] = "Quwaysina",
|
||||||
|
["Rafic_Hariri_Intl"] = "Rafic Hariri Intl",
|
||||||
|
["Ramat_David"] = "Ramat David",
|
||||||
["Ramon_Airbase"] = "Ramon Airbase",
|
["Ramon_Airbase"] = "Ramon Airbase",
|
||||||
["Ramon_International_Airport"] = "Ramon International Airport",
|
["Ramon_International_Airport"] = "Ramon International Airport",
|
||||||
["Sde_Dov"] = "Sde Dov",
|
["Sde_Dov"] = "Sde Dov",
|
||||||
["Sharm_El_Sheikh_International_Airport"] = "Sharm El Sheikh International Airport",
|
["Sharm_El_Sheikh_International_Airport"] = "Sharm El Sheikh International Airport",
|
||||||
["St_Catherine"] = "St Catherine",
|
["St_Catherine"] = "St Catherine",
|
||||||
|
["Tabuk"] = "Tabuk",
|
||||||
["Tel_Nof"] = "Tel Nof",
|
["Tel_Nof"] = "Tel Nof",
|
||||||
["Wadi_Abu_Rish"] = "Wadi Abu Rish",
|
["Wadi_Abu_Rish"] = "Wadi Abu Rish",
|
||||||
["Wadi_al_Jandali"] = "Wadi al Jandali",
|
["Wadi_al_Jandali"] = "Wadi al Jandali",
|
||||||
|
|||||||
@@ -1931,3 +1931,10 @@ end
|
|||||||
function UNIT:SetLife(Percent)
|
function UNIT:SetLife(Percent)
|
||||||
net.dostring_in("mission",string.format("a_unit_set_life_percentage(%d, %f)", self:GetID(), Percent))
|
net.dostring_in("mission",string.format("a_unit_set_life_percentage(%d, %f)", self:GetID(), Percent))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set the carrier illumination mode. -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @param #number Mode Illumination mode, can be -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
function UNIT:SetCarrierIlluminationMode(Mode)
|
||||||
|
UTILS.SetCarrierIlluminationMode(self:GetID(), Mode)
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user