mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
237 Commits
2.9.10
...
FF/MasterD
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28ae63bd8d | ||
|
|
42e7e3f94f | ||
|
|
24b47b02e0 | ||
|
|
cbcc893ce5 | ||
|
|
382b049c5f | ||
|
|
a53763221c | ||
|
|
b7bac28113 | ||
|
|
a9edb16554 | ||
|
|
0aeb1fc6af | ||
|
|
eeeeda4e5e | ||
|
|
f5881eda53 | ||
|
|
c1997d9f70 | ||
|
|
bb1caa6642 | ||
|
|
dd5ca93f26 | ||
|
|
1889df4952 | ||
|
|
7ca219748d | ||
|
|
2fc16ba694 | ||
|
|
a4feafab8e | ||
|
|
997baf21a0 | ||
|
|
b126cc00d0 | ||
|
|
09b7922b84 | ||
|
|
7a5b9a75f3 | ||
|
|
4bab2ee1de | ||
|
|
d7defe6f7f | ||
|
|
db869bcb6d | ||
|
|
ea4a1f9ff9 | ||
|
|
20406e40ca | ||
|
|
3b50fee5a0 | ||
|
|
804004198b | ||
|
|
5b8b8a5566 | ||
|
|
0468bacc0b | ||
|
|
7eba1349ae | ||
|
|
b6074a4795 | ||
|
|
36c9f551d9 | ||
|
|
89c3f7310b | ||
|
|
a6b622ed31 | ||
|
|
f1af3a50b8 | ||
|
|
0c90e90c18 | ||
|
|
f97ef25104 | ||
|
|
069c0aa03f | ||
|
|
b145588ed5 | ||
|
|
3ad60a95ce | ||
|
|
ac4b620f16 | ||
|
|
ccada18a6a | ||
|
|
1547d66327 | ||
|
|
8042e8bfaf | ||
|
|
dd7b87e9cd | ||
|
|
460d2768ff | ||
|
|
3c74272749 | ||
|
|
82c409d77a | ||
|
|
195aac4504 | ||
|
|
08d8f3e25f | ||
|
|
6f72697e26 | ||
|
|
0f6439cf9f | ||
|
|
2c10943cb1 | ||
|
|
544db963ea | ||
|
|
207698a2dd | ||
|
|
d1ae2c0f5e | ||
|
|
0392417189 | ||
|
|
be4beea9d0 | ||
|
|
5da899138b | ||
|
|
1ec1e00bde | ||
|
|
5d93b33d42 | ||
|
|
b2077bfc74 | ||
|
|
6fdf9a649f | ||
|
|
d013bbc751 | ||
|
|
e0092fdba0 | ||
|
|
fbeada439f | ||
|
|
6c8858d2f5 | ||
|
|
e2b77878df | ||
|
|
53d7972858 | ||
|
|
04a55e4104 | ||
|
|
d11acecdac | ||
|
|
49c11073e6 | ||
|
|
1a156e7e12 | ||
|
|
1856754614 | ||
|
|
6ac452ff15 | ||
|
|
d707a4775c | ||
|
|
ffccc31e38 | ||
|
|
0405af2bde | ||
|
|
e50e572c78 | ||
|
|
3083599158 | ||
|
|
b7b6c1ea19 | ||
|
|
5b107ce2da | ||
|
|
5c1e342a79 | ||
|
|
ddf33da787 | ||
|
|
b0a192a767 | ||
|
|
986c340211 | ||
|
|
2109537f86 | ||
|
|
690db7f12f | ||
|
|
4f3fd06cc9 | ||
|
|
4074023ed3 | ||
|
|
6c00b0c7eb | ||
|
|
76dc0d690a | ||
|
|
d783f7be99 | ||
|
|
b66e91b11f | ||
|
|
dc83af4d02 | ||
|
|
0a38700edb | ||
|
|
659615114a | ||
|
|
4955fe4d92 | ||
|
|
792aa73832 | ||
|
|
a915452e6e | ||
|
|
be8405b72b | ||
|
|
5ca3e3b2b8 | ||
|
|
618a8744a2 | ||
|
|
23aeef7a20 | ||
|
|
9ac4f136aa | ||
|
|
c9a09c2fc9 | ||
|
|
6028c91f81 | ||
|
|
3c57928f46 | ||
|
|
32f0bb33c3 | ||
|
|
31d0410284 | ||
|
|
87c436ba34 | ||
|
|
6e9727e265 | ||
|
|
94ee76fe62 | ||
|
|
ea23162ca9 | ||
|
|
683388faee | ||
|
|
56ec3920c5 | ||
|
|
f335ffc4ec | ||
|
|
4976cd86f2 | ||
|
|
c00eff8b23 | ||
|
|
3c710613a8 | ||
|
|
45ebf9a3c7 | ||
|
|
c808e4a4e2 | ||
|
|
e2612b97d7 | ||
|
|
70e9d91bb5 | ||
|
|
0b8810f8b3 | ||
|
|
41b867a4ca | ||
|
|
1c0a8d9380 | ||
|
|
2b0b9d44eb | ||
|
|
2fc7a3b542 | ||
|
|
12b596a47f | ||
|
|
8ef781a9ac | ||
|
|
43eeaede65 | ||
|
|
749c5f87de | ||
|
|
a520daeb56 | ||
|
|
f9ba96f228 | ||
|
|
a49bd23a2a | ||
|
|
cea2f18228 | ||
|
|
fd2d8a5119 | ||
|
|
fa4e0447dd | ||
|
|
31aa604fc4 | ||
|
|
f44db27565 | ||
|
|
9b1abab73a | ||
|
|
cad8f15b61 | ||
|
|
1d08bcf2e0 | ||
|
|
9487a5ae91 | ||
|
|
96337cc5df | ||
|
|
bc9eee22b7 | ||
|
|
f74d25b31c | ||
|
|
1156971d94 | ||
|
|
c79b5c37c4 | ||
|
|
a2b650a9e3 | ||
|
|
905b442e9b | ||
|
|
18fe3112bd | ||
|
|
cc057744ba | ||
|
|
db1779e1db | ||
|
|
d25a723fc7 | ||
|
|
f0fe1b431d | ||
|
|
8e286edd25 | ||
|
|
74520b1359 | ||
|
|
d06e44d37b | ||
|
|
35348d9b81 | ||
|
|
4b16e94eaf | ||
|
|
d983676330 | ||
|
|
03c30f3cce | ||
|
|
99b93266ad | ||
|
|
e307b57e67 | ||
|
|
5ef9bb2acd | ||
|
|
4aacdc1567 | ||
|
|
57552f4300 | ||
|
|
09d53f7d8c | ||
|
|
d9948d1a19 | ||
|
|
5f7a4f2bbb | ||
|
|
1b6945e0b0 | ||
|
|
4fd55b1bd6 | ||
|
|
20b8deb6de | ||
|
|
6af836c118 | ||
|
|
f87b8a2c2a | ||
|
|
daffd7412a | ||
|
|
bfb60b318e | ||
|
|
a55959dfbb | ||
|
|
4d24eb82be | ||
|
|
e26caa2f74 | ||
|
|
b75fff60c8 | ||
|
|
4ac57fce7a | ||
|
|
25a9a0120a | ||
|
|
66a1fa8af5 | ||
|
|
1b4033cfce | ||
|
|
48bc41873a | ||
|
|
068a1ab99c | ||
|
|
6551383070 | ||
|
|
b03978cc3d | ||
|
|
82f4c5790a | ||
|
|
5957124e9e | ||
|
|
92a05ca74a | ||
|
|
d02b5db6dd | ||
|
|
bd074728fe | ||
|
|
61b7b3ead6 | ||
|
|
7f7999e3e5 | ||
|
|
b522b38d31 | ||
|
|
b2dc7bc232 | ||
|
|
def622a02c | ||
|
|
30bedb39f1 | ||
|
|
fbcc4ee32b | ||
|
|
63c68d729b | ||
|
|
04f8f6d512 | ||
|
|
b74d46f762 | ||
|
|
02decc3901 | ||
|
|
dcdea16624 | ||
|
|
2635cf6345 | ||
|
|
e86069d39c | ||
|
|
fdcf153b0b | ||
|
|
8523b7e20a | ||
|
|
29b992bf81 | ||
|
|
4c52509d6d | ||
|
|
9bc067f2e8 | ||
|
|
5fbe0d9a70 | ||
|
|
474f767e56 | ||
|
|
f9030be843 | ||
|
|
538e35d8f0 | ||
|
|
203f0c8abc | ||
|
|
d0736b0b56 | ||
|
|
15b1ed028e | ||
|
|
008617a35c | ||
|
|
6144a61a2e | ||
|
|
5d192abd25 | ||
|
|
62337f445a | ||
|
|
b38c1c5827 | ||
|
|
c08cee2317 | ||
|
|
0f7759d070 | ||
|
|
4a0842bea6 | ||
|
|
3b3666c5f7 | ||
|
|
45912911ee | ||
|
|
9916afaa49 | ||
|
|
55c5a23616 | ||
|
|
6bee1cc88e |
@@ -1953,7 +1953,7 @@ local function refct_from_id(id) -- refct = refct_from_id(CTypeID)
|
|||||||
unsigned = refct.unsigned,
|
unsigned = refct.unsigned,
|
||||||
size = bit.band(bit.rshift(ctype.info, 16), 127),
|
size = bit.band(bit.rshift(ctype.info, 16), 127),
|
||||||
}
|
}
|
||||||
refct.bool, refct.const, refct.volatile, refct.unsigned = nil
|
refct.bool, refct.const, refct.volatile, refct.unsigned = nil, nil, nil, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if CT[4] then -- Merge sibling attributes onto this type.
|
if CT[4] then -- Merge sibling attributes onto this type.
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
--- The AI_A2A_CAP class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
|
--- The AI_A2A_CAP class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_A2A_CAP is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_CAP process can be started using the **Start** event.
|
-- The AI_A2A_CAP is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_CAP process can be started using the **Start** event.
|
||||||
|
|||||||
@@ -32,7 +32,9 @@
|
|||||||
-- [DCS WORLD - MOOSE - A2A GCICAP - Build an automatic A2A Defense System](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0S4KMNUUJpaUs6zZHjLKNx)
|
-- [DCS WORLD - MOOSE - A2A GCICAP - Build an automatic A2A Defense System](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0S4KMNUUJpaUs6zZHjLKNx)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
-- There are basically two classes available to model an A2A defense system.
|
-- There are basically two classes available to model an A2A defense system.
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_A2A_GCI is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
|
-- The AI_A2A_GCI is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
|
||||||
--
|
--
|
||||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}.
|
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_A2A_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_PATROL process can be started using the **Start** event.
|
-- The AI_A2A_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_PATROL process can be started using the **Start** event.
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
|
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
|
||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
--
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The following class is available to model an A2G defense system.
|
-- The following class is available to model an A2G defense system.
|
||||||
--
|
--
|
||||||
-- AI_A2G_DISPATCHER is the main A2G defense class that models the A2G defense system.
|
-- AI_A2G_DISPATCHER is the main A2G defense class that models the A2G defense system.
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
|
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
|
||||||
--
|
--
|
||||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
--- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}.
|
--- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- # 1) AI_AIR constructor
|
-- # 1) AI_AIR constructor
|
||||||
--
|
--
|
||||||
@@ -657,8 +658,8 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local FromRTBRoutePoint = FromCoord:WaypointAir(
|
local FromRTBRoutePoint = FromCoord:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
RTBSpeed,
|
RTBSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -666,8 +667,8 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToRTBRoutePoint = ToAirbaseCoord:WaypointAir(
|
local ToRTBRoutePoint = ToAirbaseCoord:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
RTBSpeed,
|
RTBSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -761,10 +762,10 @@ function AI_AIR:onafterRefuel( AIGroup, From, Event, To )
|
|||||||
local ToRefuelSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
local ToRefuelSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local FromRefuelRoutePoint = FromRefuelCoord:WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToRefuelSpeed, true)
|
local FromRefuelRoutePoint = FromRefuelCoord:WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToRefuelSpeed, true)
|
||||||
|
|
||||||
--- Create a route point of type air. NOT used!
|
--- Create a route point of type air. NOT used!
|
||||||
local ToRefuelRoutePoint = Tanker:GetCoordinate():WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToRefuelSpeed, true)
|
local ToRefuelRoutePoint = Tanker:GetCoordinate():WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToRefuelSpeed, true)
|
||||||
|
|
||||||
self:F( { ToRefuelSpeed = ToRefuelSpeed } )
|
self:F( { ToRefuelSpeed = ToRefuelSpeed } )
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
--
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The following class is available to model an AIR defense system.
|
-- The following class is available to model an AIR defense system.
|
||||||
--
|
--
|
||||||
-- AI_AIR_DISPATCHER is the main AIR defense class that models the AIR defense system.
|
-- AI_AIR_DISPATCHER is the main AIR defense class that models the AIR defense system.
|
||||||
|
|||||||
@@ -13,12 +13,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- @type AI_AIR_ENGAGE
|
--- @type AI_AIR_ENGAGE
|
||||||
-- @extends AI.AI_AIR#AI_AIR
|
-- @extends AI.AI_AIR#AI_AIR
|
||||||
|
|
||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_AIR_ENGAGE is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_ENGAGE process can be started using the **Start** event.
|
-- The AI_AIR_ENGAGE is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_ENGAGE process can be started using the **Start** event.
|
||||||
--
|
--
|
||||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
@@ -453,7 +455,7 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
|
|||||||
|
|
||||||
--- Calculate the target route point.
|
--- Calculate the target route point.
|
||||||
|
|
||||||
local FromWP = DefenderCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
local FromWP = DefenderCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = FromWP
|
EngageRoute[#EngageRoute+1] = FromWP
|
||||||
|
|
||||||
@@ -462,7 +464,7 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
|
|||||||
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
||||||
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
|
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
|
||||||
|
|
||||||
local ToWP = ToCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
local ToWP = ToCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = ToWP
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
@@ -536,7 +538,7 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
local AttackTasks = {}
|
local AttackTasks = {}
|
||||||
|
|
||||||
local FromWP = DefenderCoord:WaypointAir(self.EngageAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
local FromWP = DefenderCoord:WaypointAir(self.EngageAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
|
||||||
EngageRoute[#EngageRoute+1] = FromWP
|
EngageRoute[#EngageRoute+1] = FromWP
|
||||||
|
|
||||||
self:SetTargetDistance( TargetCoord ) -- For RTB status check
|
self:SetTargetDistance( TargetCoord ) -- For RTB status check
|
||||||
@@ -544,7 +546,7 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
||||||
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
|
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
|
||||||
|
|
||||||
local ToWP = ToCoord:WaypointAir(self.EngageAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
local ToWP = ToCoord:WaypointAir(self.EngageAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
|
||||||
EngageRoute[#EngageRoute+1] = ToWP
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
-- TODO: A factor of * 3 this way too low. This causes the AI NOT to engage until very close or even merged sometimes. Some A2A missiles have a much longer range! Needs more frequent updates of the task!
|
-- TODO: A factor of * 3 this way too low. This causes the AI NOT to engage until very close or even merged sometimes. Some A2A missiles have a much longer range! Needs more frequent updates of the task!
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
--- The AI_AIR_PATROL class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group}
|
--- The AI_AIR_PATROL class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_AIR_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_PATROL process can be started using the **Start** event.
|
-- The AI_AIR_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_PATROL process can be started using the **Start** event.
|
||||||
@@ -309,7 +311,7 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
|
|||||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||||
local speedkmh=ToTargetSpeed
|
local speedkmh=ToTargetSpeed
|
||||||
|
|
||||||
local FromWP = CurrentCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
|
local FromWP = CurrentCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToTargetSpeed, true)
|
||||||
PatrolRoute[#PatrolRoute+1] = FromWP
|
PatrolRoute[#PatrolRoute+1] = FromWP
|
||||||
|
|
||||||
if self.racetrack then
|
if self.racetrack then
|
||||||
@@ -359,9 +361,9 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
|
|||||||
else
|
else
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
|
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToTargetSpeed, true)
|
||||||
PatrolRoute[#PatrolRoute+1] = ToWP
|
PatrolRoute[#PatrolRoute+1] = ToWP
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
Tasks[#Tasks+1] = AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
|
Tasks[#Tasks+1] = AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
|
||||||
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- @type AI_AIR_SQUADRON
|
--- @type AI_AIR_SQUADRON
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to provide BattleGround Air Interdiction in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
--- Implements the core functions to provide BattleGround Air Interdiction in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_BAI_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
-- The AI_BAI_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
@@ -174,8 +176,7 @@ function AI_BAI_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
|
|||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
|
|
||||||
-- @return #boolean Return false to cancel Transition.
|
-- @return #boolean Return false to cancel Transition.
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Engage.
|
--- OnAfter Transition Handler for Event Engage.
|
||||||
@@ -522,12 +523,12 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
|
|||||||
|
|
||||||
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
local CurrentAltitude = self.Controllable:GetAltitude()
|
local CurrentAltitude = self.Controllable:GetAltitude()
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
self.EngageSpeed,
|
self.EngageSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -578,13 +579,13 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
|
|||||||
self:T2( ToTargetVec2 )
|
self:T2( ToTargetVec2 )
|
||||||
|
|
||||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
|
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
|
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
self.EngageSpeed,
|
self.EngageSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,8 +33,9 @@
|
|||||||
-- @field Wrapper.Group#GROUP Test
|
-- @field Wrapper.Group#GROUP Test
|
||||||
-- @extends Core.Fsm#FSM_SET
|
-- @extends Core.Fsm#FSM_SET
|
||||||
|
|
||||||
|
--- 
|
||||||
--- Monitors and manages as many replacement AI groups as there are
|
--
|
||||||
|
-- Monitors and manages as many replacement AI groups as there are
|
||||||
-- CLIENTS in a SET\_CLIENT collection, which are not occupied by human players.
|
-- CLIENTS in a SET\_CLIENT collection, which are not occupied by human players.
|
||||||
-- In other words, use AI_BALANCER to simulate human behaviour by spawning in replacement AI in multi player missions.
|
-- In other words, use AI_BALANCER to simulate human behaviour by spawning in replacement AI in multi player missions.
|
||||||
--
|
--
|
||||||
@@ -220,16 +221,9 @@ function AI_BALANCER:onenterReturning( SetGroup, From, Event, To, AIGroup )
|
|||||||
AIGroup:MessageToRed( "Returning to home base ...", 30 )
|
AIGroup:MessageToRed( "Returning to home base ...", 30 )
|
||||||
else
|
else
|
||||||
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
|
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
|
||||||
--TODO: i need to rework the POINT_VEC2 thing.
|
local PointVec2 = COORDINATE:New(AIGroup:GetVec2().x, 0, AIGroup:GetVec2().y)
|
||||||
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
|
|
||||||
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
|
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
|
||||||
self:T( ClosestAirbase.AirbaseName )
|
self:T( ClosestAirbase.AirbaseName )
|
||||||
--[[
|
|
||||||
AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 )
|
|
||||||
local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase )
|
|
||||||
AIGroupTemplate.route = RTBRoute
|
|
||||||
AIGroup:Respawn( AIGroupTemplate )
|
|
||||||
]]
|
|
||||||
AIGroup:RouteRTB(ClosestAirbase)
|
AIGroup:RouteRTB(ClosestAirbase)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}
|
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_CAP_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_CAP_ZONE process can be started using the **Start** event.
|
-- The AI_CAP_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_CAP_ZONE process can be started using the **Start** event.
|
||||||
@@ -423,12 +425,12 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
|
|
||||||
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
local CurrentAltitude = self.Controllable:GetAltitude()
|
local CurrentAltitude = self.Controllable:GetAltitude()
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
ToEngageZoneSpeed,
|
ToEngageZoneSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -445,13 +447,13 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
|
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
|
||||||
|
|
||||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
|
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir(
|
local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
ToTargetSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
|
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
|
||||||
|
|
||||||
--- Implements the core functions to provide Close Air Support in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
--- Implements the core functions to provide Close Air Support in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_CAS_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
-- The AI_CAS_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
@@ -466,12 +469,12 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
|
|||||||
|
|
||||||
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
local CurrentAltitude = self.Controllable:GetAltitude()
|
local CurrentAltitude = self.Controllable:GetAltitude()
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
self.EngageSpeed,
|
self.EngageSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -508,13 +511,13 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
|
|||||||
self:T2( ToTargetVec2 )
|
self:T2( ToTargetVec2 )
|
||||||
|
|
||||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
|
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
|
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
self.EngageSpeed,
|
self.EngageSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,12 +9,14 @@
|
|||||||
-- @module AI.AI_Cargo
|
-- @module AI.AI_Cargo
|
||||||
-- @image Cargo.JPG
|
-- @image Cargo.JPG
|
||||||
|
|
||||||
-- @type AI_CARGO
|
--- @type AI_CARGO
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||||
|
|
||||||
|
|
||||||
--- Base class for the dynamic cargo handling capability for AI groups.
|
--- Base class for the dynamic cargo handling capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
-- The AI_CARGO module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
-- CARGO derived objects must be declared within the mission to make the AI_CARGO object recognize the cargo.
|
-- CARGO derived objects must be declared within the mission to make the AI_CARGO object recognize the cargo.
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI vehicle group.
|
--- Brings a dynamic cargo handling capability for an AI vehicle group.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Armoured Personnel Carriers (APC), Trucks, Jeeps and other ground based carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Armoured Personnel Carriers (APC), Trucks, Jeeps and other ground based carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_APC class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_APC class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI airplane group.
|
--- Brings a dynamic cargo handling capability for an AI airplane group.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- Airplane carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation between airbases.
|
-- Airplane carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation between airbases.
|
||||||
--
|
--
|
||||||
@@ -440,7 +442,7 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed, Height, Uncontrolled
|
|||||||
|
|
||||||
-- To point.
|
-- To point.
|
||||||
local AirbasePointVec2 = Airbase:GetPointVec2()
|
local AirbasePointVec2 = Airbase:GetPointVec2()
|
||||||
local ToWaypoint = AirbasePointVec2:WaypointAir(POINT_VEC3.RoutePointAltType.BARO, "Land", "Landing", Speed or Airplane:GetSpeedMax()*0.8, true, Airbase)
|
local ToWaypoint = AirbasePointVec2:WaypointAir(COORDINATE.WaypointAltType.BARO, "Land", "Landing", Speed or Airplane:GetSpeedMax()*0.8, true, Airbase)
|
||||||
|
|
||||||
--ToWaypoint["airdromeId"] = Airbase:GetID()
|
--ToWaypoint["airdromeId"] = Airbase:GetID()
|
||||||
--ToWaypoint["speed_locked"] = true
|
--ToWaypoint["speed_locked"] = true
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # The dispatcher concept.
|
-- # The dispatcher concept.
|
||||||
--
|
--
|
||||||
-- Carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
--- A dynamic cargo transportation capability for AI groups.
|
--- A dynamic cargo transportation capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Armoured Personnel APCs (APC), Trucks, Jeeps and other carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Armoured Personnel APCs (APC), Trucks, Jeeps and other carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_DISPATCHER_APC module is derived from the AI_CARGO_DISPATCHER module.
|
-- The AI_CARGO_DISPATCHER_APC module is derived from the AI_CARGO_DISPATCHER module.
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for AI groups.
|
--- Brings a dynamic cargo handling capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_DISPATCHER_AIRPLANE module is derived from the AI_CARGO_DISPATCHER module.
|
-- The AI_CARGO_DISPATCHER_AIRPLANE module is derived from the AI_CARGO_DISPATCHER module.
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
--- A dynamic cargo handling capability for AI helicopter groups.
|
--- A dynamic cargo handling capability for AI helicopter groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
--- A dynamic cargo transportation capability for AI groups.
|
--- A dynamic cargo transportation capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Naval vessels can be mobilized to semi-intelligently transport cargo within the simulation.
|
-- Naval vessels can be mobilized to semi-intelligently transport cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_DISPATCHER_SHIP module is derived from the AI_CARGO_DISPATCHER module.
|
-- The AI_CARGO_DISPATCHER_SHIP module is derived from the AI_CARGO_DISPATCHER module.
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI helicopter group.
|
--- Brings a dynamic cargo handling capability for an AI helicopter group.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Helicopter carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Helicopter carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_HELICOPTER class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_HELICOPTER class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
@@ -367,8 +369,8 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
|
|||||||
-- local CoordinateFrom = Helicopter:GetCoordinate()
|
-- local CoordinateFrom = Helicopter:GetCoordinate()
|
||||||
-- local WaypointFrom = CoordinateFrom:WaypointAir(
|
-- local WaypointFrom = CoordinateFrom:WaypointAir(
|
||||||
-- "RADIO",
|
-- "RADIO",
|
||||||
-- POINT_VEC3.RoutePointType.TurningPoint,
|
-- COORDINATE.WaypointType.TurningPoint,
|
||||||
-- POINT_VEC3.RoutePointAction.TurningPoint,
|
-- COORDINATE.WaypointAction.TurningPoint,
|
||||||
-- Speed,
|
-- Speed,
|
||||||
-- true
|
-- true
|
||||||
-- )
|
-- )
|
||||||
@@ -380,8 +382,8 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
|
|||||||
|
|
||||||
local WaypointTo = CoordinateTo:WaypointAir(
|
local WaypointTo = CoordinateTo:WaypointAir(
|
||||||
"RADIO",
|
"RADIO",
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
50,
|
50,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -427,7 +429,7 @@ function AI_CARGO_HELICOPTER:onafterOrbit( Helicopter, From, Event, To, Coordina
|
|||||||
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
||||||
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
|
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
|
||||||
|
|
||||||
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, 50, true)
|
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 50, true)
|
||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
@@ -496,14 +498,14 @@ function AI_CARGO_HELICOPTER:onafterPickup( Helicopter, From, Event, To, Coordin
|
|||||||
local CoordinateFrom = Helicopter:GetCoordinate()
|
local CoordinateFrom = Helicopter:GetCoordinate()
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, _speed, true)
|
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, _speed, true)
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local CoordinateTo = Coordinate
|
local CoordinateTo = Coordinate
|
||||||
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
||||||
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
|
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
|
||||||
|
|
||||||
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint,_speed, true)
|
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint,_speed, true)
|
||||||
|
|
||||||
Route[#Route+1] = WaypointFrom
|
Route[#Route+1] = WaypointFrom
|
||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
@@ -563,7 +565,7 @@ function AI_CARGO_HELICOPTER:onafterDeploy( Helicopter, From, Event, To, Coordin
|
|||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local CoordinateFrom = Helicopter:GetCoordinate()
|
local CoordinateFrom = Helicopter:GetCoordinate()
|
||||||
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, _speed, true)
|
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, _speed, true)
|
||||||
Route[#Route+1] = WaypointFrom
|
Route[#Route+1] = WaypointFrom
|
||||||
Route[#Route+1] = WaypointFrom
|
Route[#Route+1] = WaypointFrom
|
||||||
|
|
||||||
@@ -573,7 +575,7 @@ function AI_CARGO_HELICOPTER:onafterDeploy( Helicopter, From, Event, To, Coordin
|
|||||||
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
||||||
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
|
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
|
||||||
|
|
||||||
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, _speed, true)
|
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, _speed, true)
|
||||||
|
|
||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
@@ -631,7 +633,7 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat
|
|||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local CoordinateFrom = Helicopter:GetCoordinate()
|
local CoordinateFrom = Helicopter:GetCoordinate()
|
||||||
|
|
||||||
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, Speed, true)
|
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true)
|
||||||
Route[#Route+1] = WaypointFrom
|
Route[#Route+1] = WaypointFrom
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
@@ -639,7 +641,7 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat
|
|||||||
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
local landheight = CoordinateTo:GetLandHeight() -- get target height
|
||||||
CoordinateTo.y = landheight + Height -- flight height should be 50m above ground
|
CoordinateTo.y = landheight + Height -- flight height should be 50m above ground
|
||||||
|
|
||||||
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, Speed, true)
|
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true)
|
||||||
|
|
||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI naval group.
|
--- Brings a dynamic cargo handling capability for an AI naval group.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Naval ships can be utilized to transport cargo around the map following naval shipping lanes.
|
-- Naval ships can be utilized to transport cargo around the map following naval shipping lanes.
|
||||||
-- The AI_CARGO_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
-- @{Cargo.Cargo} must be declared within the mission or warehouse to make the AI_CARGO_SHIP recognize the cargo.
|
-- @{Cargo.Cargo} must be declared within the mission or warehouse to make the AI_CARGO_SHIP recognize the cargo.
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
--
|
--
|
||||||
-- Allows you to interact with escorting AI on your flight and take the lead.
|
-- Allows you to interact with escorting AI on your flight and take the lead.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
||||||
--
|
--
|
||||||
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
--- Models the assignment of AI escorts to player flights upon request using the radio menu.
|
--- Models the assignment of AI escorts to player flights upon request using the radio menu.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
--
|
--
|
||||||
-- Allows you to interact with escorting AI on your flight and take the lead.
|
-- Allows you to interact with escorting AI on your flight and take the lead.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
||||||
--
|
--
|
||||||
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
|
|
||||||
|
|
||||||
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
|
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- AI_FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions.
|
-- AI_FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions.
|
||||||
-- The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
-- The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
||||||
@@ -158,7 +160,6 @@ AI_FORMATION.__Enum.Mode = {
|
|||||||
-- @field #number GroundRadar
|
-- @field #number GroundRadar
|
||||||
-- @field #number Ground
|
-- @field #number Ground
|
||||||
AI_FORMATION.__Enum.ReportType = {
|
AI_FORMATION.__Enum.ReportType = {
|
||||||
Airborne = "*",
|
|
||||||
Airborne = "A",
|
Airborne = "A",
|
||||||
GroundRadar = "R",
|
GroundRadar = "R",
|
||||||
Ground = "G",
|
Ground = "G",
|
||||||
@@ -725,7 +726,7 @@ function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, X
|
|||||||
|
|
||||||
for FollowID, FollowGroup in pairs( FollowSet ) do
|
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:New()
|
local PointVec3 = COORDINATE:New()
|
||||||
PointVec3:SetX( XStart + i * XSpace )
|
PointVec3:SetX( XStart + i * XSpace )
|
||||||
PointVec3:SetY( YStart + i * YSpace )
|
PointVec3:SetY( YStart + i * YSpace )
|
||||||
PointVec3:SetZ( ZStart + i * ZSpace )
|
PointVec3:SetZ( ZStart + i * ZSpace )
|
||||||
@@ -877,7 +878,7 @@ function AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event ,
|
|||||||
|
|
||||||
for FollowID, FollowGroup in pairs( FollowSet ) do
|
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:New()
|
local PointVec3 = COORDINATE:New()
|
||||||
|
|
||||||
local Side = ( i % 2 == 0 ) and 1 or -1
|
local Side = ( i % 2 == 0 ) and 1 or -1
|
||||||
local Row = i / 2 + 1
|
local Row = i / 2 + 1
|
||||||
@@ -936,7 +937,7 @@ function AI_FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XS
|
|||||||
|
|
||||||
for FollowID, FollowGroup in pairs( FollowSet ) do
|
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:New()
|
local PointVec3 = COORDINATE:New()
|
||||||
|
|
||||||
local ZIndex = i % ZLevels
|
local ZIndex = i % ZLevels
|
||||||
local XIndex = math.floor( i / ZLevels )
|
local XIndex = math.floor( i / ZLevels )
|
||||||
@@ -1222,7 +1223,6 @@ function AI_FORMATION:FollowMe(FollowGroup, ClientUnit, CT1, CV1, CT2, CV2)
|
|||||||
local CVI = {
|
local CVI = {
|
||||||
x = CV2.x + CS * 10 * math.sin(Ca),
|
x = CV2.x + CS * 10 * math.sin(Ca),
|
||||||
y = GH2.y + Inclination, -- + FollowFormation.y,
|
y = GH2.y + Inclination, -- + FollowFormation.y,
|
||||||
y = GH2.y,
|
|
||||||
z = CV2.z + CS * 10 * math.cos(Ca),
|
z = CV2.z + CS * 10 * math.cos(Ca),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}.
|
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_PATROL_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_PATROL_ZONE process can be started using the **Start** event.
|
-- The AI_PATROL_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_PATROL_ZONE process can be started using the **Start** event.
|
||||||
@@ -751,12 +753,12 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
|||||||
if not CurrentVec2 then return end
|
if not CurrentVec2 then return end
|
||||||
--Done: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
--Done: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
local CurrentAltitude = self.Controllable:GetAltitude()
|
local CurrentAltitude = self.Controllable:GetAltitude()
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TakeOffParking,
|
COORDINATE.WaypointType.TakeOffParking,
|
||||||
POINT_VEC3.RoutePointAction.FromParkingArea,
|
COORDINATE.WaypointAction.FromParkingArea,
|
||||||
ToPatrolZoneSpeed,
|
ToPatrolZoneSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -767,12 +769,12 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
|||||||
if not CurrentVec2 then return end
|
if not CurrentVec2 then return end
|
||||||
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
local CurrentAltitude = self.Controllable:GetAltitude()
|
local CurrentAltitude = self.Controllable:GetAltitude()
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
ToPatrolZoneSpeed,
|
ToPatrolZoneSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -792,13 +794,13 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
|||||||
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
|
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
|
||||||
|
|
||||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
|
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
|
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
ToTargetSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -846,7 +848,6 @@ function AI_PATROL_ZONE:onafterStatus()
|
|||||||
OldAIControllable:SetTask( TimedOrbitTask, 10 )
|
OldAIControllable:SetTask( TimedOrbitTask, 10 )
|
||||||
|
|
||||||
RTB = true
|
RTB = true
|
||||||
else
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Check GROUP damage function.
|
-- TODO: Check GROUP damage function.
|
||||||
@@ -856,6 +857,16 @@ function AI_PATROL_ZONE:onafterStatus()
|
|||||||
RTB = true
|
RTB = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self:IsInstanceOf("AI_CAS") or self:IsInstanceOf("AI_BAI") then
|
||||||
|
local atotal,shells,rockets,bombs,missiles = self.Controllable:GetAmmunition()
|
||||||
|
local arelevant = rockets+bombs
|
||||||
|
if arelevant == 0 or missiles == 0 then
|
||||||
|
RTB = true
|
||||||
|
self:T({total=atotal,shells=shells,rockets=rockets,bombs=bombs,missiles=missiles})
|
||||||
|
self:T( self.Controllable:GetName() .. " is out of ammo, RTB!" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if RTB == true then
|
if RTB == true then
|
||||||
self:RTB()
|
self:RTB()
|
||||||
else
|
else
|
||||||
@@ -881,12 +892,12 @@ function AI_PATROL_ZONE:onafterRTB()
|
|||||||
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
--local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
--local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
||||||
local CurrentAltitude = self.Controllable:GetAltitude()
|
local CurrentAltitude = self.Controllable:GetAltitude()
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
COORDINATE.WaypointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
COORDINATE.WaypointAction.TurningPoint,
|
||||||
ToPatrolZoneSpeed,
|
ToPatrolZoneSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs.
|
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -8,9 +8,11 @@
|
|||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
do -- ACT_ACCOUNT
|
do -- ACT_ACCOUNT
|
||||||
|
|
||||||
--- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
--- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ## ACT_ACCOUNT state machine:
|
-- ## ACT_ACCOUNT state machine:
|
||||||
--
|
--
|
||||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||||
@@ -133,7 +135,7 @@ do -- ACT_ACCOUNT
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To, Event )
|
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To )
|
||||||
|
|
||||||
self:__NoMore( 1 )
|
self:__NoMore( 1 )
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
--- (SP) (MP) (FSM) Accept or reject process for player (task) assignments.
|
--- (SP) (MP) (FSM) Accept or reject process for player (task) assignments.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
|
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
|
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
-- ## ACT_ASSIST state machine:
|
-- ## ACT_ASSIST state machine:
|
||||||
--
|
--
|
||||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # @{#ACT_ROUTE} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
-- # @{#ACT_ROUTE} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
-- ## ACT_ROUTE state machine:
|
-- ## ACT_ROUTE state machine:
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # 1) MOOSE Cargo System.
|
-- # 1) MOOSE Cargo System.
|
||||||
--
|
--
|
||||||
-- #### Those who have used the mission editor, know that the DCS mission editor provides cargo facilities.
|
-- #### Those who have used the mission editor, know that the DCS mission editor provides cargo facilities.
|
||||||
@@ -275,14 +277,14 @@
|
|||||||
-- The cargo must be in the **Loaded** state.
|
-- The cargo must be in the **Loaded** state.
|
||||||
-- @function [parent=#CARGO] UnBoard
|
-- @function [parent=#CARGO] UnBoard
|
||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
|
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
|
||||||
|
|
||||||
--- UnBoards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo from the Carrier.
|
--- UnBoards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo from the Carrier.
|
||||||
-- The cargo must be in the **Loaded** state.
|
-- The cargo must be in the **Loaded** state.
|
||||||
-- @function [parent=#CARGO] __UnBoard
|
-- @function [parent=#CARGO] __UnBoard
|
||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @param #number DelaySeconds The amount of seconds to delay the action.
|
-- @param #number DelaySeconds The amount of seconds to delay the action.
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
|
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
|
||||||
|
|
||||||
|
|
||||||
-- Load
|
-- Load
|
||||||
@@ -307,14 +309,14 @@
|
|||||||
-- The cargo must be in the **Loaded** state.
|
-- The cargo must be in the **Loaded** state.
|
||||||
-- @function [parent=#CARGO] UnLoad
|
-- @function [parent=#CARGO] UnLoad
|
||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
|
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
|
||||||
|
|
||||||
--- UnLoads the cargo to a Carrier. The event will unload the cargo from the Carrier. There will be no movement simulated of the cargo loading.
|
--- UnLoads the cargo to a Carrier. The event will unload the cargo from the Carrier. There will be no movement simulated of the cargo loading.
|
||||||
-- The cargo must be in the **Loaded** state.
|
-- The cargo must be in the **Loaded** state.
|
||||||
-- @function [parent=#CARGO] __UnLoad
|
-- @function [parent=#CARGO] __UnLoad
|
||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @param #number DelaySeconds The amount of seconds to delay the action.
|
-- @param #number DelaySeconds The amount of seconds to delay the action.
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
|
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
|
||||||
|
|
||||||
-- State Transition Functions
|
-- State Transition Functions
|
||||||
|
|
||||||
@@ -467,7 +469,7 @@ do -- CARGO
|
|||||||
self.Type = Type
|
self.Type = Type
|
||||||
self.Name = Name
|
self.Name = Name
|
||||||
self.Weight = Weight or 0
|
self.Weight = Weight or 0
|
||||||
self.CargoObject = nil
|
self.CargoObject = nil -- Wrapper.Group#GROUP
|
||||||
self.CargoCarrier = nil -- Wrapper.Client#CLIENT
|
self.CargoCarrier = nil -- Wrapper.Client#CLIENT
|
||||||
self.Representable = false
|
self.Representable = false
|
||||||
self.Slingloadable = false
|
self.Slingloadable = false
|
||||||
@@ -897,7 +899,7 @@ do -- CARGO
|
|||||||
|
|
||||||
--- Get the current PointVec2 of the cargo.
|
--- Get the current PointVec2 of the cargo.
|
||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @return Core.Point#POINT_VEC2
|
-- @return Core.Point#COORDINATE
|
||||||
function CARGO:GetPointVec2()
|
function CARGO:GetPointVec2()
|
||||||
return self.CargoObject:GetPointVec2()
|
return self.CargoObject:GetPointVec2()
|
||||||
end
|
end
|
||||||
@@ -1094,7 +1096,7 @@ do -- CARGO_REPRESENTABLE
|
|||||||
|
|
||||||
--- Route a cargo unit to a PointVec2.
|
--- Route a cargo unit to a PointVec2.
|
||||||
-- @param #CARGO_REPRESENTABLE self
|
-- @param #CARGO_REPRESENTABLE self
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
-- @param #number Speed
|
-- @param #number Speed
|
||||||
-- @return #CARGO_REPRESENTABLE
|
-- @return #CARGO_REPRESENTABLE
|
||||||
function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed )
|
function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed )
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ do -- CARGO_CRATE
|
|||||||
-- @type CARGO_CRATE
|
-- @type CARGO_CRATE
|
||||||
-- @extends Cargo.Cargo#CARGO_REPRESENTABLE
|
-- @extends Cargo.Cargo#CARGO_REPRESENTABLE
|
||||||
|
|
||||||
|
---
|
||||||
|
-- 
|
||||||
|
--
|
||||||
--- Defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
--- Defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
||||||
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers.
|
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers.
|
||||||
--
|
--
|
||||||
@@ -114,7 +117,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2
|
-- @param Core.Point#COORDINATE
|
||||||
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||||
--self:T( { ToPointVec2, From, Event, To } )
|
--self:T( { ToPointVec2, From, Event, To } )
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,12 @@ do -- CARGO_GROUP
|
|||||||
--- @type CARGO_GROUP
|
--- @type CARGO_GROUP
|
||||||
-- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects.
|
-- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects.
|
||||||
-- @field #string GroupName The name of the CargoGroup.
|
-- @field #string GroupName The name of the CargoGroup.
|
||||||
|
-- @field Wrapper.Group#GROUÜ CargoCarrier The carrier group.
|
||||||
-- @extends Cargo.Cargo#CARGO_REPORTABLE
|
-- @extends Cargo.Cargo#CARGO_REPORTABLE
|
||||||
|
|
||||||
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator.
|
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
|
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
|
||||||
--
|
--
|
||||||
-- The above cargo classes are used by the following AI_CARGO_ classes to allow AI groups to transport cargo:
|
-- The above cargo classes are used by the following AI_CARGO_ classes to allow AI groups to transport cargo:
|
||||||
@@ -410,7 +413,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
||||||
function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
|
function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||||
self:T( {From, Event, To, ToPointVec2, NearRadius } )
|
self:T( {From, Event, To, ToPointVec2, NearRadius } )
|
||||||
@@ -453,7 +456,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
||||||
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||||
--self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
--self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
@@ -491,7 +494,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
|
function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
|
||||||
--self:T( { From, Event, To, ToPointVec2 } )
|
--self:T( { From, Event, To, ToPointVec2 } )
|
||||||
|
|
||||||
@@ -771,3 +774,4 @@ do -- CARGO_GROUP
|
|||||||
|
|
||||||
|
|
||||||
end -- CARGO_GROUP
|
end -- CARGO_GROUP
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ do -- CARGO_SLINGLOAD
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ do -- CARGO_UNIT
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
@@ -72,7 +74,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
-- @param #number NearRadius (optional) Defaut 25 m.
|
-- @param #number NearRadius (optional) Defaut 25 m.
|
||||||
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
@@ -145,7 +147,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
-- @param #number NearRadius (optional) Defaut 100 m.
|
-- @param #number NearRadius (optional) Defaut 100 m.
|
||||||
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
@@ -171,7 +173,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#COORDINATE ToPointVec2
|
||||||
-- @param #number NearRadius (optional) Defaut 100 m.
|
-- @param #number NearRadius (optional) Defaut 100 m.
|
||||||
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
@@ -197,7 +199,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2
|
-- @param Core.Point#COORDINATE
|
||||||
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||||
self:T( { ToPointVec2, From, Event, To } )
|
self:T( { ToPointVec2, From, Event, To } )
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ BASE = {
|
|||||||
States = {},
|
States = {},
|
||||||
Debug = debug,
|
Debug = debug,
|
||||||
Scheduler = nil,
|
Scheduler = nil,
|
||||||
|
Properties = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
-- @field #BASE.__
|
-- @field #BASE.__
|
||||||
@@ -973,7 +974,7 @@ do -- Scheduling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
||||||
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
|
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
|
||||||
-- @param #table ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
|
-- @param ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
|
||||||
-- @return #string The Schedule ID of the planned schedule.
|
-- @return #string The Schedule ID of the planned schedule.
|
||||||
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
|
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
|
||||||
|
|
||||||
@@ -1109,6 +1110,31 @@ function BASE:ClearState( Object, StateName )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set one property of an object.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
|
||||||
|
-- @param Value The value that is stored. Note that the value can be a #string, but it can also be any other type!
|
||||||
|
function BASE:SetProperty(Key,Value)
|
||||||
|
self.Properties = self.Properties or {}
|
||||||
|
self.Properties[Key] = Value
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get one property of an object by the key.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
|
||||||
|
-- @return Value The value that is stored. Note that the value can be a #string, but it can also be any other type! Nil if not found.
|
||||||
|
function BASE:GetProperty(Key)
|
||||||
|
self.Properties = self.Properties or {}
|
||||||
|
return self.Properties[Key]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get all of the properties of an object in a table.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @return #table of values, indexed by keys.
|
||||||
|
function BASE:GetProperties()
|
||||||
|
return self.Properties
|
||||||
|
end
|
||||||
|
|
||||||
-- Trace section
|
-- Trace section
|
||||||
|
|
||||||
-- Log a trace (only shown when trace is on)
|
-- Log a trace (only shown when trace is on)
|
||||||
@@ -1440,4 +1466,3 @@ function BASE:I( Arguments )
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -872,6 +872,8 @@ end
|
|||||||
-- @return Wrapper.Group#GROUP The found GROUP.
|
-- @return Wrapper.Group#GROUP The found GROUP.
|
||||||
function DATABASE:FindGroup( GroupName )
|
function DATABASE:FindGroup( GroupName )
|
||||||
|
|
||||||
|
if type(GroupName) ~= "string" or GroupName == "" then return end
|
||||||
|
|
||||||
local GroupFound = self.GROUPS[GroupName]
|
local GroupFound = self.GROUPS[GroupName]
|
||||||
|
|
||||||
if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then
|
if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then
|
||||||
@@ -1697,7 +1699,7 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
if PlayerName then
|
if PlayerName then
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:I(string.format("Player '%s' joined unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName)))
|
self:I(string.format("Player '%s' joined unit '%s' (%s) of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniTypeName), tostring(Event.IniDCSGroupName)))
|
||||||
|
|
||||||
-- Add client in case it does not exist already.
|
-- Add client in case it does not exist already.
|
||||||
if client == nil or (client and client:CountPlayers() == 0) then
|
if client == nil or (client and client:CountPlayers() == 0) then
|
||||||
|
|||||||
@@ -1372,11 +1372,12 @@ function EVENT:onEvent( Event )
|
|||||||
-- Scenery
|
-- Scenery
|
||||||
---
|
---
|
||||||
Event.IniDCSUnit = Event.initiator
|
Event.IniDCSUnit = Event.initiator
|
||||||
Event.IniDCSUnitName = Event.IniDCSUnit.getName and Event.IniDCSUnit:getName() or "Scenery no name "..math.random(1,20000)
|
Event.IniDCSUnitName = ( Event.IniDCSUnit and Event.IniDCSUnit.getName ) and Event.IniDCSUnit:getName() or "Scenery no name "..math.random(1,20000)
|
||||||
Event.IniUnitName = Event.IniDCSUnitName
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
||||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
Event.IniCategory = (Event.IniDCSUnit and Event.IniDCSUnit.getDesc ) and Event.IniDCSUnit:getDesc().category
|
||||||
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY"
|
Event.IniTypeName = (Event.initiator and Event.initiator.isExist
|
||||||
|
and Event.initiator:isExist() and Event.IniDCSUnit and Event.IniDCSUnit.getTypeName) and Event.IniDCSUnit:getTypeName() or "SCENERY"
|
||||||
|
|
||||||
elseif Event.IniObjectCategory == Object.Category.BASE then
|
elseif Event.IniObjectCategory == Object.Category.BASE then
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ function MENU_INDEX:PrepareCoalition( CoalitionSide )
|
|||||||
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
|
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
|
||||||
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
|
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
function MENU_INDEX:PrepareGroup( Group )
|
function MENU_INDEX:PrepareGroup( Group )
|
||||||
@@ -118,9 +119,11 @@ end
|
|||||||
function MENU_INDEX:HasMissionMenu( Path )
|
function MENU_INDEX:HasMissionMenu( Path )
|
||||||
return self.MenuMission.Menus[Path]
|
return self.MenuMission.Menus[Path]
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:SetMissionMenu( Path, Menu )
|
function MENU_INDEX:SetMissionMenu( Path, Menu )
|
||||||
self.MenuMission.Menus[Path] = Menu
|
self.MenuMission.Menus[Path] = Menu
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:ClearMissionMenu( Path )
|
function MENU_INDEX:ClearMissionMenu( Path )
|
||||||
self.MenuMission.Menus[Path] = nil
|
self.MenuMission.Menus[Path] = nil
|
||||||
end
|
end
|
||||||
@@ -128,9 +131,11 @@ end
|
|||||||
function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
|
function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
|
||||||
return self.Coalition[Coalition].Menus[Path]
|
return self.Coalition[Coalition].Menus[Path]
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu )
|
function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu )
|
||||||
self.Coalition[Coalition].Menus[Path] = Menu
|
self.Coalition[Coalition].Menus[Path] = Menu
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
|
function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
|
||||||
self.Coalition[Coalition].Menus[Path] = nil
|
self.Coalition[Coalition].Menus[Path] = nil
|
||||||
end
|
end
|
||||||
@@ -138,19 +143,24 @@ end
|
|||||||
function MENU_INDEX:HasGroupMenu( Group, Path )
|
function MENU_INDEX:HasGroupMenu( Group, Path )
|
||||||
if Group and Group:IsAlive() then
|
if Group and Group:IsAlive() then
|
||||||
local MenuGroupName = Group:GetName()
|
local MenuGroupName = Group:GetName()
|
||||||
return self.Group[MenuGroupName].Menus[Path]
|
if self.Group[MenuGroupName] and self.Group[MenuGroupName].Menus and self.Group[MenuGroupName].Menus[Path] then
|
||||||
|
return self.Group[MenuGroupName].Menus[Path]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
|
function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
|
||||||
local MenuGroupName = Group:GetName()
|
local MenuGroupName = Group:GetName()
|
||||||
Group:F({MenuGroupName=MenuGroupName,Path=Path})
|
--Group:F({MenuGroupName=MenuGroupName,Path=Path})
|
||||||
self.Group[MenuGroupName].Menus[Path] = Menu
|
self.Group[MenuGroupName].Menus[Path] = Menu
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:ClearGroupMenu( Group, Path )
|
function MENU_INDEX:ClearGroupMenu( Group, Path )
|
||||||
local MenuGroupName = Group:GetName()
|
local MenuGroupName = Group:GetName()
|
||||||
self.Group[MenuGroupName].Menus[Path] = nil
|
self.Group[MenuGroupName].Menus[Path] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function MENU_INDEX:Refresh( Group )
|
function MENU_INDEX:Refresh( Group )
|
||||||
for MenuID, Menu in pairs( self.MenuMission.Menus ) do
|
for MenuID, Menu in pairs( self.MenuMission.Menus ) do
|
||||||
Menu:Refresh()
|
Menu:Refresh()
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ end
|
|||||||
function MESSAGE:ToGroup( Group, Settings )
|
function MESSAGE:ToGroup( Group, Settings )
|
||||||
self:F( Group.GroupName )
|
self:F( Group.GroupName )
|
||||||
|
|
||||||
if Group then
|
if Group and Group:IsAlive() then
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
@@ -231,7 +231,7 @@ end
|
|||||||
function MESSAGE:ToUnit( Unit, Settings )
|
function MESSAGE:ToUnit( Unit, Settings )
|
||||||
self:F( Unit.IdentifiableName )
|
self:F( Unit.IdentifiableName )
|
||||||
|
|
||||||
if Unit then
|
if Unit and Unit:IsAlive() then
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
@@ -464,6 +464,7 @@ _MESSAGESRS = {}
|
|||||||
-- @param #number Volume (optional) Volume, can be between 0.0 and 1.0 (loudest).
|
-- @param #number Volume (optional) Volume, can be between 0.0 and 1.0 (loudest).
|
||||||
-- @param #string Label (optional) Label, defaults to "MESSAGE" or the Message Category set.
|
-- @param #string Label (optional) Label, defaults to "MESSAGE" or the Message Category set.
|
||||||
-- @param Core.Point#COORDINATE Coordinate (optional) Coordinate this messages originates from.
|
-- @param Core.Point#COORDINATE Coordinate (optional) Coordinate this messages originates from.
|
||||||
|
-- @param #string Backend (optional) Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Mind the dot here, not using the colon this time around!
|
-- -- Mind the dot here, not using the colon this time around!
|
||||||
-- -- Needed once only
|
-- -- Needed once only
|
||||||
@@ -471,7 +472,7 @@ _MESSAGESRS = {}
|
|||||||
-- -- later on in your code
|
-- -- later on in your code
|
||||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
|
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
|
||||||
--
|
--
|
||||||
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate)
|
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate,Backend)
|
||||||
|
|
||||||
_MESSAGESRS.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
_MESSAGESRS.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
||||||
|
|
||||||
@@ -489,6 +490,10 @@ function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,G
|
|||||||
_MESSAGESRS.MSRS:SetCoordinate(Coordinate)
|
_MESSAGESRS.MSRS:SetCoordinate(Coordinate)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if Backend then
|
||||||
|
_MESSAGESRS.MSRS:SetBackend(Backend)
|
||||||
|
end
|
||||||
|
|
||||||
_MESSAGESRS.Culture = Culture or MSRS.culture or "en-GB"
|
_MESSAGESRS.Culture = Culture or MSRS.culture or "en-GB"
|
||||||
_MESSAGESRS.MSRS:SetCulture(Culture)
|
_MESSAGESRS.MSRS:SetCulture(Culture)
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
do -- COORDINATE
|
do -- COORDINATE
|
||||||
|
|
||||||
---
|
--- Coordinate class
|
||||||
-- @type COORDINATE
|
-- @type COORDINATE
|
||||||
-- @field #string ClassName Name of the class
|
-- @field #string ClassName Name of the class
|
||||||
-- @field #number x Component of the 3D vector.
|
-- @field #number x Component of the 3D vector.
|
||||||
@@ -59,6 +59,10 @@ do -- COORDINATE
|
|||||||
-- * @{#COORDINATE.SmokeOrange}(): To smoke the point in orange.
|
-- * @{#COORDINATE.SmokeOrange}(): To smoke the point in orange.
|
||||||
-- * @{#COORDINATE.SmokeWhite}(): To smoke the point in white.
|
-- * @{#COORDINATE.SmokeWhite}(): To smoke the point in white.
|
||||||
-- * @{#COORDINATE.SmokeGreen}(): To smoke the point in green.
|
-- * @{#COORDINATE.SmokeGreen}(): To smoke the point in green.
|
||||||
|
-- * @{#COORDINATE.SetSmokeOffsetDirection}(): To set an offset point direction for smoke.
|
||||||
|
-- * @{#COORDINATE.SetSmokeOffsetDistance}(): To set an offset point distance for smoke.
|
||||||
|
-- * @{#COORDINATE.SwitchSmokeOffsetOn}(): To set an offset point for smoke to on.
|
||||||
|
-- * @{#COORDINATE.SwitchSmokeOffsetOff}(): To set an offset point for smoke to off.
|
||||||
--
|
--
|
||||||
-- ## 2.2) Flare
|
-- ## 2.2) Flare
|
||||||
--
|
--
|
||||||
@@ -110,7 +114,7 @@ do -- COORDINATE
|
|||||||
--
|
--
|
||||||
-- ## 4.4) Get the North correction of the current location.
|
-- ## 4.4) Get the North correction of the current location.
|
||||||
--
|
--
|
||||||
-- * @{#COORDINATE.GetNorthCorrection}(): Obtains the north correction at the current 3D point.
|
-- * @{#COORDINATE.GetNorthCorrectionRadians}(): Obtains the north correction at the current 3D point.
|
||||||
--
|
--
|
||||||
-- ## 4.5) Point Randomization
|
-- ## 4.5) Point Randomization
|
||||||
--
|
--
|
||||||
@@ -968,8 +972,13 @@ do -- COORDINATE
|
|||||||
-- @return DCS#Distance Distance The distance in meters.
|
-- @return DCS#Distance Distance The distance in meters.
|
||||||
function COORDINATE:Get2DDistance(TargetCoordinate)
|
function COORDINATE:Get2DDistance(TargetCoordinate)
|
||||||
if not TargetCoordinate then return 1000000 end
|
if not TargetCoordinate then return 1000000 end
|
||||||
local a={x=TargetCoordinate.x-self.x, y=0, z=TargetCoordinate.z-self.z}
|
--local a={x=TargetCoordinate.x-self.x, y=0, z=TargetCoordinate.z-self.z}
|
||||||
local norm=UTILS.VecNorm(a)
|
local a = self:GetVec2()
|
||||||
|
if not TargetCoordinate.ClassName then
|
||||||
|
TargetCoordinate=COORDINATE:NewFromVec3(TargetCoordinate)
|
||||||
|
end
|
||||||
|
local b = TargetCoordinate:GetVec2()
|
||||||
|
local norm=UTILS.VecDist2D(a,b)
|
||||||
return norm
|
return norm
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1152,6 +1161,162 @@ do -- COORDINATE
|
|||||||
return vec3
|
return vec3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Return the x coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number The x coordinate.
|
||||||
|
function COORDINATE:GetX()
|
||||||
|
return self.x
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Return the y coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number The y coordinate.
|
||||||
|
function COORDINATE:GetY()
|
||||||
|
if self:IsInstanceOf("POINT_VEC2") then
|
||||||
|
return self.z
|
||||||
|
end
|
||||||
|
return self.y
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Return the z coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number The z coordinate.
|
||||||
|
function COORDINATE:GetZ()
|
||||||
|
return self.z
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the x coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number x The x coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:SetX( x )
|
||||||
|
self.x = x
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the y coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number y The y coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:SetY( y )
|
||||||
|
if self:IsInstanceOf("POINT_VEC2") then
|
||||||
|
self.z = y
|
||||||
|
else
|
||||||
|
self.y = y
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the z coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number z The z coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:SetZ( z )
|
||||||
|
self.z = z
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add to the x coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number x The x coordinate value to add to the current x coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:AddX( x )
|
||||||
|
self.x = self.x + x
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Return Return the Lat(itude) coordinate of the COORDINATE (ie: (parent)COORDINATE.x).
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number The x coordinate.
|
||||||
|
function COORDINATE:GetLat()
|
||||||
|
return self.x
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Lat(itude) coordinate of the COORDINATE (ie: COORDINATE.x).
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number x The x coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:SetLat( x )
|
||||||
|
self.x = x
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Return the Lon(gitude) coordinate of the COORDINATE (ie: (parent)COORDINATE.z).
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number The y coordinate.
|
||||||
|
function COORDINATE:GetLon()
|
||||||
|
return self.z
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Lon(gitude) coordinate of the COORDINATE (ie: COORDINATE.z).
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number y The y coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:SetLon( z )
|
||||||
|
self.z = z
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Return the altitude (height) of the land at the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number The land altitude.
|
||||||
|
function COORDINATE:GetAlt()
|
||||||
|
return self.y ~= 0 or land.getHeight( { x = self.x, y = self.z } )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the altitude of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Altitude The land altitude. If nothing (nil) is given, then the current land altitude is set.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:SetAlt( Altitude )
|
||||||
|
self.y = Altitude or land.getHeight( { x = self.x, y = self.z } )
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add to the current land height an altitude.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:AddAlt( Altitude )
|
||||||
|
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Return a random COORDINATE within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param DCS#Distance OuterRadius
|
||||||
|
-- @param DCS#Distance InnerRadius
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:GetRandomPointVec2InRadius( OuterRadius, InnerRadius )
|
||||||
|
self:F2( { OuterRadius, InnerRadius } )
|
||||||
|
|
||||||
|
return COORDINATE:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add to the y coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number y The y coordinate value to add to the current y coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:AddY( y )
|
||||||
|
if self:IsInstanceOf("POINT_VEC2") then
|
||||||
|
return self:AddZ(y)
|
||||||
|
else
|
||||||
|
self.y = self.y + y
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add to the z coordinate of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number z The z coordinate value to add to the current z coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:AddZ( z )
|
||||||
|
self.z = self.z +z
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns a text documenting the wind direction (from) and strength according the measurement system @{Core.Settings}.
|
--- Returns a text documenting the wind direction (from) and strength according the measurement system @{Core.Settings}.
|
||||||
-- The text will reflect the wind like this:
|
-- The text will reflect the wind like this:
|
||||||
@@ -1216,7 +1381,7 @@ do -- COORDINATE
|
|||||||
local s = string.format( '%03d°', AngleDegrees )
|
local s = string.format( '%03d°', AngleDegrees )
|
||||||
|
|
||||||
if MagVar then
|
if MagVar then
|
||||||
local variation = UTILS.GetMagneticDeclination() or 0
|
local variation = self:GetMagneticDeclination() or 0
|
||||||
local AngleMagnetic = AngleDegrees - variation
|
local AngleMagnetic = AngleDegrees - variation
|
||||||
|
|
||||||
if AngleMagnetic < 0 then AngleMagnetic = 360-AngleMagnetic end
|
if AngleMagnetic < 0 then AngleMagnetic = 360-AngleMagnetic end
|
||||||
@@ -1329,13 +1494,16 @@ do -- COORDINATE
|
|||||||
-- @param Core.Settings#SETTINGS Settings
|
-- @param Core.Settings#SETTINGS Settings
|
||||||
-- @param #string Language (Optional) Language "en" or "ru"
|
-- @param #string Language (Optional) Language "en" or "ru"
|
||||||
-- @param #boolean MagVar If true, also state angle in magnetic
|
-- @param #boolean MagVar If true, also state angle in magnetic
|
||||||
|
-- @param #number Precision Rounding precision, defaults to 0
|
||||||
-- @return #string The BR Text
|
-- @return #string The BR Text
|
||||||
function COORDINATE:GetBRText( AngleRadians, Distance, Settings, Language, MagVar )
|
function COORDINATE:GetBRText( AngleRadians, Distance, Settings, Language, MagVar, Precision )
|
||||||
|
|
||||||
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
|
|
||||||
|
Precision = Precision or 0
|
||||||
|
|
||||||
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, MagVar )
|
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, MagVar )
|
||||||
local DistanceText = self:GetDistanceText( Distance, Settings, Language, 0 )
|
local DistanceText = self:GetDistanceText( Distance, Settings, Language, Precision )
|
||||||
|
|
||||||
local BRText = BearingText .. DistanceText
|
local BRText = BearingText .. DistanceText
|
||||||
|
|
||||||
@@ -1954,59 +2122,200 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Smokes the point in a color.
|
--- Create colored smoke the point. The smoke we last up to 5 min (DCS limitation) but you can optionally specify a shorter duration or stop it manually.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor
|
-- @param #number SmokeColor Color of smoke, e.g. `SMOKECOLOR.Green` for green smoke.
|
||||||
function COORDINATE:Smoke( SmokeColor )
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2( { SmokeColor } )
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
trigger.action.smoke( self:GetVec3(), SmokeColor )
|
-- @param #string Name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
||||||
|
-- @param #boolean Offset (Optional) If true, offset the smokle a bit.
|
||||||
|
-- @param #number Direction (Optional) If Offset is true this is the direction of the offset, 1-359 (degrees). Default random.
|
||||||
|
-- @param #number Distance (Optional) If Offset is true this is the distance of the offset in meters. Default random 10-20.
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:Smoke( SmokeColor, Duration, Delay, Name, Offset,Direction,Distance)
|
||||||
|
self:F2( { SmokeColor, Name, Duration, Delay, Offset } )
|
||||||
|
|
||||||
|
SmokeColor=SmokeColor or SMOKECOLOR.Green
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, COORDINATE.Smoke, self, SmokeColor, Duration, 0, Name, Direction,Distance)
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Create a name which is used to stop the smoke manually
|
||||||
|
self.firename = Name or "Smoke-"..math.random(1,100000)
|
||||||
|
|
||||||
|
-- Create smoke
|
||||||
|
if Offset or self.SmokeOffset then
|
||||||
|
local Angle = Direction or self:GetSmokeOffsetDirection()
|
||||||
|
local Distance = Distance or self:GetSmokeOffsetDistance()
|
||||||
|
local newpos = self:Translate(Distance,Angle,true,false)
|
||||||
|
local newvec3 = newpos:GetVec3()
|
||||||
|
trigger.action.smoke( newvec3, SmokeColor, self.firename )
|
||||||
|
else
|
||||||
|
trigger.action.smoke( self:GetVec3(), SmokeColor, self.firename )
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Stop smoke
|
||||||
|
if Duration and Duration>0 then
|
||||||
|
self:ScheduleOnce(Duration, COORDINATE.StopSmoke, self, self.firename )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the offset direction when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number Direction in degrees.
|
||||||
|
function COORDINATE:GetSmokeOffsetDirection()
|
||||||
|
local direction = self.SmokeOffsetDirection or math.random(1,359)
|
||||||
|
return direction
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset direction when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Direction (Optional) This is the direction of the offset, 1-359 (degrees). Default random.
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SetSmokeOffsetDirection(Direction)
|
||||||
|
if self then
|
||||||
|
self.SmokeOffsetDirection = Direction or math.random(1,359)
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffsetDirection = Direction or math.random(1,359)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the offset distance when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number Distance Distance in meters.
|
||||||
|
function COORDINATE:GetSmokeOffsetDistance()
|
||||||
|
local distance = self.SmokeOffsetDistance or math.random(10,20)
|
||||||
|
return distance
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset distance when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Distance (Optional) This is the distance of the offset in meters. Default random 10-20.
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SetSmokeOffsetDistance(Distance)
|
||||||
|
if self then
|
||||||
|
self.SmokeOffsetDistance = Distance or math.random(10,20)
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffsetDistance = Distance or math.random(10,20)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset on when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SwitchSmokeOffsetOn()
|
||||||
|
if self then
|
||||||
|
self.SmokeOffset = true
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffset = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset off when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SwitchSmokeOffsetOff()
|
||||||
|
if self then
|
||||||
|
self.SmokeOffset = false
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffset = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stops smoking the point in a color.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #string name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
||||||
|
function COORDINATE:StopSmoke( name )
|
||||||
|
self:StopBigSmokeAndFire( name )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Green.
|
--- Smoke the COORDINATE Green.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeGreen()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Green )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeGreen(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Green, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Red.
|
--- Smoke the COORDINATE Red.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeRed()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Red )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeRed(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Red, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE White.
|
--- Smoke the COORDINATE White.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeWhite()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.White )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeWhite(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.White, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Orange.
|
--- Smoke the COORDINATE Orange.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeOrange()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Orange )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeOrange(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Orange, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Blue.
|
--- Smoke the COORDINATE Blue.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeBlue()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Blue )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeBlue(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Blue, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Big smoke and fire at the coordinate.
|
--- Big smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Utilities.Utils#BIGSMOKEPRESET preset Smoke preset (1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke).
|
-- @param #number Preset Smoke preset (1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke).
|
||||||
-- @param #number density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
|
-- @param #number Density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
function COORDINATE:BigSmokeAndFire( preset, density, name )
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
self:F2( { preset=preset, density=density } )
|
-- @param #string Name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
density=density or 0.5
|
-- @return #COORDINATE self
|
||||||
self.firename = name or "Fire-"..math.random(1,10000)
|
function COORDINATE:BigSmokeAndFire( Preset, Density, Duration, Delay, Name )
|
||||||
trigger.action.effectSmokeBig( self:GetVec3(), preset, density, self.firename )
|
self:F2( { preset=Preset, density=Density } )
|
||||||
|
|
||||||
|
Preset=Preset or BIGSMOKEPRESET.SmallSmokeAndFire
|
||||||
|
Density=Density or 0.5
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, COORDINATE.BigSmokeAndFire, self, Preset, Density, Duration, 0, Name)
|
||||||
|
else
|
||||||
|
|
||||||
|
self.firename = Name or "Fire-"..math.random(1,10000)
|
||||||
|
|
||||||
|
trigger.action.effectSmokeBig( self:GetVec3(), Preset, Density, self.firename )
|
||||||
|
|
||||||
|
-- Stop smoke
|
||||||
|
if Duration and Duration>0 then
|
||||||
|
self:ScheduleOnce(Duration, COORDINATE.StopBigSmokeAndFire, self, self.firename )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stop big smoke and fire at the coordinate.
|
--- Stop big smoke and fire at the coordinate.
|
||||||
@@ -2019,82 +2328,98 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- Small smoke and fire at the coordinate.
|
--- Small smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
function COORDINATE:BigSmokeAndFireSmall( density, name )
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
self:F2( { density=density } )
|
-- @param #string Name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
density=density or 0.5
|
-- @return #COORDINATE self
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, density, name)
|
function COORDINATE:BigSmokeAndFireSmall( Density, Duration, Delay, Name )
|
||||||
|
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Medium smoke and fire at the coordinate.
|
--- Medium smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeAndFireMedium( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeAndFireMedium( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Large smoke and fire at the coordinate.
|
--- Large smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeAndFireLarge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeAndFireLarge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Huge smoke and fire at the coordinate.
|
--- Huge smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeAndFireHuge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeAndFireHuge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Small smoke at the coordinate.
|
--- Small smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeSmall( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeSmall( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Medium smoke at the coordinate.
|
--- Medium smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeMedium( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeMedium( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Large smoke at the coordinate.
|
--- Large smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeLarge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeLarge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, density,name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Huge smoke at the coordinate.
|
--- Huge smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeHuge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeHuge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, density,name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Flares the point in a color.
|
--- Flares the point in a color.
|
||||||
@@ -2410,7 +2735,7 @@ do -- COORDINATE
|
|||||||
for i,coord in ipairs(Coordinates) do
|
for i,coord in ipairs(Coordinates) do
|
||||||
vecs[i+1]=coord:GetVec3()
|
vecs[i+1]=coord:GetVec3()
|
||||||
end
|
end
|
||||||
|
|
||||||
if #vecs<3 then
|
if #vecs<3 then
|
||||||
self:E("ERROR: A free form polygon needs at least three points!")
|
self:E("ERROR: A free form polygon needs at least three points!")
|
||||||
elseif #vecs==3 then
|
elseif #vecs==3 then
|
||||||
@@ -2748,8 +3073,10 @@ do -- COORDINATE
|
|||||||
local sunrise=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, true, Tdiff)
|
local sunrise=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, true, Tdiff)
|
||||||
local sunset=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tdiff)
|
local sunset=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tdiff)
|
||||||
|
|
||||||
if sunrise == "N/R" then return false end
|
if type(sunrise) == "string" or type(sunset) == "string" then
|
||||||
if sunrise == "N/S" then return true end
|
if sunrise == "N/R" then return false end
|
||||||
|
if sunset == "N/S" then return true end
|
||||||
|
end
|
||||||
|
|
||||||
local time=UTILS.ClockToSeconds(clock)
|
local time=UTILS.ClockToSeconds(clock)
|
||||||
|
|
||||||
@@ -2767,6 +3094,11 @@ do -- COORDINATE
|
|||||||
|
|
||||||
-- Todays sun set in sec.
|
-- Todays sun set in sec.
|
||||||
local sunset=self:GetSunset(true)
|
local sunset=self:GetSunset(true)
|
||||||
|
|
||||||
|
if type(sunrise) == "string" or type(sunset) == "string" then
|
||||||
|
if sunrise == "N/R" then return false end
|
||||||
|
if sunset == "N/S" then return true end
|
||||||
|
end
|
||||||
|
|
||||||
-- Seconds passed since midnight.
|
-- Seconds passed since midnight.
|
||||||
local time=UTILS.SecondsOfToday()
|
local time=UTILS.SecondsOfToday()
|
||||||
@@ -2900,12 +3232,13 @@ do -- COORDINATE
|
|||||||
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
|
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
|
||||||
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
|
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
|
||||||
-- @param #boolean MagVar If true, also get angle in MagVar for BR/BRA
|
-- @param #boolean MagVar If true, also get angle in MagVar for BR/BRA
|
||||||
|
-- @param #number Precision Rounding precision, currently full km as default (=0)
|
||||||
-- @return #string The BR text.
|
-- @return #string The BR text.
|
||||||
function COORDINATE:ToStringBR( FromCoordinate, Settings, MagVar )
|
function COORDINATE:ToStringBR( FromCoordinate, Settings, MagVar, Precision )
|
||||||
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
|
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
|
||||||
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
|
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
|
||||||
local Distance = self:Get2DDistance( FromCoordinate )
|
local Distance = self:Get2DDistance( FromCoordinate )
|
||||||
return "BR, " .. self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar )
|
return "BR, " .. self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar, Precision )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return a BRA string from a COORDINATE to the COORDINATE.
|
--- Return a BRA string from a COORDINATE to the COORDINATE.
|
||||||
@@ -2941,6 +3274,8 @@ do -- COORDINATE
|
|||||||
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
|
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
|
||||||
|
|
||||||
local bearing = UTILS.Round( UTILS.ToDegree( AngleRadians ),0 )
|
local bearing = UTILS.Round( UTILS.ToDegree( AngleRadians ),0 )
|
||||||
|
local magnetic = self:GetMagneticDeclination() or 0
|
||||||
|
bearing = bearing - magnetic
|
||||||
|
|
||||||
local rangeMetres = self:Get2DDistance(currentCoord)
|
local rangeMetres = self:Get2DDistance(currentCoord)
|
||||||
local rangeNM = UTILS.Round( UTILS.MetersToNM(rangeMetres), 0)
|
local rangeNM = UTILS.Round( UTILS.MetersToNM(rangeMetres), 0)
|
||||||
@@ -3313,16 +3648,16 @@ do -- COORDINATE
|
|||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable to retrieve the settings from, otherwise the default settings will be chosen.
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable to retrieve the settings from, otherwise the default settings will be chosen.
|
||||||
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
|
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
|
||||||
-- @param Tasking.Task#TASK Task The task for which coordinates need to be calculated.
|
|
||||||
-- @return #string The coordinate Text in the configured coordinate system.
|
-- @return #string The coordinate Text in the configured coordinate system.
|
||||||
function COORDINATE:ToString( Controllable, Settings, Task )
|
function COORDINATE:ToString( Controllable, Settings )
|
||||||
|
|
||||||
-- self:E( { Controllable = Controllable and Controllable:GetName() } )
|
-- self:E( { Controllable = Controllable and Controllable:GetName() } )
|
||||||
|
|
||||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
|
||||||
local ModeA2A = nil
|
local ModeA2A = nil
|
||||||
|
|
||||||
|
--[[
|
||||||
if Task then
|
if Task then
|
||||||
if Task:IsInstanceOf( TASK_A2A ) then
|
if Task:IsInstanceOf( TASK_A2A ) then
|
||||||
ModeA2A = true
|
ModeA2A = true
|
||||||
@@ -3339,7 +3674,7 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
if ModeA2A == nil then
|
if ModeA2A == nil then
|
||||||
local IsAir = Controllable and ( Controllable:IsAirPlane() or Controllable:IsHelicopter() ) or false
|
local IsAir = Controllable and ( Controllable:IsAirPlane() or Controllable:IsHelicopter() ) or false
|
||||||
@@ -3454,9 +3789,18 @@ do -- COORDINATE
|
|||||||
return flat, elev
|
return flat, elev
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Return a random COORDINATE within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param DCS#Distance OuterRadius
|
||||||
|
-- @param DCS#Distance InnerRadius
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
|
||||||
|
return COORDINATE:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- POINT_VEC3
|
do
|
||||||
|
|
||||||
--- The POINT_VEC3 class
|
--- The POINT_VEC3 class
|
||||||
-- @type POINT_VEC3
|
-- @type POINT_VEC3
|
||||||
@@ -3473,6 +3817,8 @@ do -- POINT_VEC3
|
|||||||
|
|
||||||
--- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space.
|
--- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space.
|
||||||
--
|
--
|
||||||
|
-- **DEPRECATED - PLEASE USE COORDINATE!**
|
||||||
|
--
|
||||||
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
|
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
|
||||||
-- In order to keep the credibility of the the author,
|
-- In order to keep the credibility of the the author,
|
||||||
-- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors,
|
-- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors,
|
||||||
@@ -3560,130 +3906,19 @@ do -- POINT_VEC3
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a new POINT_VEC3 object from Vec2 coordinates.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Vec2 Vec2 The Vec2 point.
|
|
||||||
-- @param DCS#Distance LandHeightAdd (optional) Add a landheight.
|
|
||||||
-- @return Core.Point#POINT_VEC3 self
|
|
||||||
function POINT_VEC3:NewFromVec2( Vec2, LandHeightAdd )
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) ) -- Core.Point#POINT_VEC3
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Create a new POINT_VEC3 object from Vec3 coordinates.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Vec3 Vec3 The Vec3 point.
|
|
||||||
-- @return Core.Point#POINT_VEC3 self
|
|
||||||
function POINT_VEC3:NewFromVec3( Vec3 )
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:NewFromVec3( Vec3 ) ) -- Core.Point#POINT_VEC3
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Return the x coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @return #number The x coordinate.
|
|
||||||
function POINT_VEC3:GetX()
|
|
||||||
return self.x
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the y coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @return #number The y coordinate.
|
|
||||||
function POINT_VEC3:GetY()
|
|
||||||
return self.y
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the z coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @return #number The z coordinate.
|
|
||||||
function POINT_VEC3:GetZ()
|
|
||||||
return self.z
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the x coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number x The x coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:SetX( x )
|
|
||||||
self.x = x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the y coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number y The y coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:SetY( y )
|
|
||||||
self.y = y
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the z coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number z The z coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:SetZ( z )
|
|
||||||
self.z = z
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the x coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number x The x coordinate value to add to the current x coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:AddX( x )
|
|
||||||
self.x = self.x + x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the y coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number y The y coordinate value to add to the current y coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:AddY( y )
|
|
||||||
self.y = self.y + y
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the z coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number z The z coordinate value to add to the current z coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:AddZ( z )
|
|
||||||
self.z = self.z +z
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return a random POINT_VEC3 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Distance OuterRadius
|
|
||||||
-- @param DCS#Distance InnerRadius
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
|
|
||||||
|
|
||||||
return POINT_VEC3:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- POINT_VEC2
|
do
|
||||||
|
|
||||||
-- @type POINT_VEC2
|
--- @type POINT_VEC2
|
||||||
-- @field DCS#Distance x The x coordinate in meters.
|
-- @field DCS#Distance x The x coordinate in meters.
|
||||||
-- @field DCS#Distance y the y coordinate in meters.
|
-- @field DCS#Distance y the y coordinate in meters.
|
||||||
-- @extends Core.Point#COORDINATE
|
-- @extends Core.Point#COORDINATE
|
||||||
|
|
||||||
--- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
|
--- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
|
||||||
--
|
--
|
||||||
|
-- **DEPRECATED - PLEASE USE COORDINATE!**
|
||||||
|
--
|
||||||
-- ## POINT_VEC2 constructor
|
-- ## POINT_VEC2 constructor
|
||||||
--
|
--
|
||||||
-- A new POINT_VEC2 instance can be created with:
|
-- A new POINT_VEC2 instance can be created with:
|
||||||
@@ -3731,166 +3966,4 @@ do -- POINT_VEC2
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a new POINT_VEC2 object from Vec2 coordinates.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param DCS#Vec2 Vec2 The Vec2 point.
|
|
||||||
-- @return Core.Point#POINT_VEC2 self
|
|
||||||
function POINT_VEC2:NewFromVec2( Vec2, LandHeightAdd )
|
|
||||||
|
|
||||||
local LandHeight = land.getHeight( Vec2 )
|
|
||||||
|
|
||||||
LandHeightAdd = LandHeightAdd or 0
|
|
||||||
LandHeight = LandHeight + LandHeightAdd
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) ) -- #POINT_VEC2
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Create a new POINT_VEC2 object from Vec3 coordinates.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param DCS#Vec3 Vec3 The Vec3 point.
|
|
||||||
-- @return Core.Point#POINT_VEC2 self
|
|
||||||
function POINT_VEC2:NewFromVec3( Vec3 )
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:NewFromVec3( Vec3 ) ) -- #POINT_VEC2
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the x coordinate of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @return #number The x coordinate.
|
|
||||||
function POINT_VEC2:GetX()
|
|
||||||
return self.x
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the y coordinate of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @return #number The y coordinate.
|
|
||||||
function POINT_VEC2:GetY()
|
|
||||||
return self.z
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the x coordinate of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number x The x coordinate.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:SetX( x )
|
|
||||||
self.x = x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the y coordinate of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number y The y coordinate.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:SetY( y )
|
|
||||||
self.z = y
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return Return the Lat(itude) coordinate of the POINT_VEC2 (ie: (parent)POINT_VEC3.x).
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @return #number The x coordinate.
|
|
||||||
function POINT_VEC2:GetLat()
|
|
||||||
return self.x
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the Lat(itude) coordinate of the POINT_VEC2 (ie: POINT_VEC3.x).
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number x The x coordinate.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:SetLat( x )
|
|
||||||
self.x = x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the Lon(gitude) coordinate of the POINT_VEC2 (ie: (parent)POINT_VEC3.z).
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @return #number The y coordinate.
|
|
||||||
function POINT_VEC2:GetLon()
|
|
||||||
return self.z
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the Lon(gitude) coordinate of the POINT_VEC2 (ie: POINT_VEC3.z).
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number y The y coordinate.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:SetLon( z )
|
|
||||||
self.z = z
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the altitude (height) of the land at the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @return #number The land altitude.
|
|
||||||
function POINT_VEC2:GetAlt()
|
|
||||||
return self.y ~= 0 or land.getHeight( { x = self.x, y = self.z } )
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the altitude of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number Altitude The land altitude. If nothing (nil) is given, then the current land altitude is set.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:SetAlt( Altitude )
|
|
||||||
self.y = Altitude or land.getHeight( { x = self.x, y = self.z } )
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the x coordinate of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number x The x coordinate.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:AddX( x )
|
|
||||||
self.x = self.x + x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the y coordinate of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number y The y coordinate.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:AddY( y )
|
|
||||||
self.z = self.z + y
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the current land height an altitude.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:AddAlt( Altitude )
|
|
||||||
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Return a random POINT_VEC2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC2.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param DCS#Distance OuterRadius
|
|
||||||
-- @param DCS#Distance InnerRadius
|
|
||||||
-- @return #POINT_VEC2
|
|
||||||
function POINT_VEC2:GetRandomPointVec2InRadius( OuterRadius, InnerRadius )
|
|
||||||
self:F2( { OuterRadius, InnerRadius } )
|
|
||||||
|
|
||||||
return POINT_VEC2:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) )
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO: Check this to replace
|
|
||||||
--- Calculate the distance from a reference @{#POINT_VEC2}.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param #POINT_VEC2 PointVec2Reference The reference @{#POINT_VEC2}.
|
|
||||||
-- @return DCS#Distance The distance from the reference @{#POINT_VEC2} in meters.
|
|
||||||
function POINT_VEC2:DistanceFromPointVec2( PointVec2Reference )
|
|
||||||
self:F2( PointVec2Reference )
|
|
||||||
|
|
||||||
local Distance = ( ( PointVec2Reference.x - self.x ) ^ 2 + ( PointVec2Reference.z - self.z ) ^2 ) ^ 0.5
|
|
||||||
|
|
||||||
self:T2( Distance )
|
|
||||||
return Distance
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -289,7 +289,14 @@ do -- SET_BASE
|
|||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
--self:T2( { ObjectName = ObjectName, Object = Object } )
|
--self:T2( { ObjectName = ObjectName, Object = Object } )
|
||||||
|
|
||||||
|
-- Error ahndling
|
||||||
|
if not ObjectName or ObjectName == "" then
|
||||||
|
self:E("SET_BASE:Add - Invalid ObjectName handed")
|
||||||
|
self:E({ObjectName=ObjectName, Object=Object})
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
-- Ensure that the existing element is removed from the Set before a new one is inserted to the Set
|
-- Ensure that the existing element is removed from the Set before a new one is inserted to the Set
|
||||||
if self.Set[ObjectName] then
|
if self.Set[ObjectName] then
|
||||||
self:Remove( ObjectName, true )
|
self:Remove( ObjectName, true )
|
||||||
@@ -524,6 +531,21 @@ do -- SET_BASE
|
|||||||
|
|
||||||
return self.SomeIteratorLimit or self:Count()
|
return self.SomeIteratorLimit or self:Count()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get max threat level of all objects in the SET.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @return #number Max threat level found.
|
||||||
|
function SET_BASE:GetThreatLevelMax()
|
||||||
|
local ThreatMax = 0
|
||||||
|
for _,_unit in pairs(self.Set or {}) do
|
||||||
|
local unit = _unit -- Wrapper.Unit#UNIT
|
||||||
|
local threat = unit.GetThreatLevel and unit:GetThreatLevel() or 0
|
||||||
|
if threat > ThreatMax then
|
||||||
|
ThreatMax = threat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ThreatMax
|
||||||
|
end
|
||||||
|
|
||||||
--- Filters for the defined collection.
|
--- Filters for the defined collection.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
@@ -607,14 +629,14 @@ do -- SET_BASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Iterate the SET_BASE while identifying the nearest object in the set from a @{Core.Point#POINT_VEC2}.
|
--- Iterate the SET_BASE while identifying the nearest object in the set from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#COORDINATE} or @{Core.Point#POINT_VEC2} object (but **not** a simple DCS#Vec2!) from where to evaluate the closest object in the set.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object (but **not** a simple DCS#Vec2!) from where to evaluate the closest object in the set.
|
||||||
-- @return Core.Base#BASE The closest object.
|
-- @return Core.Base#BASE The closest object.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- myset:FindNearestObjectFromPointVec2( ZONE:New("Test Zone"):GetCoordinate() )
|
-- myset:FindNearestObjectFromPointVec2( ZONE:New("Test Zone"):GetCoordinate() )
|
||||||
function SET_BASE:FindNearestObjectFromPointVec2( PointVec2 )
|
function SET_BASE:FindNearestObjectFromPointVec2( Coordinate )
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestObject = nil
|
local NearestObject = nil
|
||||||
local ClosestDistance = nil
|
local ClosestDistance = nil
|
||||||
@@ -622,9 +644,9 @@ do -- SET_BASE
|
|||||||
for ObjectID, ObjectData in pairs( self.Set ) do
|
for ObjectID, ObjectData in pairs( self.Set ) do
|
||||||
if NearestObject == nil then
|
if NearestObject == nil then
|
||||||
NearestObject = ObjectData
|
NearestObject = ObjectData
|
||||||
ClosestDistance = PointVec2:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
ClosestDistance = Coordinate:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
||||||
else
|
else
|
||||||
local Distance = PointVec2:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
local Distance = Coordinate:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
||||||
if Distance < ClosestDistance then
|
if Distance < ClosestDistance then
|
||||||
NearestObject = ObjectData
|
NearestObject = ObjectData
|
||||||
ClosestDistance = Distance
|
ClosestDistance = Distance
|
||||||
@@ -1220,12 +1242,12 @@ do
|
|||||||
return GroupFound
|
return GroupFound
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Iterate the SET_GROUP while identifying the nearest object from a @{Core.Point#POINT_VEC2}.
|
--- Iterate the SET_GROUP while identifying the nearest object from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest object in the set.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object from where to evaluate the closest object in the set.
|
||||||
-- @return Wrapper.Group#GROUP The closest group.
|
-- @return Wrapper.Group#GROUP The closest group.
|
||||||
function SET_GROUP:FindNearestGroupFromPointVec2( PointVec2 )
|
function SET_GROUP:FindNearestGroupFromPointVec2( Coordinate )
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestGroup = nil -- Wrapper.Group#GROUP
|
local NearestGroup = nil -- Wrapper.Group#GROUP
|
||||||
local ClosestDistance = nil
|
local ClosestDistance = nil
|
||||||
@@ -1235,9 +1257,9 @@ do
|
|||||||
for ObjectID, ObjectData in pairs( Set ) do
|
for ObjectID, ObjectData in pairs( Set ) do
|
||||||
if NearestGroup == nil then
|
if NearestGroup == nil then
|
||||||
NearestGroup = ObjectData
|
NearestGroup = ObjectData
|
||||||
ClosestDistance = PointVec2:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
ClosestDistance = Coordinate:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
||||||
else
|
else
|
||||||
local Distance = PointVec2:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
local Distance = Coordinate:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
||||||
if Distance < ClosestDistance then
|
if Distance < ClosestDistance then
|
||||||
NearestGroup = ObjectData
|
NearestGroup = ObjectData
|
||||||
ClosestDistance = Distance
|
ClosestDistance = Distance
|
||||||
@@ -1538,6 +1560,13 @@ do
|
|||||||
local size = 1
|
local size = 1
|
||||||
if Event.IniDCSGroup then
|
if Event.IniDCSGroup then
|
||||||
size = Event.IniDCSGroup:getSize()
|
size = Event.IniDCSGroup:getSize()
|
||||||
|
elseif Event.IniDCSGroupName then
|
||||||
|
local grp = Group.getByName(Event.IniDCSGroupName)
|
||||||
|
if grp then
|
||||||
|
size = grp:getSize()
|
||||||
|
end
|
||||||
|
elseif Object:IsAlive() then
|
||||||
|
size = Object:CountAliveUnits()
|
||||||
end
|
end
|
||||||
if size == 1 then -- Only remove if the last unit of the group was destroyed.
|
if size == 1 then -- Only remove if the last unit of the group was destroyed.
|
||||||
self:Remove( ObjectName )
|
self:Remove( ObjectName )
|
||||||
@@ -2490,6 +2519,35 @@ do -- SET_UNIT
|
|||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Builds a set of units which belong to groups with certain **group names**.
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @param #string Prefixes The (partial) group names to look for. Can be a single string or a table of strings.
|
||||||
|
-- @return #SET_UNIT self
|
||||||
|
function SET_UNIT:FilterGroupPrefixes(Prefixes)
|
||||||
|
if type(Prefixes) == "string" then
|
||||||
|
Prefixes = {Prefixes}
|
||||||
|
end
|
||||||
|
self:FilterFunction(
|
||||||
|
function(unit,prefixes)
|
||||||
|
local outcome = false
|
||||||
|
if unit then
|
||||||
|
local grp = unit:GetGroup()
|
||||||
|
local gname = grp ~= nil and grp:GetName() or "none"
|
||||||
|
for _,_fix in pairs(prefixes or {}) do
|
||||||
|
if string.find(gname,_fix) then
|
||||||
|
outcome = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return outcome
|
||||||
|
end, Prefixes
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Builds a set of units having a radar of give types.
|
--- Builds a set of units having a radar of give types.
|
||||||
-- All the units having a radar of a given type will be included within the set.
|
-- All the units having a radar of a given type will be included within the set.
|
||||||
@@ -4405,6 +4463,35 @@ do -- SET_CLIENT
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Builds a set of clients which belong to groups with certain **group names**.
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @param #string Prefixes The (partial) group names to look for. Can be anywhere in the group name. Can be a single string or a table of strings.
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
function SET_CLIENT:FilterGroupPrefixes(Prefixes)
|
||||||
|
if type(Prefixes) == "string" then
|
||||||
|
Prefixes = {Prefixes}
|
||||||
|
end
|
||||||
|
self:FilterFunction(
|
||||||
|
function(unit,prefixes)
|
||||||
|
local outcome = false
|
||||||
|
if unit then
|
||||||
|
local grp = unit:GetGroup()
|
||||||
|
local gname = grp ~= nil and grp:GetName() or "none"
|
||||||
|
for _,_fix in pairs(prefixes or {}) do
|
||||||
|
if string.find(gname,_fix) then
|
||||||
|
outcome = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return outcome
|
||||||
|
end, Prefixes
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Builds a set of clients that are only active.
|
--- Builds a set of clients that are only active.
|
||||||
-- Only the clients that are active will be included within the set.
|
-- Only the clients that are active will be included within the set.
|
||||||
@@ -4582,6 +4669,16 @@ do -- SET_CLIENT
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Make the SET handle CA slots **only** (GROUND units used by any player). Needs active filtering with `FilterStart()`
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
function SET_CLIENT:HandleCASlots()
|
||||||
|
self:HandleEvent(EVENTS.PlayerEnterUnit,SET_CLIENT._EventPlayerEnterUnit)
|
||||||
|
self:HandleEvent(EVENTS.PlayerLeaveUnit,SET_CLIENT._EventPlayerLeaveUnit)
|
||||||
|
self:FilterFunction(function(client) if client and client:IsAlive() and client:IsGround() then return true else return false end end)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
||||||
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
||||||
@@ -5364,6 +5461,7 @@ do -- SET_AIRBASE
|
|||||||
Airbases = {},
|
Airbases = {},
|
||||||
Filter = {
|
Filter = {
|
||||||
Coalitions = nil,
|
Coalitions = nil,
|
||||||
|
Zones = nil,
|
||||||
},
|
},
|
||||||
FilterMeta = {
|
FilterMeta = {
|
||||||
Coalitions = {
|
Coalitions = {
|
||||||
@@ -5515,6 +5613,31 @@ do -- SET_AIRBASE
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Builds a set of airbase objects in zones.
|
||||||
|
-- @param #SET_AIRBASE self
|
||||||
|
-- @param #table Zones Table of Core.Zone#ZONE Zone objects, or a Core.Set#SET_ZONE
|
||||||
|
-- @return #SET_AIRBASE self
|
||||||
|
function SET_AIRBASE:FilterZones( Zones )
|
||||||
|
if not self.Filter.Zones then
|
||||||
|
self.Filter.Zones = {}
|
||||||
|
end
|
||||||
|
local zones = {}
|
||||||
|
if Zones.ClassName and Zones.ClassName == "SET_ZONE" then
|
||||||
|
zones = Zones.Set
|
||||||
|
elseif type( Zones ) ~= "table" or (type( Zones ) == "table" and Zones.ClassName ) then
|
||||||
|
self:E("***** FilterZones needs either a table of ZONE Objects or a SET_ZONE as parameter!")
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
zones = Zones
|
||||||
|
end
|
||||||
|
for _,Zone in pairs( zones ) do
|
||||||
|
local zonename = Zone:GetName()
|
||||||
|
--self:T((zonename)
|
||||||
|
self.Filter.Zones[zonename] = Zone
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Starts the filtering.
|
--- Starts the filtering.
|
||||||
-- @param #SET_AIRBASE self
|
-- @param #SET_AIRBASE self
|
||||||
@@ -5605,14 +5728,14 @@ do -- SET_AIRBASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Iterate the SET_AIRBASE while identifying the nearest @{Wrapper.Airbase#AIRBASE} from a @{Core.Point#POINT_VEC2}.
|
--- Iterate the SET_AIRBASE while identifying the nearest @{Wrapper.Airbase#AIRBASE} from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_AIRBASE self
|
-- @param #SET_AIRBASE self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest @{Wrapper.Airbase#AIRBASE}.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object from where to evaluate the closest @{Wrapper.Airbase#AIRBASE}.
|
||||||
-- @return Wrapper.Airbase#AIRBASE The closest @{Wrapper.Airbase#AIRBASE}.
|
-- @return Wrapper.Airbase#AIRBASE The closest @{Wrapper.Airbase#AIRBASE}.
|
||||||
function SET_AIRBASE:FindNearestAirbaseFromPointVec2( PointVec2 )
|
function SET_AIRBASE:FindNearestAirbaseFromPointVec2( Coordinate )
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestAirbase = self:FindNearestObjectFromPointVec2( PointVec2 )
|
local NearestAirbase = self:FindNearestObjectFromPointVec2( Coordinate )
|
||||||
return NearestAirbase
|
return NearestAirbase
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -5653,6 +5776,20 @@ do -- SET_AIRBASE
|
|||||||
--self:T(( { "Evaluated Category", MAirbaseCategory } )
|
--self:T(( { "Evaluated Category", MAirbaseCategory } )
|
||||||
MAirbaseInclude = MAirbaseInclude and MAirbaseCategory
|
MAirbaseInclude = MAirbaseInclude and MAirbaseCategory
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.Filter.Zones and MAirbaseInclude then
|
||||||
|
local MAirbaseZone = false
|
||||||
|
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
||||||
|
--self:T(( "Zone:", ZoneName )
|
||||||
|
local coord = MAirbase:GetCoordinate()
|
||||||
|
if coord and Zone:IsCoordinateInZone(coord) then
|
||||||
|
MAirbaseZone = true
|
||||||
|
end
|
||||||
|
--self:T(( { "Evaluated Zone", MSceneryZone } )
|
||||||
|
end
|
||||||
|
MAirbaseInclude = MAirbaseInclude and MAirbaseZone
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Functions and MAirbaseInclude then
|
if self.Filter.Functions and MAirbaseInclude then
|
||||||
@@ -5928,17 +6065,19 @@ do -- SET_CARGO
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (R2.1) Iterate the SET_CARGO while identifying the nearest @{Cargo.Cargo#CARGO} from a @{Core.Point#POINT_VEC2}.
|
--- (R2.1) Iterate the SET_CARGO while identifying the nearest @{Cargo.Cargo#CARGO} from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_CARGO self
|
-- @param #SET_CARGO self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest @{Cargo.Cargo#CARGO}.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object from where to evaluate the closest @{Cargo.Cargo#CARGO}.
|
||||||
-- @return Cargo.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
-- @return Cargo.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
||||||
function SET_CARGO:FindNearestCargoFromPointVec2( PointVec2 ) -- R2.1
|
function SET_CARGO:FindNearestCargoFromPointVec2( Coordinate ) -- R2.1
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestCargo = self:FindNearestObjectFromPointVec2( PointVec2 )
|
local NearestCargo = self:FindNearestObjectFromPointVec2( Coordinate )
|
||||||
return NearestCargo
|
return NearestCargo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @param #SET_CARGO self
|
||||||
function SET_CARGO:FirstCargoWithState( State )
|
function SET_CARGO:FirstCargoWithState( State )
|
||||||
|
|
||||||
local FirstCargo = nil
|
local FirstCargo = nil
|
||||||
@@ -5953,6 +6092,8 @@ do -- SET_CARGO
|
|||||||
return FirstCargo
|
return FirstCargo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @param #SET_CARGO self
|
||||||
function SET_CARGO:FirstCargoWithStateAndNotDeployed( State )
|
function SET_CARGO:FirstCargoWithStateAndNotDeployed( State )
|
||||||
|
|
||||||
local FirstCargo = nil
|
local FirstCargo = nil
|
||||||
@@ -7971,7 +8112,7 @@ function SET_OPSGROUP:_EventOnBirth(Event)
|
|||||||
function SET_OPSGROUP:_EventOnDeadOrCrash( Event )
|
function SET_OPSGROUP:_EventOnDeadOrCrash( Event )
|
||||||
--self:F( { Event } )
|
--self:F( { Event } )
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSGroup then
|
||||||
local ObjectName, Object = self:FindInDatabase( Event )
|
local ObjectName, Object = self:FindInDatabase( Event )
|
||||||
if ObjectName then
|
if ObjectName then
|
||||||
if Event.IniDCSGroup:getSize() == 1 then -- Only remove if the last unit of the group was destroyed.
|
if Event.IniDCSGroup:getSize() == 1 then -- Only remove if the last unit of the group was destroyed.
|
||||||
@@ -8614,7 +8755,6 @@ do -- SET_DYNAMICCARGO
|
|||||||
-- @field #SET_DYNAMICCARGO SET_DYNAMICCARGO
|
-- @field #SET_DYNAMICCARGO SET_DYNAMICCARGO
|
||||||
SET_DYNAMICCARGO = {
|
SET_DYNAMICCARGO = {
|
||||||
ClassName = "SET_DYNAMICCARGO",
|
ClassName = "SET_DYNAMICCARGO",
|
||||||
Filter = {},
|
|
||||||
Set = {},
|
Set = {},
|
||||||
List = {},
|
List = {},
|
||||||
Index = {},
|
Index = {},
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ do -- SETTINGS
|
|||||||
return (self.A2ASystem and self.A2ASystem == "MGRS") or (not self.A2ASystem and _SETTINGS:IsA2A_MGRS())
|
return (self.A2ASystem and self.A2ASystem == "MGRS") or (not self.A2ASystem and _SETTINGS:IsA2A_MGRS())
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
-- @param Wrapper.Group#GROUP MenuGroup Group for which to add menus.
|
-- @param Wrapper.Group#GROUP MenuGroup Group for which to add menus.
|
||||||
-- @param #table RootMenu Root menu table
|
-- @param #table RootMenu Root menu table
|
||||||
-- @return #SETTINGS
|
-- @return #SETTINGS
|
||||||
@@ -948,49 +948,49 @@ do -- SETTINGS
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
|
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
|
||||||
self.A2GSystem = A2GSystem
|
self.A2GSystem = A2GSystem
|
||||||
MESSAGE:New( string.format( "Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
|
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
|
||||||
self.A2ASystem = A2ASystem
|
self.A2ASystem = A2ASystem
|
||||||
MESSAGE:New( string.format( "Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
|
function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
|
||||||
self.LL_Accuracy = LL_Accuracy
|
self.LL_Accuracy = LL_Accuracy
|
||||||
MESSAGE:New( string.format( "Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
|
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
|
||||||
self.MGRS_Accuracy = MGRS_Accuracy
|
self.MGRS_Accuracy = MGRS_Accuracy
|
||||||
MESSAGE:New( string.format( "Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
|
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
|
||||||
self.Metric = MW
|
self.Metric = MW
|
||||||
MESSAGE:New( string.format( "Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuMessageTimingsSystem( MenuGroup, RootMenu, MessageType, MessageTime )
|
function SETTINGS:MenuMessageTimingsSystem( MenuGroup, RootMenu, MessageType, MessageTime )
|
||||||
self:SetMessageTime( MessageType, MessageTime )
|
self:SetMessageTime( MessageType, MessageTime )
|
||||||
MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToAll()
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
|
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
|
||||||
--BASE:E( {PlayerUnit:GetName(), A2GSystem } )
|
--BASE:E( {PlayerUnit:GetName(), A2GSystem } )
|
||||||
self.A2GSystem = A2GSystem
|
self.A2GSystem = A2GSystem
|
||||||
@@ -1001,7 +1001,7 @@ do -- SETTINGS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
|
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
|
||||||
self.A2ASystem = A2ASystem
|
self.A2ASystem = A2ASystem
|
||||||
MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
@@ -1011,7 +1011,7 @@ do -- SETTINGS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
|
function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
|
||||||
self.LL_Accuracy = LL_Accuracy
|
self.LL_Accuracy = LL_Accuracy
|
||||||
MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
@@ -1021,7 +1021,7 @@ do -- SETTINGS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
|
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
|
||||||
self.MGRS_Accuracy = MGRS_Accuracy
|
self.MGRS_Accuracy = MGRS_Accuracy
|
||||||
MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
@@ -1031,7 +1031,7 @@ do -- SETTINGS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
|
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
|
||||||
self.Metric = MW
|
self.Metric = MW
|
||||||
MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
@@ -1041,7 +1041,7 @@ do -- SETTINGS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupMessageTimingsSystem( PlayerUnit, PlayerGroup, PlayerName, MessageType, MessageTime )
|
function SETTINGS:MenuGroupMessageTimingsSystem( PlayerUnit, PlayerGroup, PlayerName, MessageType, MessageTime )
|
||||||
self:SetMessageTime( MessageType, MessageTime )
|
self:SetMessageTime( MessageType, MessageTime )
|
||||||
MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToGroup( PlayerGroup )
|
||||||
|
|||||||
@@ -1081,7 +1081,7 @@ function SPAWN:InitRandomizeTemplate( SpawnTemplatePrefixTable )
|
|||||||
self.SpawnRandomizeTemplate = true
|
self.SpawnRandomizeTemplate = true
|
||||||
|
|
||||||
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
||||||
self:_RandomizeTemplate( SpawnGroupID )
|
self:_RandomizeTemplate( SpawnGroupID, RandomizePositionInZone )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -1093,6 +1093,7 @@ end
|
|||||||
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
|
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Set#SET_GROUP SpawnTemplateSet A SET_GROUP object set, that contains the groups that are possible unit representatives of the group to be spawned.
|
-- @param Core.Set#SET_GROUP SpawnTemplateSet A SET_GROUP object set, that contains the groups that are possible unit representatives of the group to be spawned.
|
||||||
|
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
||||||
-- @return #SPAWN
|
-- @return #SPAWN
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
@@ -1111,11 +1112,11 @@ end
|
|||||||
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
--
|
--
|
||||||
function SPAWN:InitRandomizeTemplateSet( SpawnTemplateSet )
|
function SPAWN:InitRandomizeTemplateSet( SpawnTemplateSet,RandomizePositionInZone )
|
||||||
--self:F( { self.SpawnTemplatePrefix } )
|
--self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
local setnames = SpawnTemplateSet:GetSetNames()
|
local setnames = SpawnTemplateSet:GetSetNames()
|
||||||
self:InitRandomizeTemplate(setnames)
|
self:InitRandomizeTemplate(setnames,RandomizePositionInZone)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1125,7 +1126,8 @@ end
|
|||||||
-- but they will all follow the same Template route and have the same prefix name.
|
-- but they will all follow the same Template route and have the same prefix name.
|
||||||
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
|
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #string SpawnTemplatePrefixes A string or a list of string that contains the prefixes of the groups that are possible unit representatives of the group to be spawned.
|
-- @param #string SpawnTemplatePrefixes A string or a list of string that contains the prefixes of the groups that are possible unit representatives of the group to be spawned.
|
||||||
|
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
||||||
-- @return #SPAWN
|
-- @return #SPAWN
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
@@ -1141,12 +1143,12 @@ end
|
|||||||
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
--
|
--
|
||||||
function SPAWN:InitRandomizeTemplatePrefixes( SpawnTemplatePrefixes ) -- R2.3
|
function SPAWN:InitRandomizeTemplatePrefixes( SpawnTemplatePrefixes, RandomizePositionInZone ) -- R2.3
|
||||||
--self:F( { self.SpawnTemplatePrefix } )
|
--self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
local SpawnTemplateSet = SET_GROUP:New():FilterPrefixes( SpawnTemplatePrefixes ):FilterOnce()
|
local SpawnTemplateSet = SET_GROUP:New():FilterPrefixes( SpawnTemplatePrefixes ):FilterOnce()
|
||||||
|
|
||||||
self:InitRandomizeTemplateSet( SpawnTemplateSet )
|
self:InitRandomizeTemplateSet( SpawnTemplateSet, RandomizePositionInZone )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1166,6 +1168,7 @@ end
|
|||||||
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
|
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Core.Zone}s objects.
|
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Core.Zone}s objects.
|
||||||
|
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
@@ -1178,7 +1181,7 @@ end
|
|||||||
-- :InitRandomizeZones( ZoneTable )
|
-- :InitRandomizeZones( ZoneTable )
|
||||||
-- :SpawnScheduled( 5, .5 )
|
-- :SpawnScheduled( 5, .5 )
|
||||||
--
|
--
|
||||||
function SPAWN:InitRandomizeZones( SpawnZoneTable )
|
function SPAWN:InitRandomizeZones( SpawnZoneTable, RandomizePositionInZone )
|
||||||
--self:F( { self.SpawnTemplatePrefix, SpawnZoneTable } )
|
--self:F( { self.SpawnTemplatePrefix, SpawnZoneTable } )
|
||||||
|
|
||||||
local temptable = {}
|
local temptable = {}
|
||||||
@@ -1190,7 +1193,7 @@ function SPAWN:InitRandomizeZones( SpawnZoneTable )
|
|||||||
self.SpawnRandomizeZones = true
|
self.SpawnRandomizeZones = true
|
||||||
|
|
||||||
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
||||||
self:_RandomizeZones( SpawnGroupID )
|
self:_RandomizeZones( SpawnGroupID, RandomizePositionInZone )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -1275,6 +1278,7 @@ end
|
|||||||
|
|
||||||
--- Respawn group after landing.
|
--- Respawn group after landing.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
|
-- @param #number WaitingTime Wait this many seconds before despawning the alive group after landing. Defaults to 3 .
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
@@ -1282,15 +1286,16 @@ end
|
|||||||
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
|
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
|
||||||
-- SpawnRU_SU34 = SPAWN:New( 'Su-34' )
|
-- SpawnRU_SU34 = SPAWN:New( 'Su-34' )
|
||||||
-- :InitRandomizeRoute( 1, 1, 3000 )
|
-- :InitRandomizeRoute( 1, 1, 3000 )
|
||||||
-- :InitRepeatOnLanding()
|
-- :InitRepeatOnLanding(20)
|
||||||
-- :Spawn()
|
-- :Spawn()
|
||||||
--
|
--
|
||||||
function SPAWN:InitRepeatOnLanding()
|
function SPAWN:InitRepeatOnLanding(WaitingTime)
|
||||||
--self:F( { self.SpawnTemplatePrefix } )
|
--self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
self:InitRepeat()
|
self:InitRepeat()
|
||||||
self.RepeatOnEngineShutDown = false
|
self.RepeatOnEngineShutDown = false
|
||||||
self.RepeatOnLanding = true
|
self.RepeatOnLanding = true
|
||||||
|
self.RepeatOnLandingTime = (WaitingTime and WaitingTime > 3) and WaitingTime or 3
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1626,7 +1631,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
|
|
||||||
if SpawnTemplate then
|
if SpawnTemplate then
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
|
local PointVec3 = COORDINATE:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
|
||||||
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
|
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
|
||||||
|
|
||||||
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
|
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
|
||||||
@@ -2028,12 +2033,10 @@ end
|
|||||||
--
|
--
|
||||||
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold, nil, AIRBASE.TerminalType.OpenBig )
|
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold, nil, AIRBASE.TerminalType.OpenBig )
|
||||||
--
|
--
|
||||||
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType, EmergencyAirSpawn, Parkingdata ) -- R2.2, R2.4
|
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType, EmergencyAirSpawn, Parkingdata )
|
||||||
--self:F( { self.SpawnTemplatePrefix, SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType } )
|
|
||||||
|
|
||||||
-- Get position of airbase.
|
-- Get position of airbase.
|
||||||
local PointVec3 = SpawnAirbase:GetCoordinate()
|
local PointVec3 = SpawnAirbase:GetCoordinate()
|
||||||
--self:T2( PointVec3 )
|
|
||||||
|
|
||||||
-- Set take off type. Default is hot.
|
-- Set take off type. Default is hot.
|
||||||
Takeoff = Takeoff or SPAWN.Takeoff.Hot
|
Takeoff = Takeoff or SPAWN.Takeoff.Hot
|
||||||
@@ -2043,39 +2046,24 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
EmergencyAirSpawn = true
|
EmergencyAirSpawn = true
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:F( { SpawnIndex = self.SpawnIndex } )
|
|
||||||
|
|
||||||
if self:_GetSpawnIndex( self.SpawnIndex + 1 ) then
|
if self:_GetSpawnIndex( self.SpawnIndex + 1 ) then
|
||||||
|
|
||||||
-- Get group template.
|
-- Get group template.
|
||||||
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
||||||
|
|
||||||
--self:F( { SpawnTemplate = SpawnTemplate } )
|
|
||||||
|
|
||||||
if SpawnTemplate then
|
if SpawnTemplate then
|
||||||
|
|
||||||
-- Check if the aircraft with the specified SpawnIndex is already spawned.
|
|
||||||
-- If yes, ensure that the aircraft is spawned at the same aircraft spot.
|
|
||||||
|
|
||||||
local GroupAlive = self:GetGroupFromIndex( self.SpawnIndex )
|
|
||||||
|
|
||||||
--self:F( { GroupAlive = GroupAlive } )
|
|
||||||
|
|
||||||
-- Debug output
|
|
||||||
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
|
||||||
|
|
||||||
-- Template group, unit and its attributes.
|
-- Template group, unit and its attributes.
|
||||||
local TemplateGroup = GROUP:FindByName( self.SpawnTemplatePrefix )
|
local group = GROUP:FindByName( self.SpawnTemplatePrefix )
|
||||||
local TemplateUnit = TemplateGroup:GetUnit( 1 )
|
local unit = group:GetUnit( 1 )
|
||||||
|
|
||||||
-- General category of spawned group.
|
-- General category of spawned group.
|
||||||
local group = TemplateGroup
|
|
||||||
local istransport = group:HasAttribute( "Transports" ) and group:HasAttribute( "Planes" )
|
local istransport = group:HasAttribute( "Transports" ) and group:HasAttribute( "Planes" )
|
||||||
local isawacs = group:HasAttribute( "AWACS" )
|
local isawacs = group:HasAttribute( "AWACS" )
|
||||||
local isfighter = group:HasAttribute( "Fighters" ) or group:HasAttribute( "Interceptors" ) or group:HasAttribute( "Multirole fighters" ) or (group:HasAttribute( "Bombers" ) and not group:HasAttribute( "Strategic bombers" ))
|
local isfighter = group:HasAttribute( "Fighters" ) or group:HasAttribute( "Interceptors" ) or group:HasAttribute( "Multirole fighters" ) or (group:HasAttribute( "Bombers" ) and not group:HasAttribute( "Strategic bombers" ))
|
||||||
local isbomber = group:HasAttribute( "Strategic bombers" )
|
local isbomber = group:HasAttribute( "Strategic bombers" )
|
||||||
local istanker = group:HasAttribute( "Tankers" )
|
local istanker = group:HasAttribute( "Tankers" )
|
||||||
local ishelo = TemplateUnit:HasAttribute( "Helicopters" )
|
local ishelo = unit:HasAttribute( "Helicopters" )
|
||||||
|
|
||||||
-- Number of units in the group. With grouping this can actually differ from the template group size!
|
-- Number of units in the group. With grouping this can actually differ from the template group size!
|
||||||
local nunits = #SpawnTemplate.units
|
local nunits = #SpawnTemplate.units
|
||||||
@@ -2093,40 +2081,32 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
local AirbaseCategory = SpawnAirbase:GetAirbaseCategory()
|
local AirbaseCategory = SpawnAirbase:GetAirbaseCategory()
|
||||||
--self:F( { AirbaseCategory = AirbaseCategory } )
|
--self:F( { AirbaseCategory = AirbaseCategory } )
|
||||||
|
|
||||||
-- Set airdromeId.
|
-- Set airdrome ID. For helipads and ships we need to add the helipad ID and linked unit.
|
||||||
|
-- Note, it is important not to set the airdrome ID for at least ships, because spawn will happen at origin of the map
|
||||||
if AirbaseCategory == Airbase.Category.SHIP then
|
if AirbaseCategory == Airbase.Category.SHIP then
|
||||||
SpawnPoint.linkUnit = AirbaseID
|
SpawnPoint.linkUnit = AirbaseID
|
||||||
SpawnPoint.helipadId = AirbaseID
|
SpawnPoint.helipadId = AirbaseID
|
||||||
elseif AirbaseCategory == Airbase.Category.HELIPAD then
|
elseif AirbaseCategory == Airbase.Category.HELIPAD then
|
||||||
SpawnPoint.linkUnit = AirbaseID
|
SpawnPoint.linkUnit = AirbaseID
|
||||||
SpawnPoint.helipadId = AirbaseID
|
SpawnPoint.helipadId = AirbaseID
|
||||||
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
else
|
||||||
SpawnPoint.airdromeId = AirbaseID
|
SpawnPoint.airdromeId = AirbaseID
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set waypoint type/action.
|
-- Set waypoint type/action.
|
||||||
SpawnPoint.alt = 0
|
SpawnPoint.alt = 0
|
||||||
SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
||||||
SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
||||||
|
|
||||||
-- Check if we spawn on ground.
|
-- Check if we spawn on ground.
|
||||||
local spawnonground = not (Takeoff == SPAWN.Takeoff.Air)
|
local spawnonground = not (Takeoff == SPAWN.Takeoff.Air)
|
||||||
--self:T2( { spawnonground = spawnonground, TOtype = Takeoff, TOair = Takeoff == SPAWN.Takeoff.Air } )
|
|
||||||
|
|
||||||
-- Check where we actually spawn if we spawn on ground.
|
-- Check where we actually spawn if we spawn on ground.
|
||||||
local spawnonship = false
|
local autoparking=false
|
||||||
local spawnonfarp = false
|
if SpawnAirbase.isAirdrome then
|
||||||
local spawnonrunway = false
|
autoparking=false
|
||||||
local spawnonairport = false
|
else
|
||||||
if spawnonground then
|
autoparking=true
|
||||||
if AirbaseCategory == Airbase.Category.SHIP then
|
|
||||||
spawnonship = true
|
|
||||||
elseif AirbaseCategory == Airbase.Category.HELIPAD then
|
|
||||||
spawnonfarp = true
|
|
||||||
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
|
||||||
spawnonairport = true
|
|
||||||
end
|
|
||||||
spawnonrunway = Takeoff == SPAWN.Takeoff.Runway
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Array with parking spots coordinates.
|
-- Array with parking spots coordinates.
|
||||||
@@ -2142,8 +2122,8 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
-- Set terminal type.
|
-- Set terminal type.
|
||||||
local termtype = TerminalType
|
local termtype = TerminalType
|
||||||
if spawnonrunway then
|
if Takeoff==SPAWN.Takeoff.Runway then
|
||||||
if spawnonship then
|
if SpawnAirbase.isShip then
|
||||||
-- Looks like there are no runway spawn spots on the stennis!
|
-- Looks like there are no runway spawn spots on the stennis!
|
||||||
if ishelo then
|
if ishelo then
|
||||||
termtype = AIRBASE.TerminalType.HelicopterUsable
|
termtype = AIRBASE.TerminalType.HelicopterUsable
|
||||||
@@ -2163,34 +2143,31 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
local verysafe = false
|
local verysafe = false
|
||||||
|
|
||||||
-- Number of free parking spots at the airbase.
|
-- Number of free parking spots at the airbase.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if autoparking then
|
||||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
--self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
|
||||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
--[[
|
|
||||||
elseif Parkingdata~=nil then
|
elseif Parkingdata~=nil then
|
||||||
-- Parking data explicitly set by user as input parameter.
|
-- Parking data explicitly set by user as input parameter. (This was commented out for some unknown reason. But I need it this way.)
|
||||||
nfree=#Parkingdata
|
nfree=#Parkingdata
|
||||||
spots=Parkingdata
|
spots=Parkingdata
|
||||||
]]
|
|
||||||
else
|
else
|
||||||
if ishelo then
|
if ishelo then
|
||||||
if termtype == nil then
|
if termtype == nil then
|
||||||
-- Helo is spawned. Try exclusive helo spots first.
|
-- Helo is spawned. Try exclusive helo spots first.
|
||||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
if nfree < nunits then
|
if nfree < nunits then
|
||||||
-- Not enough helo ports. Let's try also other terminal types.
|
-- Not enough helo ports. Let's try also other terminal types.
|
||||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- No terminal type specified. We try all spots except shelters.
|
-- No terminal type specified. We try all spots except shelters.
|
||||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -2199,44 +2176,33 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if isbomber or istransport or istanker or isawacs then
|
if isbomber or istransport or istanker or isawacs then
|
||||||
-- First we fill the potentially bigger spots.
|
-- First we fill the potentially bigger spots.
|
||||||
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenBig ) )
|
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenBig ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.OpenBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
if nfree < nunits then
|
if nfree < nunits then
|
||||||
-- Now we try the smaller ones.
|
-- Now we try the smaller ones.
|
||||||
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenMedOrBig ) )
|
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenMedOrBig ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenMedOrBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.OpenMedOrBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
--self:T2( string.format( "Fighter group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.FighterAircraft ) )
|
--self:T2( string.format( "Fighter group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.FighterAircraft ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.FighterAircraft, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.FighterAircraft, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Terminal type explicitly given.
|
-- Terminal type explicitly given.
|
||||||
--self:T2( string.format( "Plane group %s is at %s using terminal type %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), tostring( termtype ) ) )
|
--self:T2( string.format( "Plane group %s is at %s using terminal type %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), tostring( termtype ) ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug: Get parking data.
|
|
||||||
--[[
|
|
||||||
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
|
||||||
--self:T2(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
|
||||||
for _,_spot in pairs(parkingdata) do
|
|
||||||
--self:T2(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
|
||||||
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
|
||||||
end
|
|
||||||
--self:T2(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- Set this to true if not enough spots are available for emergency air start.
|
-- Set this to true if not enough spots are available for emergency air start.
|
||||||
local _notenough = false
|
local _notenough = false
|
||||||
|
|
||||||
-- Need to differentiate some cases again.
|
-- Need to differentiate some cases again.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if autoparking then
|
||||||
|
|
||||||
-- On free spot required in these cases.
|
-- On free spot required in these cases.
|
||||||
if nfree >= 1 then
|
if nfree >= 1 then
|
||||||
@@ -2254,7 +2220,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
_notenough = true
|
_notenough = true
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif spawnonairport then
|
else
|
||||||
|
|
||||||
if nfree >= nunits then
|
if nfree >= nunits then
|
||||||
|
|
||||||
@@ -2276,13 +2242,10 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
self:E( string.format( "WARNING: Group %s has no parking spots at %s ==> air start!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
self:E( string.format( "WARNING: Group %s has no parking spots at %s ==> air start!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
|
||||||
-- Not enough parking spots at the airport ==> Spawn in air.
|
-- Not enough parking spots at the airport ==> Spawn in air.
|
||||||
spawnonground = false
|
autoparking=false
|
||||||
spawnonship = false
|
|
||||||
spawnonfarp = false
|
|
||||||
spawnonrunway = false
|
|
||||||
|
|
||||||
-- Set waypoint type/action to turning point.
|
-- Set waypoint type/action to turning point.
|
||||||
SpawnPoint.type = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][1] -- type = Turning Point
|
SpawnPoint.type = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][1] -- type = Turning Point
|
||||||
SpawnPoint.action = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][2] -- action = Turning Point
|
SpawnPoint.action = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][2] -- action = Turning Point
|
||||||
|
|
||||||
-- Adjust altitude to be 500-1000 m above the airbase.
|
-- Adjust altitude to be 500-1000 m above the airbase.
|
||||||
@@ -2324,7 +2287,6 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
SpawnTemplate.parked = true
|
SpawnTemplate.parked = true
|
||||||
|
|
||||||
for UnitID = 1, nunits do
|
for UnitID = 1, nunits do
|
||||||
--self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
|
||||||
|
|
||||||
-- Template of the current unit.
|
-- Template of the current unit.
|
||||||
local UnitTemplate = SpawnTemplate.units[UnitID]
|
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||||
@@ -2340,9 +2302,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if spawnonground then
|
if spawnonground then
|
||||||
|
|
||||||
-- Ships and FARPS seem to have a build in queue.
|
-- Ships and FARPS seem to have a build in queue.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if autoparking then
|
||||||
|
|
||||||
--self:T2( string.format( "Group %s spawning at farp, ship or runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
|
||||||
|
|
||||||
-- Spawn on ship. We take only the position of the ship.
|
-- Spawn on ship. We take only the position of the ship.
|
||||||
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
||||||
@@ -2351,20 +2311,15 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
--self:T2( string.format( "Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID] ) )
|
|
||||||
|
|
||||||
-- Get coordinates of parking spot.
|
-- Get coordinates of parking spot.
|
||||||
SpawnTemplate.units[UnitID].x = parkingspots[UnitID].x
|
SpawnTemplate.units[UnitID].x = parkingspots[UnitID].x
|
||||||
SpawnTemplate.units[UnitID].y = parkingspots[UnitID].z
|
SpawnTemplate.units[UnitID].y = parkingspots[UnitID].z
|
||||||
SpawnTemplate.units[UnitID].alt = parkingspots[UnitID].y
|
SpawnTemplate.units[UnitID].alt = parkingspots[UnitID].y
|
||||||
|
|
||||||
-- parkingspots[UnitID]:MarkToAll(string.format("Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID]))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
--self:T2( string.format( "Group %s spawning in air at %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
|
||||||
|
|
||||||
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
||||||
SpawnTemplate.units[UnitID].x = TX
|
SpawnTemplate.units[UnitID].x = TX
|
||||||
SpawnTemplate.units[UnitID].y = TY
|
SpawnTemplate.units[UnitID].y = TY
|
||||||
@@ -2378,11 +2333,6 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if parkingindex[UnitID] then
|
if parkingindex[UnitID] then
|
||||||
UnitTemplate.parking = parkingindex[UnitID]
|
UnitTemplate.parking = parkingindex[UnitID]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug output.
|
|
||||||
--self:T2( string.format( "Group %s unit number %d: Parking = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking ) ) )
|
|
||||||
--self:T2( string.format( "Group %s unit number %d: Parking ID = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking_id ) ) )
|
|
||||||
--self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2402,14 +2352,15 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
-- When spawned in the air, we need to generate a Takeoff Event.
|
-- When spawned in the air, we need to generate a Takeoff Event.
|
||||||
if Takeoff == GROUP.Takeoff.Air then
|
if Takeoff == GROUP.Takeoff.Air then
|
||||||
for UnitID, UnitSpawned in pairs( GroupSpawned:GetUnits() ) do
|
for UnitID, UnitSpawned in pairs( GroupSpawned:GetUnits() ) do
|
||||||
SCHEDULER:New( nil, BASE.CreateEventTakeoff, { GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject() }, 5 )
|
--SCHEDULER:New( nil, BASE.CreateEventTakeoff, { GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject() }, 5 ) --No need to create a new SCHEDULER instance every time!
|
||||||
|
self:ScheduleOnce(5, BASE.CreateEventTakeoff, {GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject()})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if we accidentally spawned on the runway. Needs to be schedules, because group is not immidiately alive.
|
-- Check if we accidentally spawned on the runway. Needs to be schedules, because group is not immidiately alive.
|
||||||
if Takeoff ~= SPAWN.Takeoff.Runway and Takeoff ~= SPAWN.Takeoff.Air and spawnonairport then
|
--if Takeoff ~= SPAWN.Takeoff.Runway and Takeoff ~= SPAWN.Takeoff.Air and spawnonairport then
|
||||||
SCHEDULER:New( nil, AIRBASE.CheckOnRunWay, { SpawnAirbase, GroupSpawned, 75, true }, 1.0 )
|
-- SCHEDULER:New( nil, AIRBASE.CheckOnRunWay, { SpawnAirbase, GroupSpawned, 75, true }, 1.0 )
|
||||||
end
|
--end
|
||||||
|
|
||||||
return GroupSpawned
|
return GroupSpawned
|
||||||
end
|
end
|
||||||
@@ -2879,7 +2830,7 @@ end
|
|||||||
function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
||||||
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
|
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
local PointVec3 = COORDINATE:NewFromVec3( Vec3 )
|
||||||
--self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
if SpawnIndex then
|
if SpawnIndex then
|
||||||
@@ -2955,7 +2906,7 @@ end
|
|||||||
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 coordinates where to spawn the group.
|
-- @param Core.Point#COORDINATE PointVec3 The COORDINATE coordinates where to spawn the group.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
|
||||||
-- @usage
|
-- @usage
|
||||||
@@ -3003,12 +2954,12 @@ function SPAWN:SpawnFromVec2( Vec2, MinHeight, MaxHeight, SpawnIndex )
|
|||||||
return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air.
|
return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air.
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Will spawn a group from a POINT_VEC2 in 3D space.
|
--- Will spawn a group from a COORDINATE in 3D space.
|
||||||
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
|
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
|
||||||
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 coordinates where to spawn the group.
|
-- @param Core.Point#COORDINATE PointVec2 The coordinates where to spawn the group.
|
||||||
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
||||||
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
@@ -3814,8 +3765,9 @@ end
|
|||||||
--- Private method that randomizes the @{Core.Zone}s where the Group will be spawned.
|
--- Private method that randomizes the @{Core.Zone}s where the Group will be spawned.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #number SpawnIndex
|
-- @param #number SpawnIndex
|
||||||
|
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
function SPAWN:_RandomizeZones( SpawnIndex )
|
function SPAWN:_RandomizeZones( SpawnIndex, RandomizePositionInZone)
|
||||||
--self:F( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeZones } )
|
--self:F( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeZones } )
|
||||||
|
|
||||||
if self.SpawnRandomizeZones then
|
if self.SpawnRandomizeZones then
|
||||||
@@ -3829,7 +3781,11 @@ function SPAWN:_RandomizeZones( SpawnIndex )
|
|||||||
|
|
||||||
--self:T2( "Preparing Spawn in Zone", SpawnZone:GetName() )
|
--self:T2( "Preparing Spawn in Zone", SpawnZone:GetName() )
|
||||||
|
|
||||||
local SpawnVec2 = SpawnZone:GetRandomVec2()
|
local SpawnVec2 = SpawnZone:GetVec2()
|
||||||
|
|
||||||
|
if RandomizePositionInZone ~= false then
|
||||||
|
SpawnVec2 = SpawnZone:GetRandomVec2()
|
||||||
|
end
|
||||||
|
|
||||||
--self:T2( { SpawnVec2 = SpawnVec2 } )
|
--self:T2( { SpawnVec2 = SpawnVec2 } )
|
||||||
|
|
||||||
@@ -4056,7 +4012,7 @@ function SPAWN:_OnLand( EventData )
|
|||||||
-- self:ReSpawn( SpawnGroupIndex )
|
-- self:ReSpawn( SpawnGroupIndex )
|
||||||
-- Delay respawn by three seconds due to DCS 2.5.4.26368 OB bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
-- Delay respawn by three seconds due to DCS 2.5.4.26368 OB bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
||||||
-- Bug was initially only for engine shutdown event but after ED "fixed" it, it now happens on landing events.
|
-- Bug was initially only for engine shutdown event but after ED "fixed" it, it now happens on landing events.
|
||||||
SCHEDULER:New( nil, self.ReSpawn, { self, SpawnGroupIndex }, 3 )
|
SCHEDULER:New( nil, self.ReSpawn, { self, SpawnGroupIndex }, self.RepeatOnLandingTime or 3 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
--
|
--
|
||||||
-- * @{#SPAWNSTATIC.Spawn}(Heading, NewName) spawns the static with the set parameters. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.Spawn}(Heading, NewName) spawns the static with the set parameters. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
-- * @{#SPAWNSTATIC.SpawnFromCoordinate}(Coordinate, Heading, NewName) spawn the static at the given coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.SpawnFromCoordinate}(Coordinate, Heading, NewName) spawn the static at the given coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a POINT_VEC2 coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a COORDINATE coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
-- * @{#SPAWNSTATIC.SpawnFromZone}(Zone, Heading, NewName) spawns the static at the center of a @{Core.Zone}. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.SpawnFromZone}(Zone, Heading, NewName) spawns the static at the center of a @{Core.Zone}. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
--
|
--
|
||||||
-- @field #SPAWNSTATIC SPAWNSTATIC
|
-- @field #SPAWNSTATIC SPAWNSTATIC
|
||||||
@@ -411,9 +411,9 @@ function SPAWNSTATIC:Spawn(Heading, NewName)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Creates a new @{Wrapper.Static} from a POINT_VEC2.
|
--- Creates a new @{Wrapper.Static} from a COORDINATE.
|
||||||
-- @param #SPAWNSTATIC self
|
-- @param #SPAWNSTATIC self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 The 2D coordinate where to spawn the static.
|
-- @param Core.Point#COORDINATE PointVec2 The 2D coordinate where to spawn the static.
|
||||||
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||||
-- @param #string NewName (Optional) The name of the new static.
|
-- @param #string NewName (Optional) The name of the new static.
|
||||||
-- @return Wrapper.Static#STATIC The static spawned.
|
-- @return Wrapper.Static#STATIC The static spawned.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,8 @@
|
|||||||
-- @module Core.Zone_Detection
|
-- @module Core.Zone_Detection
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
--- @type ZONE_DETECTION
|
---
|
||||||
|
-- @type ZONE_DETECTION
|
||||||
-- @field DCS#Vec2 Vec2 The current location of the zone.
|
-- @field DCS#Vec2 Vec2 The current location of the zone.
|
||||||
-- @field DCS#Distance Radius The radius of the zone.
|
-- @field DCS#Distance Radius The radius of the zone.
|
||||||
-- @extends #ZONE_BASE
|
-- @extends #ZONE_BASE
|
||||||
@@ -106,7 +107,7 @@ function ZONE_DETECTION:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
|
|||||||
local Radial = ( Angle + AngleOffset ) * RadialBase / 360
|
local Radial = ( Angle + AngleOffset ) * RadialBase / 360
|
||||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||||
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Smoke( SmokeColor )
|
COORDINATE:New( Point.x, AddHeight, Point.y):Smoke( SmokeColor )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -137,7 +138,7 @@ function ZONE_DETECTION:FlareZone( FlareColor, Points, Azimuth, AddHeight )
|
|||||||
local Radial = Angle * RadialBase / 360
|
local Radial = Angle * RadialBase / 360
|
||||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||||
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Flare( FlareColor, Azimuth )
|
COORDINATE:New( Point.x, AddHeight, Point.y ):Flare( FlareColor, Azimuth )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -201,4 +202,3 @@ function ZONE_DETECTION:IsVec3InZone( Vec3 )
|
|||||||
|
|
||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ end -- env
|
|||||||
|
|
||||||
do -- radio
|
do -- radio
|
||||||
|
|
||||||
---@type radio
|
--@type radio
|
||||||
-- @field #radio.modulation modulation
|
-- @field #radio.modulation modulation
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -630,9 +630,13 @@ do -- Object
|
|||||||
--- @function [parent=#Object] destroy
|
--- @function [parent=#Object] destroy
|
||||||
-- @param #Object self
|
-- @param #Object self
|
||||||
|
|
||||||
--- @function [parent=#Object] getCategory
|
--- Returns an enumerator of the category for the specific object.
|
||||||
|
-- The enumerator returned is dependent on the category of the object and how the function is called.
|
||||||
|
-- As of DCS 2.9.2 when this function is called on an Object, Unit, Weapon, or Airbase a 2nd value will be returned which details the object sub-category value.
|
||||||
|
-- @function [parent=#Object] getCategory
|
||||||
-- @param #Object self
|
-- @param #Object self
|
||||||
-- @return #Object.Category
|
-- @return #Object.Category The object category (1=UNIT, 2=WEAPON, 3=STATIC, 4=BASE, 5=SCENERY, 6=Cargo)
|
||||||
|
-- @return #number The subcategory of the passed object, e.g. Unit.Category if a unit object was passed.
|
||||||
|
|
||||||
--- Returns type name of the Object.
|
--- Returns type name of the Object.
|
||||||
-- @function [parent=#Object] getTypeName
|
-- @function [parent=#Object] getTypeName
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
-- ### Author: FlightControl - Framework Design & Programming
|
-- ### Author: FlightControl - Framework Design & Programming
|
||||||
-- ### Refactoring to use the Runway auto-detection: Applevangelist
|
-- ### Refactoring to use the Runway auto-detection: Applevangelist
|
||||||
-- @date August 2022
|
-- @date August 2022
|
||||||
-- Last Update Oct 2024
|
-- Last Update Feb 2025
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -416,7 +416,7 @@ end
|
|||||||
-- @field #ATC_GROUND_UNIVERSAL
|
-- @field #ATC_GROUND_UNIVERSAL
|
||||||
ATC_GROUND_UNIVERSAL = {
|
ATC_GROUND_UNIVERSAL = {
|
||||||
ClassName = "ATC_GROUND_UNIVERSAL",
|
ClassName = "ATC_GROUND_UNIVERSAL",
|
||||||
Version = "0.0.1",
|
Version = "0.0.2",
|
||||||
SetClient = nil,
|
SetClient = nil,
|
||||||
Airbases = nil,
|
Airbases = nil,
|
||||||
AirbaseList = nil,
|
AirbaseList = nil,
|
||||||
@@ -441,17 +441,25 @@ function ATC_GROUND_UNIVERSAL:New(AirbaseList)
|
|||||||
self:T( { self.ClassName } )
|
self:T( { self.ClassName } )
|
||||||
|
|
||||||
self.Airbases = {}
|
self.Airbases = {}
|
||||||
|
|
||||||
for _name,_ in pairs(_DATABASE.AIRBASES) do
|
|
||||||
self.Airbases[_name]={}
|
|
||||||
end
|
|
||||||
|
|
||||||
self.AirbaseList = AirbaseList
|
self.AirbaseList = AirbaseList
|
||||||
|
|
||||||
if not self.AirbaseList then
|
if not self.AirbaseList then
|
||||||
self.AirbaseList = {}
|
self.AirbaseList = {}
|
||||||
for _name,_ in pairs(_DATABASE.AIRBASES) do
|
for _name,_base in pairs(_DATABASE.AIRBASES) do
|
||||||
self.AirbaseList[_name]=_name
|
-- DONE exclude FARPS and Ships
|
||||||
|
if _base and _base.isAirdrome == true then
|
||||||
|
self.AirbaseList[_name]=_name
|
||||||
|
self.Airbases[_name]={}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _,_name in pairs(AirbaseList) do
|
||||||
|
-- DONE exclude FARPS and Ships
|
||||||
|
local airbase = _DATABASE:FindAirbase(_name)
|
||||||
|
if airbase and (airbase.isAirdrome == true) then
|
||||||
|
self.Airbases[_name]={}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1447,11 +1455,10 @@ function ATC_GROUND_PERSIANGULF:Start( RepeatScanSeconds )
|
|||||||
self.AirbaseMonitor = SCHEDULER:New( self, self._AirbaseMonitor, { self }, 0, RepeatScanSeconds )
|
self.AirbaseMonitor = SCHEDULER:New( self, self._AirbaseMonitor, { self }, 0, RepeatScanSeconds )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
-- @type ATC_GROUND_MARIANAISLANDS
|
-- @type ATC_GROUND_MARIANAISLANDS
|
||||||
-- @extends #ATC_GROUND
|
-- @extends #ATC_GROUND
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- # ATC\_GROUND\_MARIANA, extends @{#ATC_GROUND}
|
--- # ATC\_GROUND\_MARIANA, extends @{#ATC_GROUND}
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -619,63 +619,148 @@ ARTY.WeaponType={
|
|||||||
}
|
}
|
||||||
|
|
||||||
--- Database of common artillery unit properties.
|
--- Database of common artillery unit properties.
|
||||||
|
-- @type ARTY.dbitem
|
||||||
|
-- @field #string displayname Name displayed in ME.
|
||||||
|
-- @field #number minrange Minimum firing range in meters.
|
||||||
|
-- @field #number maxrange Maximum firing range in meters.
|
||||||
|
-- @field #number reloadtime Reload time in seconds.
|
||||||
|
|
||||||
|
--- Database of common artillery unit properties.
|
||||||
|
-- Table key is the "type name" and table value is and `ARTY.dbitem`.
|
||||||
-- @type ARTY.db
|
-- @type ARTY.db
|
||||||
ARTY.db={
|
ARTY.db={
|
||||||
["2B11 mortar"] = { -- type "2B11 mortar"
|
["LeFH_18-40-105"] = {
|
||||||
minrange = 500, -- correct?
|
displayname = "FH LeFH-18 105mm", -- name displayed in the ME
|
||||||
maxrange = 7000, -- 7 km
|
minrange = 500, -- min range (green circle) in meters
|
||||||
reloadtime = 30, -- 30 sec
|
maxrange = 10500, -- max range (red circle) in meters
|
||||||
|
reloadtime = nil, -- reload time in seconds
|
||||||
},
|
},
|
||||||
["SPH 2S1 Gvozdika"] = { -- type "SAU Gvozdika"
|
["M2A1-105"] = {
|
||||||
minrange = 300, -- correct?
|
displayname = "FH M2A1 105mm",
|
||||||
maxrange = 15000, -- 15 km
|
minrange = 500,
|
||||||
reloadtime = nil, -- unknown
|
maxrange = 11500,
|
||||||
|
reloadtime = nil,
|
||||||
},
|
},
|
||||||
["SPH 2S19 Msta"] = { --type "SAU Msta", alias "2S19 Msta"
|
["Pak40"] = {
|
||||||
minrange = 300, -- correct?
|
displayname = "FH Pak 40 75mm",
|
||||||
maxrange = 23500, -- 23.5 km
|
minrange = 500,
|
||||||
reloadtime = nil, -- unknown
|
maxrange = 3000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["L118_Unit"] = {
|
||||||
|
displayname = "L118 Light Artillery Gun",
|
||||||
|
minrange = 500,
|
||||||
|
maxrange = 17500,
|
||||||
|
reloadtime = nil,
|
||||||
},
|
},
|
||||||
["SPH 2S3 Akatsia"] = { -- type "SAU Akatsia", alias "2S3 Akatsia"
|
["Smerch"] = {
|
||||||
minrange = 300, -- correct?
|
displayname = "MLRS 9A52 Smerch CM 300mm",
|
||||||
maxrange = 17000, -- 17 km
|
minrange = 20000,
|
||||||
reloadtime = nil, -- unknown
|
maxrange = 70000,
|
||||||
|
reloadtime = 2160,
|
||||||
},
|
},
|
||||||
["SPH 2S9 Nona"] = { --type "SAU 2-C9"
|
["Smerch_HE"] = {
|
||||||
minrange = 500, -- correct?
|
displayname = "MLRS 9A52 Smerch HE 300mm",
|
||||||
maxrange = 7000, -- 7 km
|
minrange = 20000,
|
||||||
reloadtime = nil, -- unknown
|
maxrange = 70000,
|
||||||
|
reloadtime = 2160,
|
||||||
},
|
},
|
||||||
["SPH M109 Paladin"] = { -- type "M-109", alias "M109"
|
["Uragan_BM-27"] = {
|
||||||
minrange = 300, -- correct?
|
displayname = "MLRS 9K57 Uragan BM-27 220mm",
|
||||||
maxrange = 22000, -- 22 km
|
minrange = 11500,
|
||||||
reloadtime = nil, -- unknown
|
maxrange = 35800,
|
||||||
|
reloadtime = 840,
|
||||||
},
|
},
|
||||||
["SpGH Dana"] = { -- type "SpGH_Dana"
|
["Grad-URAL"] = {
|
||||||
minrange = 300, -- correct?
|
displayname = "MLRS BM-21 Grad 122mm",
|
||||||
maxrange = 18700, -- 18.7 km
|
minrange = 5000,
|
||||||
reloadtime = nil, -- unknown
|
maxrange = 19000,
|
||||||
|
reloadtime = 420,
|
||||||
},
|
},
|
||||||
["MLRS BM-21 Grad"] = { --type "Grad-URAL", alias "MLRS BM-21 Grad"
|
["HL_B8M1"] = {
|
||||||
minrange = 5000, -- 5 km
|
displayname = "MLRS HL with B8M1 80mm",
|
||||||
maxrange = 19000, -- 19 km
|
minrange = 500,
|
||||||
reloadtime = 420, -- 7 min
|
maxrange = 5000,
|
||||||
|
reloadtime = nil,
|
||||||
},
|
},
|
||||||
["MLRS 9K57 Uragan BM-27"] = { -- type "Uragan_BM-27"
|
["tt_B8M1"] = {
|
||||||
minrange = 11500, -- 11.5 km
|
displayname = "MLRS LC with B8M1 80mm",
|
||||||
maxrange = 35800, -- 35.8 km
|
minrange = 500,
|
||||||
reloadtime = 840, -- 14 min
|
maxrange = 5000,
|
||||||
|
reloadtime = nil,
|
||||||
},
|
},
|
||||||
["MLRS 9A52 Smerch"] = { -- type "Smerch"
|
["MLRS"] = {
|
||||||
minrange = 20000, -- 20 km
|
displayname = "MLRS M270 227mm",
|
||||||
maxrange = 70000, -- 70 km
|
minrange = 10000,
|
||||||
reloadtime = 2160, -- 36 min
|
maxrange = 32000,
|
||||||
|
reloadtime = 540,
|
||||||
},
|
},
|
||||||
["MLRS M270"] = { --type "MRLS", alias "M270 MRLS"
|
["2B11 mortar"] = {
|
||||||
minrange = 10000, -- 10 km
|
displayname = "Mortar 2B11 120mm",
|
||||||
maxrange = 32000, -- 32 km
|
minrange = 500,
|
||||||
reloadtime = 540, -- 9 min
|
maxrange = 7000,
|
||||||
|
reloadtime = 30,
|
||||||
},
|
},
|
||||||
|
["PLZ05"] = {
|
||||||
|
displayname = "PLZ-05",
|
||||||
|
minrange = 500,
|
||||||
|
maxrange = 23500,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["SAU Gvozdika"] = {
|
||||||
|
displayname = "SPH 2S1 Gvozdika 122mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 15000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["SAU Msta"] = {
|
||||||
|
displayname = "SPH 2S19 Msta 152mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 23500,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["SAU Akatsia"] = {
|
||||||
|
displayname = "SPH 2S3 Akatsia 152mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 17000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["SpGH_Dana"] = {
|
||||||
|
displayname = "SPH Dana vz77 152mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 18700,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["M-109"] = {
|
||||||
|
displayname = "SPH M109 Paladin 155mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 22000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["M12_GMC"] = {
|
||||||
|
displayname = "SPH M12 GMC 155mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 18200,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["Wespe124"] = {
|
||||||
|
displayname = "SPH Sd.Kfz.124 Wespe 105mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 7000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["T155_Firtina"] = {
|
||||||
|
displayname = "SPH T155 Firtina 155mm",
|
||||||
|
minrange = 300,
|
||||||
|
maxrange = 41000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
|
["SAU 2-C9"] = {
|
||||||
|
displayname = "SPM 2S9 Nona 120mm M",
|
||||||
|
minrange = 500,
|
||||||
|
maxrange = 7000,
|
||||||
|
reloadtime = nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Target.
|
--- Target.
|
||||||
@@ -695,7 +780,7 @@ ARTY.db={
|
|||||||
|
|
||||||
--- Arty script version.
|
--- Arty script version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
ARTY.version="1.3.1"
|
ARTY.version="1.3.3"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -797,8 +882,8 @@ function ARTY:New(group, alias)
|
|||||||
-- Maximum speed in km/h.
|
-- Maximum speed in km/h.
|
||||||
self.SpeedMax=group:GetSpeedMax()
|
self.SpeedMax=group:GetSpeedMax()
|
||||||
|
|
||||||
-- Group is mobile or not (e.g. mortars).
|
-- Group is mobile or not (e.g. mortars). Some immobile units have a speed of 1 m/s = 3.6 km/h. So we check this number.
|
||||||
if self.SpeedMax>1 then
|
if self.SpeedMax>3.6 then
|
||||||
self.ismobile=true
|
self.ismobile=true
|
||||||
else
|
else
|
||||||
self.ismobile=false
|
self.ismobile=false
|
||||||
@@ -1923,7 +2008,7 @@ function ARTY:onafterStart(Controllable, From, Event, To)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Check if we have and arty type that is in the DB.
|
-- Check if we have and arty type that is in the DB.
|
||||||
local _dbproperties=self:_CheckDB(self.DisplayName)
|
local _dbproperties=self:_CheckDB(self.Type)
|
||||||
self:T({dbproperties=_dbproperties})
|
self:T({dbproperties=_dbproperties})
|
||||||
if _dbproperties~=nil then
|
if _dbproperties~=nil then
|
||||||
for property,value in pairs(_dbproperties) do
|
for property,value in pairs(_dbproperties) do
|
||||||
@@ -1969,8 +2054,8 @@ function ARTY:onafterStart(Controllable, From, Event, To)
|
|||||||
text=text..string.format("Type = %s\n", self.Type)
|
text=text..string.format("Type = %s\n", self.Type)
|
||||||
text=text..string.format("Display Name = %s\n", self.DisplayName)
|
text=text..string.format("Display Name = %s\n", self.DisplayName)
|
||||||
text=text..string.format("Number of units = %d\n", self.IniGroupStrength)
|
text=text..string.format("Number of units = %d\n", self.IniGroupStrength)
|
||||||
text=text..string.format("Speed max = %d km/h\n", self.SpeedMax)
|
text=text..string.format("Speed max = %.1f km/h\n", self.SpeedMax)
|
||||||
text=text..string.format("Speed default = %d km/h\n", self.Speed)
|
text=text..string.format("Speed default = %.1f km/h\n", self.Speed)
|
||||||
text=text..string.format("Is mobile = %s\n", tostring(self.ismobile))
|
text=text..string.format("Is mobile = %s\n", tostring(self.ismobile))
|
||||||
text=text..string.format("Is cargo = %s\n", tostring(self.iscargo))
|
text=text..string.format("Is cargo = %s\n", tostring(self.iscargo))
|
||||||
text=text..string.format("Min range = %.1f km\n", self.minrange/1000)
|
text=text..string.format("Min range = %.1f km\n", self.minrange/1000)
|
||||||
@@ -3049,7 +3134,7 @@ function ARTY:onafterOpenFire(Controllable, From, Event, To, target)
|
|||||||
local nfire=Narty
|
local nfire=Narty
|
||||||
local _type="shots"
|
local _type="shots"
|
||||||
if target.weapontype==ARTY.WeaponType.Auto then
|
if target.weapontype==ARTY.WeaponType.Auto then
|
||||||
nfire=Narty
|
nfire=Nammo -- We take everything that is available
|
||||||
_type="shots"
|
_type="shots"
|
||||||
elseif target.weapontype==ARTY.WeaponType.Cannon then
|
elseif target.weapontype==ARTY.WeaponType.Cannon then
|
||||||
nfire=Narty
|
nfire=Narty
|
||||||
@@ -3070,6 +3155,8 @@ function ARTY:onafterOpenFire(Controllable, From, Event, To, target)
|
|||||||
nfire=Nmissiles
|
nfire=Nmissiles
|
||||||
_type="cruise missiles"
|
_type="cruise missiles"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--env.info(string.format("FF type=%s, Nrockets=%d, Nfire=%d target.nshells=%d", _type, Nrockets, nfire, target.nshells))
|
||||||
|
|
||||||
-- Adjust if less than requested ammo is left.
|
-- Adjust if less than requested ammo is left.
|
||||||
target.nshells=math.min(target.nshells, nfire)
|
target.nshells=math.min(target.nshells, nfire)
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ function CLEANUP_AIRBASE.__:EventAddForCleanUp( Event )
|
|||||||
self:F({Event})
|
self:F({Event})
|
||||||
|
|
||||||
|
|
||||||
if Event.IniDCSUnit and Event.IniCategory == Object.Category.UNIT then
|
if Event.IniDCSUnit and Event.IniUnit and Event.IniCategory == Object.Category.UNIT then
|
||||||
if self.CleanUpList[Event.IniDCSUnitName] == nil then
|
if self.CleanUpList[Event.IniDCSUnitName] == nil then
|
||||||
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
|
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
|
||||||
self:AddForCleanUp( Event.IniUnit, Event.IniDCSUnitName )
|
self:AddForCleanUp( Event.IniUnit, Event.IniDCSUnitName )
|
||||||
@@ -362,7 +362,7 @@ function CLEANUP_AIRBASE.__:EventAddForCleanUp( Event )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if Event.TgtDCSUnit and Event.TgtCategory == Object.Category.UNIT then
|
if Event.TgtDCSUnit and Event.TgtUnit and Event.TgtCategory == Object.Category.UNIT then
|
||||||
if self.CleanUpList[Event.TgtDCSUnitName] == nil then
|
if self.CleanUpList[Event.TgtDCSUnitName] == nil then
|
||||||
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
|
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
|
||||||
self:AddForCleanUp( Event.TgtUnit, Event.TgtDCSUnitName )
|
self:AddForCleanUp( Event.TgtUnit, Event.TgtDCSUnitName )
|
||||||
@@ -384,7 +384,7 @@ function CLEANUP_AIRBASE.__:CleanUpSchedule()
|
|||||||
local CleanUpUnit = CleanUpListData.CleanUpUnit -- Wrapper.Unit#UNIT
|
local CleanUpUnit = CleanUpListData.CleanUpUnit -- Wrapper.Unit#UNIT
|
||||||
local CleanUpGroupName = CleanUpListData.CleanUpGroupName
|
local CleanUpGroupName = CleanUpListData.CleanUpGroupName
|
||||||
|
|
||||||
if CleanUpUnit:IsAlive() ~= nil then
|
if CleanUpUnit and CleanUpUnit:IsAlive() ~= nil then
|
||||||
|
|
||||||
if self:IsInAirbase( CleanUpUnit:GetVec2() ) then
|
if self:IsInAirbase( CleanUpUnit:GetVec2() ) then
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ function CLEANUP_AIRBASE.__:CleanUpSchedule()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Clean Units which are waiting for a very long time in the CleanUpZone.
|
-- Clean Units which are waiting for a very long time in the CleanUpZone.
|
||||||
if CleanUpUnit and not CleanUpUnit:GetPlayerName() then
|
if CleanUpUnit and (CleanUpUnit.GetPlayerName == nil or not CleanUpUnit:GetPlayerName()) then
|
||||||
local CleanUpUnitVelocity = CleanUpUnit:GetVelocityKMH()
|
local CleanUpUnitVelocity = CleanUpUnit:GetVelocityKMH()
|
||||||
if CleanUpUnitVelocity < 1 then
|
if CleanUpUnitVelocity < 1 then
|
||||||
if CleanUpListData.CleanUpMoved then
|
if CleanUpListData.CleanUpMoved then
|
||||||
|
|||||||
@@ -1154,8 +1154,6 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
|
|
||||||
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
|
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
|
||||||
|
|
||||||
if true then
|
|
||||||
|
|
||||||
local EscortGroupName = self.EscortGroup:GetName()
|
local EscortGroupName = self.EscortGroup:GetName()
|
||||||
|
|
||||||
self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
|
self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
|
||||||
@@ -1226,177 +1224,6 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
else
|
|
||||||
-- local EscortGroupName = self.EscortGroup:GetName()
|
|
||||||
-- local EscortTargets = self.EscortGroup:GetDetectedTargets()
|
|
||||||
--
|
|
||||||
-- local ClientEscortTargets = self.EscortClient._EscortGroups[EscortGroupName].Targets
|
|
||||||
--
|
|
||||||
-- local EscortTargetMessages = ""
|
|
||||||
-- for EscortTargetID, EscortTarget in pairs( EscortTargets ) do
|
|
||||||
-- local EscortObject = EscortTarget.object
|
|
||||||
-- self:T( EscortObject )
|
|
||||||
-- if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then
|
|
||||||
--
|
|
||||||
-- local EscortTargetUnit = UNIT:Find( EscortObject )
|
|
||||||
-- local EscortTargetUnitName = EscortTargetUnit:GetName()
|
|
||||||
--
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- -- local EscortTargetIsDetected,
|
|
||||||
-- -- EscortTargetIsVisible,
|
|
||||||
-- -- EscortTargetLastTime,
|
|
||||||
-- -- EscortTargetKnowType,
|
|
||||||
-- -- EscortTargetKnowDistance,
|
|
||||||
-- -- EscortTargetLastPos,
|
|
||||||
-- -- EscortTargetLastVelocity
|
|
||||||
-- -- = self.EscortGroup:IsTargetDetected( EscortObject )
|
|
||||||
-- --
|
|
||||||
-- -- self:T( { EscortTargetIsDetected,
|
|
||||||
-- -- EscortTargetIsVisible,
|
|
||||||
-- -- EscortTargetLastTime,
|
|
||||||
-- -- EscortTargetKnowType,
|
|
||||||
-- -- EscortTargetKnowDistance,
|
|
||||||
-- -- EscortTargetLastPos,
|
|
||||||
-- -- EscortTargetLastVelocity } )
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- local EscortTargetUnitVec3 = EscortTargetUnit:GetVec3()
|
|
||||||
-- local EscortVec3 = self.EscortGroup:GetVec3()
|
|
||||||
-- local Distance = ( ( EscortTargetUnitVec3.x - EscortVec3.x )^2 +
|
|
||||||
-- ( EscortTargetUnitVec3.y - EscortVec3.y )^2 +
|
|
||||||
-- ( EscortTargetUnitVec3.z - EscortVec3.z )^2
|
|
||||||
-- ) ^ 0.5 / 1000
|
|
||||||
--
|
|
||||||
-- self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } )
|
|
||||||
--
|
|
||||||
-- if Distance <= 15 then
|
|
||||||
--
|
|
||||||
-- if not ClientEscortTargets[EscortTargetUnitName] then
|
|
||||||
-- ClientEscortTargets[EscortTargetUnitName] = {}
|
|
||||||
-- end
|
|
||||||
-- ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit
|
|
||||||
-- ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible
|
|
||||||
-- ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type
|
|
||||||
-- ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance
|
|
||||||
-- else
|
|
||||||
-- if ClientEscortTargets[EscortTargetUnitName] then
|
|
||||||
-- ClientEscortTargets[EscortTargetUnitName] = nil
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- self:T( { "Sorting Targets Table:", ClientEscortTargets } )
|
|
||||||
-- table.sort( ClientEscortTargets, function( a, b ) return a.Distance < b.Distance end )
|
|
||||||
-- self:T( { "Sorted Targets Table:", ClientEscortTargets } )
|
|
||||||
--
|
|
||||||
-- -- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
|
|
||||||
-- self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
|
|
||||||
--
|
|
||||||
-- if self.EscortMenuTargetAssistance then
|
|
||||||
-- self.EscortMenuTargetAssistance:RemoveSubMenus()
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- --for MenuIndex = 1, #self.EscortMenuAttackTargets do
|
|
||||||
-- -- self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } )
|
|
||||||
-- -- self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove()
|
|
||||||
-- --end
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- if ClientEscortTargets then
|
|
||||||
-- for ClientEscortTargetUnitName, ClientEscortTargetData in pairs( ClientEscortTargets ) do
|
|
||||||
--
|
|
||||||
-- for ClientEscortGroupName, EscortGroupData in pairs( self.EscortClient._EscortGroups ) do
|
|
||||||
--
|
|
||||||
-- if ClientEscortTargetData and ClientEscortTargetData.AttackUnit:IsAlive() then
|
|
||||||
--
|
|
||||||
-- local EscortTargetMessage = ""
|
|
||||||
-- local EscortTargetCategoryName = ClientEscortTargetData.AttackUnit:GetCategoryName()
|
|
||||||
-- local EscortTargetCategoryType = ClientEscortTargetData.AttackUnit:GetTypeName()
|
|
||||||
-- if ClientEscortTargetData.type then
|
|
||||||
-- EscortTargetMessage = EscortTargetMessage .. EscortTargetCategoryName .. " (" .. EscortTargetCategoryType .. ") at "
|
|
||||||
-- else
|
|
||||||
-- EscortTargetMessage = EscortTargetMessage .. "Unknown target at "
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- local EscortTargetUnitVec3 = ClientEscortTargetData.AttackUnit:GetVec3()
|
|
||||||
-- local EscortVec3 = self.EscortGroup:GetVec3()
|
|
||||||
-- local Distance = ( ( EscortTargetUnitVec3.x - EscortVec3.x )^2 +
|
|
||||||
-- ( EscortTargetUnitVec3.y - EscortVec3.y )^2 +
|
|
||||||
-- ( EscortTargetUnitVec3.z - EscortVec3.z )^2
|
|
||||||
-- ) ^ 0.5 / 1000
|
|
||||||
--
|
|
||||||
-- self:T( { self.EscortGroup:GetName(), ClientEscortTargetData.AttackUnit:GetName(), Distance, ClientEscortTargetData.AttackUnit } )
|
|
||||||
-- if ClientEscortTargetData.visible == false then
|
|
||||||
-- EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " estimated km"
|
|
||||||
-- else
|
|
||||||
-- EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km"
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- if ClientEscortTargetData.visible then
|
|
||||||
-- EscortTargetMessage = EscortTargetMessage .. ", visual"
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- if ClientEscortGroupName == EscortGroupName then
|
|
||||||
--
|
|
||||||
-- MENU_GROUP_COMMAND:New( self.EscortClient,
|
|
||||||
-- EscortTargetMessage,
|
|
||||||
-- self.EscortMenuAttackNearbyTargets,
|
|
||||||
-- ESCORT._AttackTarget,
|
|
||||||
-- { ParamSelf = self,
|
|
||||||
-- ParamUnit = ClientEscortTargetData.AttackUnit
|
|
||||||
-- }
|
|
||||||
-- )
|
|
||||||
-- EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
|
|
||||||
-- else
|
|
||||||
-- if self.EscortMenuTargetAssistance then
|
|
||||||
-- local MenuTargetAssistance = MENU_GROUP:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
|
|
||||||
-- MENU_GROUP_COMMAND:New( self.EscortClient,
|
|
||||||
-- EscortTargetMessage,
|
|
||||||
-- MenuTargetAssistance,
|
|
||||||
-- ESCORT._AssistTarget,
|
|
||||||
-- self,
|
|
||||||
-- EscortGroupData.EscortGroup,
|
|
||||||
-- ClientEscortTargetData.AttackUnit
|
|
||||||
-- )
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- else
|
|
||||||
-- ClientEscortTargetData = nil
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- if EscortTargetMessages ~= "" and self.ReportTargets == true then
|
|
||||||
-- self.EscortGroup:MessageToClient( "Detected targets within 15 km range:" .. EscortTargetMessages:gsub("\n$",""), 20, self.EscortClient )
|
|
||||||
-- else
|
|
||||||
-- self.EscortGroup:MessageToClient( "No targets detected!", 20, self.EscortClient )
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- if self.EscortMenuResumeMission then
|
|
||||||
-- self.EscortMenuResumeMission:RemoveSubMenus()
|
|
||||||
--
|
|
||||||
-- -- if self.EscortMenuResumeWayPoints then
|
|
||||||
-- -- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do
|
|
||||||
-- -- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } )
|
|
||||||
-- -- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove()
|
|
||||||
-- -- end
|
|
||||||
-- -- end
|
|
||||||
--
|
|
||||||
-- local TaskPoints = self:RegisterRoute()
|
|
||||||
-- for WayPointID, WayPoint in pairs( TaskPoints ) do
|
|
||||||
-- local EscortVec3 = self.EscortGroup:GetVec3()
|
|
||||||
-- local Distance = ( ( WayPoint.x - EscortVec3.x )^2 +
|
|
||||||
-- ( WayPoint.y - EscortVec3.z )^2
|
|
||||||
-- ) ^ 0.5 / 1000
|
|
||||||
-- MENU_GROUP_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ FOX = {
|
|||||||
explosiondist = 200,
|
explosiondist = 200,
|
||||||
explosiondist2 = 500,
|
explosiondist2 = 500,
|
||||||
bigmissilemass = 50,
|
bigmissilemass = 50,
|
||||||
destroy = nil,
|
|
||||||
dt50 = 5,
|
dt50 = 5,
|
||||||
dt10 = 1,
|
dt10 = 1,
|
||||||
dt05 = 0.5,
|
dt05 = 0.5,
|
||||||
@@ -1060,7 +1059,7 @@ function FOX:onafterMissileLaunch(From, Event, To, missile)
|
|||||||
|
|
||||||
-- Tracking info and init of last bomb position.
|
-- Tracking info and init of last bomb position.
|
||||||
local text=string.format("FOX: Tracking missile %s(%s) - target %s - shooter %s", missile.missileType, missile.missileName, tostring(missile.targetName), missile.shooterName)
|
local text=string.format("FOX: Tracking missile %s(%s) - target %s - shooter %s", missile.missileType, missile.missileName, tostring(missile.targetName), missile.shooterName)
|
||||||
self:I(FOX.lid..text)
|
self:T(FOX.lid..text)
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
|
|
||||||
-- Loop over players.
|
-- Loop over players.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
--
|
--
|
||||||
-- Last Update: Sep 2024
|
-- Last Update: May 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
@@ -60,6 +60,11 @@
|
|||||||
-- @field #number ShoradActDistance Distance of an attacker in meters from a Mantis SAM site, on which Shorad will be switched on. Useful to not give away Shorad sites too early. Default 15km. Should be smaller than checkradius.
|
-- @field #number ShoradActDistance Distance of an attacker in meters from a Mantis SAM site, on which Shorad will be switched on. Useful to not give away Shorad sites too early. Default 15km. Should be smaller than checkradius.
|
||||||
-- @field #boolean checkforfriendlies If true, do not activate a SAM installation if a friendly aircraft is in firing range.
|
-- @field #boolean checkforfriendlies If true, do not activate a SAM installation if a friendly aircraft is in firing range.
|
||||||
-- @field #table FilterZones Table of Core.Zone#ZONE Zones Consider SAM groups in this zone(s) only for this MANTIS instance, must be handed as #table of Zone objects.
|
-- @field #table FilterZones Table of Core.Zone#ZONE Zones Consider SAM groups in this zone(s) only for this MANTIS instance, must be handed as #table of Zone objects.
|
||||||
|
-- @field #boolean SmokeDecoy If true, smoke short range SAM units as decoy if a plane is in firing range.
|
||||||
|
-- @field #number SmokeDecoyColor Color to use, defaults to SMOKECOLOR.White
|
||||||
|
-- @field #number checkcounter Counter for SAM Table refreshes.
|
||||||
|
-- @field #number DLinkCacheTime Seconds after which cached contacts in DLink will decay.
|
||||||
|
-- @field #boolean logsamstatus Log SAM status in dcs.log every cycle if true
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
@@ -71,10 +76,9 @@
|
|||||||
--
|
--
|
||||||
-- * Moose derived Modular, Automatic and Network capable Targeting and Interception System.
|
-- * Moose derived Modular, Automatic and Network capable Targeting and Interception System.
|
||||||
-- * Controls a network of SAM sites. Uses detection to switch on the SAM site closest to the enemy.
|
-- * Controls a network of SAM sites. Uses detection to switch on the SAM site closest to the enemy.
|
||||||
-- * **Automatic mode** (default since 0.8) can set-up your SAM site network automatically for you
|
-- * **Automatic mode** (default) will set-up your SAM site network automatically for you.
|
||||||
-- * **Classic mode** behaves like before
|
-- * Leverage evasiveness from SEAD, leverage attack range setting.
|
||||||
-- * Leverage evasiveness from SEAD, leverage attack range setting
|
-- * Automatic setup of SHORAD based on groups of the class "short-range".
|
||||||
-- * Automatic setup of SHORAD based on groups of the class "short-range"
|
|
||||||
--
|
--
|
||||||
-- # 0. Base considerations and naming conventions
|
-- # 0. Base considerations and naming conventions
|
||||||
--
|
--
|
||||||
@@ -86,6 +90,7 @@
|
|||||||
-- * SAM sites, e.g. each **group name** begins with "Red SAM"
|
-- * SAM sites, e.g. each **group name** begins with "Red SAM"
|
||||||
-- * EWR network and AWACS, e.g. each **group name** begins with "Red EWR" and *not* e.g. "Red SAM EWR" (overlap with "Red SAM"), "Red EWR Awacs" will be found by "Red EWR"
|
-- * EWR network and AWACS, e.g. each **group name** begins with "Red EWR" and *not* e.g. "Red SAM EWR" (overlap with "Red SAM"), "Red EWR Awacs" will be found by "Red EWR"
|
||||||
-- * SHORAD, e.g. each **group name** begins with "Red SHORAD" and *not" e.g. just "SHORAD" because you might also have "Blue SHORAD"
|
-- * SHORAD, e.g. each **group name** begins with "Red SHORAD" and *not" e.g. just "SHORAD" because you might also have "Blue SHORAD"
|
||||||
|
-- * Point Defense, e.g. each **group name** begins with "Red AAA" and *not" e.g. just "AAA" because you might also have "Blue AAA"
|
||||||
--
|
--
|
||||||
-- It's important to get this right because of the nature of the filter-system in @{Core.Set#SET_GROUP}. Filters are "greedy", that is they
|
-- It's important to get this right because of the nature of the filter-system in @{Core.Set#SET_GROUP}. Filters are "greedy", that is they
|
||||||
-- will match *any* string that contains the search string - hence we need to avoid that SAMs, EWR and SHORAD step on each other\'s toes.
|
-- will match *any* string that contains the search string - hence we need to avoid that SAMs, EWR and SHORAD step on each other\'s toes.
|
||||||
@@ -129,10 +134,10 @@
|
|||||||
--
|
--
|
||||||
-- # 0.1 Set-up in the mission editor
|
-- # 0.1 Set-up in the mission editor
|
||||||
--
|
--
|
||||||
-- Set up your SAM sites in the mission editor. Name the groups using a systematic approach like above.
|
-- Set up your SAM sites in the mission editor. Name the groups using a systematic approach like above.Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
|
||||||
-- Set up your EWR system in the mission editor. Name the groups using a systematic approach like above. Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
|
|
||||||
-- Search Radars usually have "SR" or "STR" in their names. Use the encyclopedia in the mission editor to inform yourself.
|
-- Search Radars usually have "SR" or "STR" in their names. Use the encyclopedia in the mission editor to inform yourself.
|
||||||
-- Set up your SHORAD systems. They need to be **close** to (i.e. around) the SAM sites to be effective. Use **one** group per SAM location. SA-15 TOR systems offer a good missile defense.
|
-- Set up your SHORAD systems. They need to be **close** to (i.e. around) the SAM sites to be effective. Use **one unit ** per group (multiple groups) for the SAM location.
|
||||||
|
-- Else, evasive manoevers might club up all defenders in one place. Red SA-15 TOR systems offer a good missile defense.
|
||||||
--
|
--
|
||||||
-- [optional] Set up your HQ. Can be any group, e.g. a command vehicle.
|
-- [optional] Set up your HQ. Can be any group, e.g. a command vehicle.
|
||||||
--
|
--
|
||||||
@@ -144,6 +149,7 @@
|
|||||||
-- **Location** is of highest importance here. Whilst AWACS in DCS has almost the "all seeing eye", EWR don't have that. Choose your location wisely, against a mountain backdrop or inside a valley even the best EWR system
|
-- **Location** is of highest importance here. Whilst AWACS in DCS has almost the "all seeing eye", EWR don't have that. Choose your location wisely, against a mountain backdrop or inside a valley even the best EWR system
|
||||||
-- doesn't work well. Prefer higher-up locations with a good view; use F7 in-game to check where you actually placed your EWR and have a look around. Apart from the obvious choice, do also consider other radar units
|
-- doesn't work well. Prefer higher-up locations with a good view; use F7 in-game to check where you actually placed your EWR and have a look around. Apart from the obvious choice, do also consider other radar units
|
||||||
-- for this role, most have "SR" (search radar) or "STR" (search and track radar) in their names, use the encyclopedia to see what they actually do.
|
-- for this role, most have "SR" (search radar) or "STR" (search and track radar) in their names, use the encyclopedia to see what they actually do.
|
||||||
|
-- **HINT** Set at least one EWR on invisible and immortal so MANTIS doesn't stop working.
|
||||||
--
|
--
|
||||||
-- ## 1.2 SAM sites
|
-- ## 1.2 SAM sites
|
||||||
--
|
--
|
||||||
@@ -183,7 +189,7 @@
|
|||||||
--
|
--
|
||||||
-- ## 2.1 Auto mode features
|
-- ## 2.1 Auto mode features
|
||||||
--
|
--
|
||||||
-- ### 2.1.1 You can now add Accept-, Reject- and Conflict-Zones to your setup, e.g. to consider borders or de-militarized zones:
|
-- ### 2.1.1 You can add Accept-, Reject- and Conflict-Zones to your setup, e.g. to consider borders or de-militarized zones:
|
||||||
--
|
--
|
||||||
-- -- Parameters are tables of Core.Zone#ZONE objects!
|
-- -- Parameters are tables of Core.Zone#ZONE objects!
|
||||||
-- -- This is effectively a 3-stage filter allowing for zone overlap. A coordinate is accepted first when
|
-- -- This is effectively a 3-stage filter allowing for zone overlap. A coordinate is accepted first when
|
||||||
@@ -192,31 +198,32 @@
|
|||||||
-- mybluemantis:AddZones(AcceptZones,RejectZones,ConflictZones)
|
-- mybluemantis:AddZones(AcceptZones,RejectZones,ConflictZones)
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
-- ### 2.1.2 Change the number of long-, mid- and short-range systems going live on a detected target:
|
-- ### 2.1.2 Change the number of long-, mid- and short-range, point defense systems going live on a detected target:
|
||||||
--
|
--
|
||||||
-- -- parameters are numbers. Defaults are 1,2,2,6 respectively
|
-- -- parameters are numbers. Defaults are 1,2,2,6,6 respectively
|
||||||
-- mybluemantis:SetMaxActiveSAMs(Short,Mid,Long,Classic)
|
-- mybluemantis:SetMaxActiveSAMs(Short,Mid,Long,Classic,Point)
|
||||||
--
|
--
|
||||||
-- ### 2.1.3 SHORAD will automatically be added from SAM sites of type "short-range"
|
-- ### 2.1.3 SHORAD/Point defense will automatically be added from SAM sites of type "point" or if the range is less than 5km or if the type is AAA.
|
||||||
--
|
--
|
||||||
-- ### 2.1.4 Advanced features
|
-- ### 2.1.4 Advanced features
|
||||||
--
|
|
||||||
-- -- switch off auto mode **before** you start MANTIS.
|
|
||||||
-- mybluemantis.automode = false
|
|
||||||
--
|
--
|
||||||
-- -- switch off auto shorad **before** you start MANTIS.
|
-- -- Option to set the scale of the activation range, i.e. don't activate at the fringes of max range, defaults below.
|
||||||
-- mybluemantis.autoshorad = false
|
|
||||||
--
|
|
||||||
-- -- scale of the activation range, i.e. don't activate at the fringes of max range, defaults below.
|
|
||||||
-- -- also see engagerange below.
|
-- -- also see engagerange below.
|
||||||
-- self.radiusscale[MANTIS.SamType.LONG] = 1.1
|
-- self.radiusscale[MANTIS.SamType.LONG] = 1.1
|
||||||
-- self.radiusscale[MANTIS.SamType.MEDIUM] = 1.2
|
-- self.radiusscale[MANTIS.SamType.MEDIUM] = 1.2
|
||||||
-- self.radiusscale[MANTIS.SamType.SHORT] = 1.3
|
-- self.radiusscale[MANTIS.SamType.SHORT] = 1.3
|
||||||
|
-- self.radiusscale[MANTIS.SamType.POINT] = 1.4
|
||||||
--
|
--
|
||||||
-- ### 2.1.5 Friendlies check in firing range
|
-- ### 2.1.5 Friendlies check in firing range
|
||||||
--
|
--
|
||||||
-- -- For some scenarios, like Cold War, it might be useful not to activate SAMs if friendly aircraft are around to avoid death by friendly fire.
|
-- -- For some scenarios, like Cold War, it might be useful not to activate SAMs if friendly aircraft are around to avoid death by friendly fire.
|
||||||
-- mybluemantis.checkforfriendlies = true
|
-- mybluemantis.checkforfriendlies = true
|
||||||
|
--
|
||||||
|
-- ### 2.1.6 Shoot & Scoot
|
||||||
|
--
|
||||||
|
-- -- Option to make the (driveable) SHORAD units drive around and shuffle positions
|
||||||
|
-- -- We use a SET_ZONE for that, number of zones to consider defaults to three, Random is true for random coordinates and Formation is e.g. "Vee".
|
||||||
|
-- mybluemantis:AddScootZones(ZoneSet, Number, Random, Formation)
|
||||||
--
|
--
|
||||||
-- # 3. Default settings [both modes unless stated otherwise]
|
-- # 3. Default settings [both modes unless stated otherwise]
|
||||||
--
|
--
|
||||||
@@ -239,26 +246,8 @@
|
|||||||
-- E.g. mymantis:SetAdvancedMode( true, 90 )
|
-- E.g. mymantis:SetAdvancedMode( true, 90 )
|
||||||
--
|
--
|
||||||
-- Use this option if you want to make use of or allow advanced SEAD tactics.
|
-- Use this option if you want to make use of or allow advanced SEAD tactics.
|
||||||
--
|
|
||||||
-- # 5. Integrate SHORAD [classic mode, not necessary in automode]
|
|
||||||
--
|
|
||||||
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
|
|
||||||
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
|
|
||||||
--
|
|
||||||
-- local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()
|
|
||||||
-- myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")
|
|
||||||
-- -- now set up MANTIS
|
|
||||||
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
|
||||||
-- mymantis:AddShorad(myshorad,720)
|
|
||||||
-- mymantis:Start()
|
|
||||||
--
|
--
|
||||||
-- If you systematically name your SHORAD groups starting with "Blue SHORAD" you'll need exactly **one** SHORAD instance to manage all SHORAD groups.
|
-- # 5. Integrated SEAD
|
||||||
--
|
|
||||||
-- (Optionally) you can remove the link later on with
|
|
||||||
--
|
|
||||||
-- mymantis:RemoveShorad()
|
|
||||||
--
|
|
||||||
-- # 6. Integrated SEAD
|
|
||||||
--
|
--
|
||||||
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
|
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
|
||||||
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
|
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
|
||||||
@@ -296,6 +285,7 @@ MANTIS = {
|
|||||||
SAM_Table_Long = {},
|
SAM_Table_Long = {},
|
||||||
SAM_Table_Medium = {},
|
SAM_Table_Medium = {},
|
||||||
SAM_Table_Short = {},
|
SAM_Table_Short = {},
|
||||||
|
SAM_Table_PointDef = {},
|
||||||
lid = "",
|
lid = "",
|
||||||
Detection = nil,
|
Detection = nil,
|
||||||
AWACS_Detection = nil,
|
AWACS_Detection = nil,
|
||||||
@@ -329,6 +319,11 @@ MANTIS = {
|
|||||||
autoshorad = true,
|
autoshorad = true,
|
||||||
ShoradGroupSet = nil,
|
ShoradGroupSet = nil,
|
||||||
checkforfriendlies = false,
|
checkforfriendlies = false,
|
||||||
|
SmokeDecoy = false,
|
||||||
|
SmokeDecoyColor = SMOKECOLOR.White,
|
||||||
|
checkcounter = 1,
|
||||||
|
DLinkCacheTime = 120,
|
||||||
|
logsamstatus = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Advanced state enumerator
|
--- Advanced state enumerator
|
||||||
@@ -345,8 +340,17 @@ MANTIS.SamType = {
|
|||||||
SHORT = "Short",
|
SHORT = "Short",
|
||||||
MEDIUM = "Medium",
|
MEDIUM = "Medium",
|
||||||
LONG = "Long",
|
LONG = "Long",
|
||||||
|
POINT = "Point",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- SAM Radiusscale
|
||||||
|
-- @type MANTIS.radiusscale
|
||||||
|
MANTIS.radiusscale = {}
|
||||||
|
MANTIS.radiusscale[MANTIS.SamType.LONG] = 1.1
|
||||||
|
MANTIS.radiusscale[MANTIS.SamType.MEDIUM] = 1.2
|
||||||
|
MANTIS.radiusscale[MANTIS.SamType.SHORT] = 1.75
|
||||||
|
MANTIS.radiusscale[MANTIS.SamType.POINT] = 3
|
||||||
|
|
||||||
--- SAM data
|
--- SAM data
|
||||||
-- @type MANTIS.SamData
|
-- @type MANTIS.SamData
|
||||||
-- @field #number Range Max firing range in km
|
-- @field #number Range Max firing range in km
|
||||||
@@ -354,10 +358,11 @@ MANTIS.SamType = {
|
|||||||
-- @field #number Height Max firing height in km
|
-- @field #number Height Max firing height in km
|
||||||
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
||||||
-- @field #string Radar Radar typename on unit level (used as key)
|
-- @field #string Radar Radar typename on unit level (used as key)
|
||||||
|
-- @field #string Point Point defense capable
|
||||||
MANTIS.SamData = {
|
MANTIS.SamData = {
|
||||||
["Hawk"] = { Range=35, Blindspot=0, Height=12, Type="Medium", Radar="Hawk" }, -- measures in km
|
["Hawk"] = { Range=35, Blindspot=0, Height=12, Type="Medium", Radar="Hawk" }, -- measures in km
|
||||||
["NASAMS"] = { Range=14, Blindspot=0, Height=7, Type="Short", Radar="NSAMS" }, -- AIM 120B
|
["NASAMS"] = { Range=14, Blindspot=0, Height=7, Type="Short", Radar="NSAMS" }, -- AIM 120B
|
||||||
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot" },
|
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot str" },
|
||||||
["Rapier"] = { Range=10, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
|
["Rapier"] = { Range=10, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
|
||||||
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="S_75M_Volhov" },
|
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="S_75M_Volhov" },
|
||||||
["SA-3"] = { Range=18, Blindspot=6, Height=18, Type="Short", Radar="5p73 s-125 ln" },
|
["SA-3"] = { Range=18, Blindspot=6, Height=18, Type="Short", Radar="5p73 s-125 ln" },
|
||||||
@@ -365,24 +370,25 @@ MANTIS.SamData = {
|
|||||||
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
|
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
|
||||||
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS 4"},
|
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS 4"},
|
||||||
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
|
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
|
||||||
["Roland"] = { Range=5, Blindspot=0, Height=5, Type="Short", Radar="Roland" },
|
["Roland"] = { Range=6, Blindspot=0, Height=5, Type="Short", Radar="Roland" },
|
||||||
|
["Gepard"] = { Range=5, Blindspot=0, Height=4, Type="Point", Radar="Gepard" },
|
||||||
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
|
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
|
||||||
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
|
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Strela", Point="true" },
|
||||||
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
|
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
|
||||||
["SA-19"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Tunguska" },
|
["SA-19"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Tunguska" },
|
||||||
["SA-15"] = { Range=11, Blindspot=0, Height=6, Type="Short", Radar="Tor 9A331" },
|
["SA-15"] = { Range=11, Blindspot=0, Height=6, Type="Point", Radar="Tor 9A331", Point="true" },
|
||||||
["SA-13"] = { Range=5, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
|
["SA-13"] = { Range=5, Blindspot=0, Height=3, Type="Point", Radar="Strela", Point="true" },
|
||||||
["Avenger"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Avenger" },
|
["Avenger"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Avenger" },
|
||||||
["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="Short", Radar="Linebacker" },
|
["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" },
|
||||||
-- 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=30, Type="Medium", Radar="SA-17" },
|
["SA-17"] = { Range=50, Blindspot=3, Height=30, Type="Medium", Radar="SA-17" },
|
||||||
["SA-20A"] = { Range=150, Blindspot=5, Height=27, Type="Long" , Radar="S-300PMU1"},
|
["SA-20A"] = { Range=150, Blindspot=5, Height=27, Type="Long" , Radar="S-300PMU1"},
|
||||||
["SA-20B"] = { Range=200, Blindspot=4, Height=27, Type="Long" , Radar="S-300PMU2"},
|
["SA-20B"] = { Range=200, Blindspot=4, Height=27, Type="Long" , Radar="S-300PMU2"},
|
||||||
["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" },
|
||||||
["SHORAD"] = { Range=3, Blindspot=0, Height=3, Type="Short", Radar="Igla" },
|
|
||||||
["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" },
|
||||||
}
|
}
|
||||||
@@ -394,6 +400,7 @@ MANTIS.SamData = {
|
|||||||
-- @field #number Height Max firing height in km
|
-- @field #number Height Max firing height in km
|
||||||
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
||||||
-- @field #string Radar Radar typename on unit level (used as key)
|
-- @field #string Radar Radar typename on unit level (used as key)
|
||||||
|
-- @field #string Point Point defense capable
|
||||||
MANTIS.SamDataHDS = {
|
MANTIS.SamDataHDS = {
|
||||||
-- units from HDS Mod, multi launcher options is tricky
|
-- units from HDS Mod, multi launcher options is tricky
|
||||||
-- group name MUST contain HDS to ID launcher type correctly!
|
-- group name MUST contain HDS to ID launcher type correctly!
|
||||||
@@ -415,20 +422,21 @@ MANTIS.SamDataHDS = {
|
|||||||
-- @field #number Height Max firing height in km
|
-- @field #number Height Max firing height in km
|
||||||
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
||||||
-- @field #string Radar Radar typename on unit level (used as key)
|
-- @field #string Radar Radar typename on unit level (used as key)
|
||||||
|
-- @field #string Point Point defense capable
|
||||||
MANTIS.SamDataSMA = {
|
MANTIS.SamDataSMA = {
|
||||||
-- units from SMA Mod (Sweedish Military Assets)
|
-- units from SMA Mod (Sweedish Military Assets)
|
||||||
-- https://forum.dcs.world/topic/295202-swedish-military-assets-for-dcs-by-currenthill/
|
-- https://forum.dcs.world/topic/295202-swedish-military-assets-for-dcs-by-currenthill/
|
||||||
-- group name MUST contain SMA to ID launcher type correctly!
|
-- group name MUST contain SMA to ID launcher type correctly!
|
||||||
["RBS98M SMA"] = { Range=20, Blindspot=0, Height=8, Type="Short", Radar="RBS-98" },
|
["RBS98M SMA"] = { Range=20, Blindspot=0.2, Height=8, Type="Short", Radar="RBS-98" },
|
||||||
["RBS70 SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-70" },
|
["RBS70 SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-70" },
|
||||||
["RBS70M SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="BV410_RBS70" },
|
["RBS70M SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS70" },
|
||||||
["RBS90 SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-90" },
|
["RBS90 SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-90" },
|
||||||
["RBS90M SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="BV410_RBS90" },
|
["RBS90M SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS90" },
|
||||||
["RBS103A SMA"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
|
["RBS103A SMA"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
|
||||||
["RBS103B SMA"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_Rb103B" },
|
["RBS103B SMA"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103B" },
|
||||||
["RBS103AM SMA"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
|
["RBS103AM SMA"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
|
||||||
["RBS103BM SMA"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_HX_Rb103B" },
|
["RBS103BM SMA"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103B" },
|
||||||
["Lvkv9040M SMA"] = { Range=4, Blindspot=0, Height=2.5, Type="Short", Radar="LvKv9040" },
|
["Lvkv9040M SMA"] = { Range=2, Blindspot=0.1, Height=1.2, Type="Point", Radar="LvKv9040",Point="true" },
|
||||||
}
|
}
|
||||||
|
|
||||||
--- SAM data CH
|
--- SAM data CH
|
||||||
@@ -438,51 +446,54 @@ MANTIS.SamDataSMA = {
|
|||||||
-- @field #number Height Max firing height in km
|
-- @field #number Height Max firing height in km
|
||||||
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
||||||
-- @field #string Radar Radar typename on unit level (used as key)
|
-- @field #string Radar Radar typename on unit level (used as key)
|
||||||
|
-- @field #string Point Point defense capable
|
||||||
MANTIS.SamDataCH = {
|
MANTIS.SamDataCH = {
|
||||||
-- units from CH (Military Assets by Currenthill)
|
-- units from CH (Military Assets by Currenthill)
|
||||||
-- 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=8, Blindspot=0.5, Height=6, 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="Short", Radar="PantsirS1" },
|
||||||
["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=0.5, 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=20, 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=160, 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=120, 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="Short", Radar="TorM2" },
|
||||||
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
||||||
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
||||||
["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="Short", Radar="CH_Centurion_C_RAM" },
|
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_Centurion_C_RAM", Point="true" },
|
||||||
["PGZ-09 CHM"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="CH_PGZ09" },
|
["PGZ-09 CHM"] = { Range=4, Blindspot=0.5, Height=3, Type="Point", Radar="CH_PGZ09", Point="true" },
|
||||||
["S350-9M100 CHM"] = { Range=15, Blindspot=1.5, Height=8, Type="Short", Radar="CH_S350_50P6_9M100" },
|
["S350-9M100 CHM"] = { Range=15, Blindspot=1, Height=8, Type="Short", Radar="CH_S350_50P6_9M100" },
|
||||||
["S350-9M96D CHM"] = { Range=150, Blindspot=2.5, Height=30, Type="Long", Radar="CH_S350_50P6_9M96D" },
|
["S350-9M96D CHM"] = { Range=150, Blindspot=2.5, Height=30, Type="Long", Radar="CH_S350_50P6_9M96D" },
|
||||||
["LAV-AD CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_LAVAD" },
|
["LAV-AD CHM"] = { Range=8, Blindspot=0.16, Height=4.8, Type="Short", Radar="CH_LAVAD" },
|
||||||
["HQ-22 CHM"] = { Range=170, Blindspot=5, Height=27, Type="Long", Radar="CH_HQ22_LN" },
|
["HQ-22 CHM"] = { Range=170, Blindspot=5, Height=27, Type="Long", Radar="CH_HQ22_LN" },
|
||||||
["PGZ-95 CHM"] = { Range=2, Blindspot=0, Height=2, Type="Short", Radar="CH_PGZ95" },
|
["PGZ-95 CHM"] = { Range=2.5, Blindspot=0.5, Height=2, Type="Point", Radar="CH_PGZ95",Point="true" },
|
||||||
["LD-3000 CHM"] = { Range=3, Blindspot=0, Height=3, Type="Short", Radar="CH_LD3000_stationary" },
|
["LD-3000 CHM"] = { Range=2.5, Blindspot=0.1, Height=3, Type="Point", Radar="CH_LD3000_stationary", Point="true" },
|
||||||
["LD-3000M CHM"] = { Range=3, Blindspot=0, Height=3, Type="Short", Radar="CH_LD3000" },
|
["LD-3000M CHM"] = { Range=2.5, Blindspot=0.1, Height=3, Type="Point", Radar="CH_LD3000", Point="true" },
|
||||||
["FlaRakRad CHM"] = { Range=8, Blindspot=1.5, Height=6, Type="Short", Radar="HQ17A" },
|
["FlaRakRad CHM"] = { Range=8, Blindspot=1.5, Height=6, Type="Short", Radar="CH_FlaRakRad" },
|
||||||
["IRIS-T SLM CHM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
|
["IRIS-T SLM CHM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
|
||||||
["M903PAC2KAT1 CHM"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="CH_MIM104_M903_PAC2_KAT1" },
|
["M903PAC2KAT1 CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="CH_MIM104_M903_PAC2_KAT1" },
|
||||||
["Skynex CHM"] = { Range=3.5, Blindspot=0, Height=3.5, Type="Short", Radar="CH_SkynexHX" },
|
["Skynex CHM"] = { Range=3.5, Blindspot=0.1, Height=3.5, Type="Point", Radar="CH_SkynexHX", Point="true" },
|
||||||
["Skyshield CHM"] = { Range=3.5, Blindspot=0, Height=3.5, Type="Short", Radar="CH_Skyshield_Gun" },
|
["Skyshield CHM"] = { Range=3.5, Blindspot=0.1, Height=3.5, Type="Point", Radar="CH_Skyshield_Gun", Point="true" },
|
||||||
["WieselOzelot CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_Wiesel2Ozelot" },
|
["WieselOzelot CHM"] = { Range=8, Blindspot=0.16, Height=4.8, Type="Short", Radar="CH_Wiesel2Ozelot" },
|
||||||
["BukM3-9M317M CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317M" },
|
["BukM3-9M317M CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317M" },
|
||||||
["BukM3-9M317MA CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317MA" },
|
["BukM3-9M317MA CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317MA" },
|
||||||
["SkySabre CHM"] = { Range=30, Blindspot=0.5, Height=10, Type="Medium", Radar="CH_SkySabreLN" },
|
["SkySabre CHM"] = { Range=30, Blindspot=0.5, Height=10, Type="Medium", Radar="CH_SkySabreLN" },
|
||||||
["Stormer CHM"] = { Range=7.5, Blindspot=0.3, Height=7, Type="Short", Radar="CH_StormerHVM" },
|
["Stormer CHM"] = { Range=7.5, Blindspot=0.3, Height=7, Type="Short", Radar="CH_StormerHVM" },
|
||||||
["THAAD CHM"] = { Range=200, Blindspot=40, Height=150, Type="Long", Radar="CH_THAAD_M1120" },
|
["THAAD CHM"] = { Range=200, Blindspot=40, Height=150, Type="Long", Radar="CH_THAAD_M1120" },
|
||||||
["USInfantryFIM92K CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_USInfantry_FIM92" },
|
["USInfantryFIM92K CHM"] = { Range=8, Blindspot=0.16, Height=4.8, Type="Short", Radar="CH_USInfantry_FIM92" },
|
||||||
["RBS98M CHM"] = { Range=20, Blindspot=0, Height=8, Type="Short", Radar="RBS-98" },
|
["RBS98M CHM"] = { Range=20, Blindspot=0.2, Height=8, Type="Short", Radar="RBS-98" },
|
||||||
["RBS70 CHM"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-70" },
|
["RBS70 CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-70" },
|
||||||
["RBS90 CHM"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-90" },
|
["RBS70M CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS70" },
|
||||||
["RBS103A CHM"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
|
["RBS90 CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-90" },
|
||||||
["RBS103B CHM"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_Rb103B" },
|
["RBS90M CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS90" },
|
||||||
["RBS103AM CHM"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
|
["RBS103A CHM"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
|
||||||
["RBS103BM CHM"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_HX_Rb103B" },
|
["RBS103B CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103B" },
|
||||||
["Lvkv9040M CHM"] = { Range=4, Blindspot=0, Height=2.5, Type="Short", Radar="LvKv9040" },
|
["RBS103AM CHM"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
|
||||||
|
["RBS103BM CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103B" },
|
||||||
|
["Lvkv9040M CHM"] = { Range=2, Blindspot=0.1, Height=1.2, Type="Point", Radar="LvKv9040",Point="true" },
|
||||||
}
|
}
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
@@ -543,6 +554,7 @@ do
|
|||||||
self.SAM_Table_Long = {}
|
self.SAM_Table_Long = {}
|
||||||
self.SAM_Table_Medium = {}
|
self.SAM_Table_Medium = {}
|
||||||
self.SAM_Table_Short = {}
|
self.SAM_Table_Short = {}
|
||||||
|
self.SAM_Table_PointDef = {}
|
||||||
self.dynamic = dynamic or false
|
self.dynamic = dynamic or false
|
||||||
self.checkradius = 25000
|
self.checkradius = 25000
|
||||||
self.grouping = 5000
|
self.grouping = 5000
|
||||||
@@ -571,10 +583,6 @@ do
|
|||||||
self.SuppressedGroups = {}
|
self.SuppressedGroups = {}
|
||||||
-- 0.8 additions
|
-- 0.8 additions
|
||||||
self.automode = true
|
self.automode = true
|
||||||
self.radiusscale = {}
|
|
||||||
self.radiusscale[MANTIS.SamType.LONG] = 1.1
|
|
||||||
self.radiusscale[MANTIS.SamType.MEDIUM] = 1.2
|
|
||||||
self.radiusscale[MANTIS.SamType.SHORT] = 1.3
|
|
||||||
--self.SAMCheckRanges = {}
|
--self.SAMCheckRanges = {}
|
||||||
self.usezones = false
|
self.usezones = false
|
||||||
self.AcceptZones = {}
|
self.AcceptZones = {}
|
||||||
@@ -583,6 +591,7 @@ do
|
|||||||
self.maxlongrange = 1
|
self.maxlongrange = 1
|
||||||
self.maxmidrange = 2
|
self.maxmidrange = 2
|
||||||
self.maxshortrange = 2
|
self.maxshortrange = 2
|
||||||
|
self.maxpointdefrange = 6
|
||||||
self.maxclassic = 6
|
self.maxclassic = 6
|
||||||
self.autoshorad = true
|
self.autoshorad = true
|
||||||
self.ShoradGroupSet = SET_GROUP:New() -- Core.Set#SET_GROUP
|
self.ShoradGroupSet = SET_GROUP:New() -- Core.Set#SET_GROUP
|
||||||
@@ -590,7 +599,10 @@ do
|
|||||||
|
|
||||||
self.SkateZones = nil
|
self.SkateZones = nil
|
||||||
self.SkateNumber = 3
|
self.SkateNumber = 3
|
||||||
self.shootandscoot = false
|
self.shootandscoot = false
|
||||||
|
|
||||||
|
self.SmokeDecoy = false
|
||||||
|
self.SmokeDecoyColor = SMOKECOLOR.White
|
||||||
|
|
||||||
self.UseEmOnOff = true
|
self.UseEmOnOff = true
|
||||||
if EmOnOff == false then
|
if EmOnOff == false then
|
||||||
@@ -602,7 +614,9 @@ do
|
|||||||
else
|
else
|
||||||
self.advAwacs = false
|
self.advAwacs = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:SetDLinkCacheTime()
|
||||||
|
|
||||||
-- Set the string id for output to DCS.log file.
|
-- Set the string id for output to DCS.log file.
|
||||||
self.lid=string.format("MANTIS %s | ", self.name)
|
self.lid=string.format("MANTIS %s | ", self.name)
|
||||||
|
|
||||||
@@ -635,6 +649,8 @@ do
|
|||||||
table.insert(self.ewr_templates,awacs)
|
table.insert(self.ewr_templates,awacs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.logsamstatus = false
|
||||||
|
|
||||||
self:T({self.ewr_templates})
|
self:T({self.ewr_templates})
|
||||||
|
|
||||||
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition)
|
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition)
|
||||||
@@ -661,9 +677,12 @@ do
|
|||||||
self.HQ_CC = GROUP:FindByName(self.HQ_Template_CC)
|
self.HQ_CC = GROUP:FindByName(self.HQ_Template_CC)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- counter for SAM table updates
|
||||||
|
self.checkcounter = 1
|
||||||
|
|
||||||
-- TODO Version
|
-- TODO Version
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
self.version="0.8.20"
|
self.version="0.9.30"
|
||||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||||
|
|
||||||
--- FSM Functions ---
|
--- FSM Functions ---
|
||||||
@@ -860,7 +879,7 @@ 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 #AcceptZones > 0 or #RejectZones > 0 or #ConflictZones > 0 then
|
if #self.AcceptZones > 0 or #self.RejectZones > 0 or #self.ConflictZones > 0 then
|
||||||
self.usezones = true
|
self.usezones = true
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@@ -899,19 +918,31 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function to set Short Range SAMs to spit out smoke as decoy, if an enemy plane is in range.
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #boolean Onoff Set to true for on and nil/false for off.
|
||||||
|
-- @param #number Color (Optional) Color to use, defaults to `SMOKECOLOR.White`
|
||||||
|
function MANTIS:SetSmokeDecoy(Onoff,Color)
|
||||||
|
self.SmokeDecoy = Onoff
|
||||||
|
self.SmokeDecoyColor = Color or SMOKECOLOR.White
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Function to set number of SAMs going active on a valid, detected thread
|
--- Function to set number of SAMs going active on a valid, detected thread
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
-- @param #number Short Number of short-range systems activated, defaults to 1.
|
-- @param #number Short Number of short-range systems activated, defaults to 1.
|
||||||
-- @param #number Mid Number of mid-range systems activated, defaults to 2.
|
-- @param #number Mid Number of mid-range systems activated, defaults to 2.
|
||||||
-- @param #number Long Number of long-range systems activated, defaults to 2.
|
-- @param #number Long Number of long-range systems activated, defaults to 2.
|
||||||
-- @param #number Classic (non-automode) Number of overall systems activated, defaults to 6.
|
-- @param #number Classic (non-automode) Number of overall systems activated, defaults to 6.
|
||||||
|
-- @param #number Point Number of point defense and AAA systems activated, defaults to 6.
|
||||||
-- @return #MANTIS self
|
-- @return #MANTIS self
|
||||||
function MANTIS:SetMaxActiveSAMs(Short,Mid,Long,Classic)
|
function MANTIS:SetMaxActiveSAMs(Short,Mid,Long,Classic,Point)
|
||||||
self:T(self.lid .. "SetMaxActiveSAMs")
|
self:T(self.lid .. "SetMaxActiveSAMs")
|
||||||
self.maxclassic = Classic or 6
|
self.maxclassic = Classic or 6
|
||||||
self.maxlongrange = Long or 1
|
self.maxlongrange = Long or 1
|
||||||
self.maxmidrange = Mid or 2
|
self.maxmidrange = Mid or 2
|
||||||
self.maxshortrange = Short or 2
|
self.maxshortrange = Short or 2
|
||||||
|
self.maxpointdefrange= Point or 6
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1001,6 +1032,16 @@ do
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function to set how long INTEL DLINK remembers contacts.
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #number seconds Remember this many seconds, at least 5 seconds.
|
||||||
|
-- @return #MANTIS self
|
||||||
|
function MANTIS:SetDLinkCacheTime(seconds)
|
||||||
|
self.DLinkCacheTime = math.abs(seconds or 120)
|
||||||
|
if self.DLinkCacheTime < 5 then self.DLinkCacheTime = 5 end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Function to set the detection interval
|
--- Function to set the detection interval
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
@@ -1113,6 +1154,24 @@ do
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [Internal] Check if any EWR or AWACS is still alive
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @return #boolean outcome
|
||||||
|
function MANTIS:_CheckAnyEWRAlive()
|
||||||
|
self:T(self.lid .. "_CheckAnyEWRAlive")
|
||||||
|
local alive = false
|
||||||
|
if self.EWR_Group:CountAlive() > 0 then
|
||||||
|
alive = true
|
||||||
|
end
|
||||||
|
if not alive and self.AWACS_Prefix then
|
||||||
|
local awacs = GROUP:FindByName(self.AWACS_Prefix)
|
||||||
|
if awacs and awacs:IsAlive() then
|
||||||
|
alive = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return alive
|
||||||
|
end
|
||||||
|
|
||||||
--- [Internal] Function to determine state of the advanced mode
|
--- [Internal] Function to determine state of the advanced mode
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
@@ -1287,9 +1346,9 @@ do
|
|||||||
-- DEBUG
|
-- DEBUG
|
||||||
set = self:_PreFilterHeight(height)
|
set = self:_PreFilterHeight(height)
|
||||||
end
|
end
|
||||||
local friendlyset -- Core.Set#SET_GROUP
|
--self.friendlyset -- Core.Set#SET_GROUP
|
||||||
if self.checkforfriendlies == true then
|
if self.checkforfriendlies == true and self.friendlyset == nil then
|
||||||
friendlyset = SET_GROUP:New():FilterCoalitions(self.Coalition):FilterCategories({"plane","helicopter"}):FilterFunction(function(grp) if grp and grp:InAir() then return true else return false end end):FilterOnce()
|
self.friendlyset = SET_GROUP:New():FilterCoalitions(self.Coalition):FilterCategories({"plane","helicopter"}):FilterFunction(function(grp) if grp and grp:InAir() then return true else return false end end):FilterStart()
|
||||||
end
|
end
|
||||||
for _,_coord in pairs (set) do
|
for _,_coord in pairs (set) do
|
||||||
local coord = _coord -- get current coord to check
|
local coord = _coord -- get current coord to check
|
||||||
@@ -1305,20 +1364,21 @@ do
|
|||||||
zonecheck = self:_CheckCoordinateInZones(coord)
|
zonecheck = self:_CheckCoordinateInZones(coord)
|
||||||
end
|
end
|
||||||
if self.verbose and self.debug then
|
if self.verbose and self.debug then
|
||||||
local dectstring = coord:ToStringLLDMS()
|
--local dectstring = coord:ToStringLLDMS()
|
||||||
local samstring = samcoordinate:ToStringLLDMS()
|
local samstring = samcoordinate:ToStringMGRS({MGRS_Accuracy=0})
|
||||||
|
samstring = string.gsub(samstring,"%s","")
|
||||||
local inrange = "false"
|
local inrange = "false"
|
||||||
if targetdistance <= rad then
|
if targetdistance <= rad then
|
||||||
inrange = "true"
|
inrange = "true"
|
||||||
end
|
end
|
||||||
local text = string.format("Checking SAM at %s | Targetdist %d | Rad %d | Inrange %s", samstring, targetdistance, rad, inrange)
|
local text = string.format("Checking SAM at %s | Tgtdist %.1fkm | Rad %.1fkm | Inrange %s", samstring, targetdistance/1000, rad/1000, inrange)
|
||||||
local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug)
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
end
|
end
|
||||||
-- friendlies around?
|
-- friendlies around?
|
||||||
local nofriendlies = true
|
local nofriendlies = true
|
||||||
if self.checkforfriendlies == true then
|
if self.checkforfriendlies == true then
|
||||||
local closestfriend, distance = friendlyset:GetClosestGroup(samcoordinate)
|
local closestfriend, distance = self.friendlyset:GetClosestGroup(samcoordinate)
|
||||||
if closestfriend and distance and distance < rad then
|
if closestfriend and distance and distance < rad then
|
||||||
nofriendlies = false
|
nofriendlies = false
|
||||||
end
|
end
|
||||||
@@ -1374,7 +1434,9 @@ do
|
|||||||
--IntelTwo:SetClusterRadius(5000)
|
--IntelTwo:SetClusterRadius(5000)
|
||||||
IntelTwo:Start()
|
IntelTwo:Start()
|
||||||
|
|
||||||
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,300)
|
local CacheTime = self.DLinkCacheTime or 120
|
||||||
|
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,CacheTime)
|
||||||
|
|
||||||
IntelDlink:__Start(1)
|
IntelDlink:__Start(1)
|
||||||
|
|
||||||
self:SetUsingDLink(IntelDlink)
|
self:SetUsingDLink(IntelDlink)
|
||||||
@@ -1436,7 +1498,7 @@ do
|
|||||||
elseif chm then
|
elseif chm then
|
||||||
SAMData = self.SamDataCH
|
SAMData = self.SamDataCH
|
||||||
end
|
end
|
||||||
--self:T("Looking to auto-match for "..grpname)
|
--self:I("Looking to auto-match for "..grpname)
|
||||||
for _,_unit in pairs(units) do
|
for _,_unit in pairs(units) do
|
||||||
local unit = _unit -- Wrapper.Unit#UNIT
|
local unit = _unit -- Wrapper.Unit#UNIT
|
||||||
local type = string.lower(unit:GetTypeName())
|
local type = string.lower(unit:GetTypeName())
|
||||||
@@ -1458,6 +1520,17 @@ do
|
|||||||
end
|
end
|
||||||
if found then break end
|
if found then break end
|
||||||
end
|
end
|
||||||
|
--- AAA or Point Defense
|
||||||
|
if not found then
|
||||||
|
local grp = GROUP:FindByName(grpname)
|
||||||
|
if (grp and grp:IsAlive() and grp:IsAAA()) or string.find(grpname,"AAA",1,true) then
|
||||||
|
range = 2000
|
||||||
|
height = 2000
|
||||||
|
blind = 50
|
||||||
|
type = MANTIS.SamType.POINT
|
||||||
|
found = true
|
||||||
|
end
|
||||||
|
end
|
||||||
if not found then
|
if not found then
|
||||||
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
|
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
|
||||||
end
|
end
|
||||||
@@ -1491,7 +1564,7 @@ do
|
|||||||
end
|
end
|
||||||
--if self.automode then
|
--if self.automode then
|
||||||
for idx,entry in pairs(self.SamData) do
|
for idx,entry in pairs(self.SamData) do
|
||||||
self:T("ID = " .. idx)
|
self:T2("ID = " .. idx)
|
||||||
if string.find(grpname,idx,1,true) then
|
if string.find(grpname,idx,1,true) then
|
||||||
local _entry = entry -- #MANTIS.SamData
|
local _entry = entry -- #MANTIS.SamData
|
||||||
type = _entry.Type
|
type = _entry.Type
|
||||||
@@ -1505,14 +1578,25 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
--end
|
--end
|
||||||
-- secondary filter if not found
|
--- Secondary - AAA or Point Defense
|
||||||
|
if not found then
|
||||||
|
local grp = GROUP:FindByName(grpname)
|
||||||
|
if (grp and grp:IsAlive() and grp:IsAAA()) or string.find(grpname,"AAA",1,true) then
|
||||||
|
range = 2000
|
||||||
|
height = 2000
|
||||||
|
blind = 50
|
||||||
|
type = MANTIS.SamType.POINT
|
||||||
|
found = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--- Tertiary filter if not found
|
||||||
if (not found) or HDSmod or SMAMod or CHMod then
|
if (not found) or HDSmod or SMAMod or CHMod then
|
||||||
range, height, type = self:_GetSAMDataFromUnits(grpname,HDSmod,SMAMod,CHMod)
|
range, height, type = self:_GetSAMDataFromUnits(grpname,HDSmod,SMAMod,CHMod)
|
||||||
elseif not found then
|
elseif not found then
|
||||||
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
|
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
|
||||||
end
|
end
|
||||||
if string.find(grpname,"SHORAD",1,true) then
|
if found and string.find(grpname,"SHORAD",1,true) then
|
||||||
type = MANTIS.SamType.SHORT -- force short on match
|
type = MANTIS.SamType.POINT -- force short on match
|
||||||
end
|
end
|
||||||
return range, height, type, blind
|
return range, height, type, blind
|
||||||
end
|
end
|
||||||
@@ -1531,6 +1615,7 @@ do
|
|||||||
local SAM_Tbl_lg = {} -- table of long range SAM defense zones
|
local SAM_Tbl_lg = {} -- table of long range SAM defense zones
|
||||||
local SAM_Tbl_md = {} -- table of mid range SAM defense zones
|
local SAM_Tbl_md = {} -- table of mid range SAM defense zones
|
||||||
local SAM_Tbl_sh = {} -- table of short range SAM defense zones
|
local SAM_Tbl_sh = {} -- table of short range SAM defense zones
|
||||||
|
local SAM_Tbl_pt = {} -- table of point defense/AAA
|
||||||
local SEAD_Grps = {} -- table of SAM names to make evasive
|
local SEAD_Grps = {} -- table of SAM names to make evasive
|
||||||
local engagerange = self.engagerange -- firing range in % of max
|
local engagerange = self.engagerange -- firing range in % of max
|
||||||
--cycle through groups and set alarm state etc
|
--cycle through groups and set alarm state etc
|
||||||
@@ -1549,23 +1634,27 @@ do
|
|||||||
local grpname = group:GetName()
|
local grpname = group:GetName()
|
||||||
local grpcoord = group:GetCoordinate()
|
local grpcoord = group:GetCoordinate()
|
||||||
local grprange,grpheight,type,blind = self:_GetSAMRange(grpname)
|
local grprange,grpheight,type,blind = self:_GetSAMRange(grpname)
|
||||||
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
--table.insert( SEAD_Grps, grpname )
|
--table.insert( SEAD_Grps, grpname )
|
||||||
if type == MANTIS.SamType.LONG then
|
if type == MANTIS.SamType.LONG then
|
||||||
table.insert( SAM_Tbl_lg, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl_lg, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
table.insert( SEAD_Grps, grpname )
|
table.insert( SEAD_Grps, grpname )
|
||||||
--self:T("SAM "..grpname.." is type LONG")
|
self:T("SAM "..grpname.." is type LONG")
|
||||||
elseif type == MANTIS.SamType.MEDIUM then
|
elseif type == MANTIS.SamType.MEDIUM then
|
||||||
table.insert( SAM_Tbl_md, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl_md, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
table.insert( SEAD_Grps, grpname )
|
table.insert( SEAD_Grps, grpname )
|
||||||
--self:T("SAM "..grpname.." is type MEDIUM")
|
self:T("SAM "..grpname.." is type MEDIUM")
|
||||||
elseif type == MANTIS.SamType.SHORT then
|
elseif type == MANTIS.SamType.SHORT then
|
||||||
table.insert( SAM_Tbl_sh, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl_sh, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
--self:T("SAM "..grpname.." is type SHORT")
|
table.insert( SEAD_Grps, grpname )
|
||||||
|
self:T("SAM "..grpname.." is type SHORT")
|
||||||
|
elseif type == MANTIS.SamType.POINT then
|
||||||
|
table.insert( SAM_Tbl_pt, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
|
self:T("SAM "..grpname.." is type POINT")
|
||||||
self.ShoradGroupSet:Add(grpname,group)
|
self.ShoradGroupSet:Add(grpname,group)
|
||||||
if not self.autoshorad then
|
if not self.autoshorad then
|
||||||
table.insert( SEAD_Grps, grpname )
|
table.insert( SEAD_Grps, grpname )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.SamStateTracker[grpname] = "GREEN"
|
self.SamStateTracker[grpname] = "GREEN"
|
||||||
end
|
end
|
||||||
@@ -1574,6 +1663,7 @@ do
|
|||||||
self.SAM_Table_Long = SAM_Tbl_lg
|
self.SAM_Table_Long = SAM_Tbl_lg
|
||||||
self.SAM_Table_Medium = SAM_Tbl_md
|
self.SAM_Table_Medium = SAM_Tbl_md
|
||||||
self.SAM_Table_Short = SAM_Tbl_sh
|
self.SAM_Table_Short = SAM_Tbl_sh
|
||||||
|
self.SAM_Table_PointDef = SAM_Tbl_pt
|
||||||
-- make SAMs evasive
|
-- make SAMs evasive
|
||||||
local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD
|
local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD
|
||||||
mysead:SetEngagementRange(engagerange)
|
mysead:SetEngagementRange(engagerange)
|
||||||
@@ -1597,7 +1687,8 @@ do
|
|||||||
local SAM_Tbl = {} -- table of SAM defense zones
|
local SAM_Tbl = {} -- table of SAM defense zones
|
||||||
local SAM_Tbl_lg = {} -- table of long range SAM defense zones
|
local SAM_Tbl_lg = {} -- table of long range SAM defense zones
|
||||||
local SAM_Tbl_md = {} -- table of mid range SAM defense zones
|
local SAM_Tbl_md = {} -- table of mid range SAM defense zones
|
||||||
local SAM_Tbl_sh = {} -- table of short range SAM defense zon
|
local SAM_Tbl_sh = {} -- table of short range SAM defense zones
|
||||||
|
local SAM_Tbl_pt = {} -- table of point defense/AAA
|
||||||
local SEAD_Grps = {} -- table of SAM names to make evasive
|
local SEAD_Grps = {} -- table of SAM names to make evasive
|
||||||
local engagerange = self.engagerange -- firing range in % of max
|
local engagerange = self.engagerange -- firing range in % of max
|
||||||
--cycle through groups and set alarm state etc
|
--cycle through groups and set alarm state etc
|
||||||
@@ -1608,17 +1699,23 @@ do
|
|||||||
local grpname = group:GetName()
|
local grpname = group:GetName()
|
||||||
local grpcoord = group:GetCoordinate()
|
local grpcoord = group:GetCoordinate()
|
||||||
local grprange, grpheight,type,blind = self:_GetSAMRange(grpname)
|
local grprange, grpheight,type,blind = self:_GetSAMRange(grpname)
|
||||||
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind}) -- make the table lighter, as I don't really use the zone here
|
-- TODO the below might stop working at some point after some hours, needs testing
|
||||||
|
--local radaralive = group:IsSAM()
|
||||||
|
local radaralive = true
|
||||||
|
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind, type}) -- make the table lighter, as I don't really use the zone here
|
||||||
table.insert( SEAD_Grps, grpname )
|
table.insert( SEAD_Grps, grpname )
|
||||||
if type == MANTIS.SamType.LONG then
|
if type == MANTIS.SamType.LONG and radaralive then
|
||||||
table.insert( SAM_Tbl_lg, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl_lg, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
--self:I({grpname,grprange, grpheight})
|
self:T({grpname,grprange, grpheight})
|
||||||
elseif type == MANTIS.SamType.MEDIUM then
|
elseif type == MANTIS.SamType.MEDIUM and radaralive then
|
||||||
table.insert( SAM_Tbl_md, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl_md, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
--self:I({grpname,grprange, grpheight})
|
self:T({grpname,grprange, grpheight})
|
||||||
elseif type == MANTIS.SamType.SHORT then
|
elseif type == MANTIS.SamType.SHORT and radaralive then
|
||||||
table.insert( SAM_Tbl_sh, {grpname, grpcoord, grprange, grpheight, blind})
|
table.insert( SAM_Tbl_sh, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
-- self:I({grpname,grprange, grpheight})
|
self:T({grpname,grprange, grpheight})
|
||||||
|
elseif type == MANTIS.SamType.POINT or (not radaralive) then
|
||||||
|
table.insert( SAM_Tbl_pt, {grpname, grpcoord, grprange, grpheight, blind, type})
|
||||||
|
self:T({grpname,grprange, grpheight})
|
||||||
self.ShoradGroupSet:Add(grpname,group)
|
self.ShoradGroupSet:Add(grpname,group)
|
||||||
if self.autoshorad then
|
if self.autoshorad then
|
||||||
self.Shorad.Groupset = self.ShoradGroupSet
|
self.Shorad.Groupset = self.ShoradGroupSet
|
||||||
@@ -1630,6 +1727,7 @@ do
|
|||||||
self.SAM_Table_Long = SAM_Tbl_lg
|
self.SAM_Table_Long = SAM_Tbl_lg
|
||||||
self.SAM_Table_Medium = SAM_Tbl_md
|
self.SAM_Table_Medium = SAM_Tbl_md
|
||||||
self.SAM_Table_Short = SAM_Tbl_sh
|
self.SAM_Table_Short = SAM_Tbl_sh
|
||||||
|
self.SAM_Table_PointDef = SAM_Tbl_pt
|
||||||
-- make SAMs evasive
|
-- make SAMs evasive
|
||||||
if self.mysead ~= nil then
|
if self.mysead ~= nil then
|
||||||
local mysead = self.mysead
|
local mysead = self.mysead
|
||||||
@@ -1673,13 +1771,15 @@ do
|
|||||||
-- @param #table detset Table of COORDINATES
|
-- @param #table detset Table of COORDINATES
|
||||||
-- @param #boolean dlink Using DLINK
|
-- @param #boolean dlink Using DLINK
|
||||||
-- @param #number limit of SAM sites to go active on a contact
|
-- @param #number limit of SAM sites to go active on a contact
|
||||||
-- @return #MANTIS self
|
-- @return #number instatusred
|
||||||
|
-- @return #number instatusgreen
|
||||||
|
-- @return #number activeshorads
|
||||||
function MANTIS:_CheckLoop(samset,detset,dlink,limit)
|
function MANTIS:_CheckLoop(samset,detset,dlink,limit)
|
||||||
self:T(self.lid .. "CheckLoop " .. #detset .. " Coordinates")
|
self:T(self.lid .. "CheckLoop " .. #detset .. " Coordinates")
|
||||||
local switchedon = 0
|
local switchedon = 0
|
||||||
local statusreport = REPORT:New("\nMANTIS Status")
|
|
||||||
local instatusred = 0
|
local instatusred = 0
|
||||||
local instatusgreen = 0
|
local instatusgreen = 0
|
||||||
|
local activeshorads = 0
|
||||||
local SEADactive = 0
|
local SEADactive = 0
|
||||||
for _,_data in pairs (samset) do
|
for _,_data in pairs (samset) do
|
||||||
local samcoordinate = _data[2]
|
local samcoordinate = _data[2]
|
||||||
@@ -1687,10 +1787,17 @@ do
|
|||||||
local radius = _data[3]
|
local radius = _data[3]
|
||||||
local height = _data[4]
|
local height = _data[4]
|
||||||
local blind = _data[5] * 1.25 + 1
|
local blind = _data[5] * 1.25 + 1
|
||||||
|
local shortsam = (_data[6] == MANTIS.SamType.SHORT) and true or false
|
||||||
|
if not shortsam then
|
||||||
|
shortsam = (_data[6] == MANTIS.SamType.POINT) and true or false
|
||||||
|
end
|
||||||
local samgroup = GROUP:FindByName(name)
|
local samgroup = GROUP:FindByName(name)
|
||||||
local IsInZone, Distance = self:_CheckObjectInZone(detset, samcoordinate, radius, height, dlink)
|
local IsInZone, Distance = self:_CheckObjectInZone(detset, samcoordinate, radius, height, dlink)
|
||||||
local suppressed = self.SuppressedGroups[name] or false
|
local suppressed = self.SuppressedGroups[name] or false
|
||||||
local activeshorad = self.Shorad.ActiveGroups[name] or false
|
local activeshorad = false
|
||||||
|
if self.Shorad and self.Shorad.ActiveGroups and self.Shorad.ActiveGroups[name] then
|
||||||
|
activeshorad = true
|
||||||
|
end
|
||||||
if IsInZone and not suppressed and not activeshorad then --check any target in zone and not currently managed by SEAD
|
if IsInZone and not suppressed and not activeshorad then --check any target in zone and not currently managed by SEAD
|
||||||
if samgroup:IsAlive() then
|
if samgroup:IsAlive() then
|
||||||
-- switch on SAM
|
-- switch on SAM
|
||||||
@@ -1709,6 +1816,17 @@ do
|
|||||||
self:__RedState(1,samgroup)
|
self:__RedState(1,samgroup)
|
||||||
self.SamStateTracker[name] = "RED"
|
self.SamStateTracker[name] = "RED"
|
||||||
end
|
end
|
||||||
|
-- TODO doesn't work
|
||||||
|
if shortsam == true and self.SmokeDecoy == true then
|
||||||
|
self:T("Smoking")
|
||||||
|
local units = samgroup:GetUnits() or {}
|
||||||
|
local smoke = self.SmokeDecoyColor or SMOKECOLOR.White
|
||||||
|
for _,unit in pairs(units) do
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
unit:GetCoordinate():Smoke(smoke)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
-- link in to SHORAD if available
|
-- link in to SHORAD if available
|
||||||
-- DONE: Test integration fully
|
-- DONE: Test integration fully
|
||||||
if self.ShoradLink and (Distance < self.ShoradActDistance or Distance < blind ) then -- don't give SHORAD position away too early
|
if self.ShoradLink and (Distance < self.ShoradActDistance or Distance < blind ) then -- don't give SHORAD position away too early
|
||||||
@@ -1745,7 +1863,7 @@ do
|
|||||||
end --end alive
|
end --end alive
|
||||||
end --end check
|
end --end check
|
||||||
end --for loop
|
end --for loop
|
||||||
if self.debug then
|
if self.debug or self.verbose or self.logsamstatus then
|
||||||
for _,_status in pairs(self.SamStateTracker) do
|
for _,_status in pairs(self.SamStateTracker) do
|
||||||
if _status == "GREEN" then
|
if _status == "GREEN" then
|
||||||
instatusgreen=instatusgreen+1
|
instatusgreen=instatusgreen+1
|
||||||
@@ -1753,41 +1871,67 @@ do
|
|||||||
instatusred=instatusred+1
|
instatusred=instatusred+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
statusreport:Add("+-----------------------------+")
|
if self.Shorad then
|
||||||
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
for _,_name in pairs(self.Shorad.ActiveGroups or {}) do
|
||||||
statusreport:Add(string.format("+ SAM in GREEN State: %2d",instatusgreen))
|
activeshorads=activeshorads+1
|
||||||
statusreport:Add("+-----------------------------+")
|
end
|
||||||
MESSAGE:New(statusreport:Text(),10,nil,true):ToAll():ToLog()
|
end
|
||||||
end
|
end
|
||||||
return self
|
return instatusred, instatusgreen, activeshorads
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [Internal] Check detection function
|
--- [Internal] Check detection function
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
|
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
|
||||||
-- @param #boolean dlink
|
-- @param #boolean dlink
|
||||||
|
-- @param #boolean reporttolog
|
||||||
-- @return #MANTIS self
|
-- @return #MANTIS self
|
||||||
function MANTIS:_Check(detection,dlink)
|
function MANTIS:_Check(detection,dlink,reporttolog)
|
||||||
self:T(self.lid .. "Check")
|
self:T(self.lid .. "Check")
|
||||||
--get detected set
|
--get detected set
|
||||||
local detset = detection:GetDetectedItemCoordinates()
|
local detset = detection:GetDetectedItemCoordinates()
|
||||||
--self:T("Check:", {detset})
|
--self:T("Check:", {detset})
|
||||||
-- randomly update SAM Table
|
-- update SAM Table evey 3 runs
|
||||||
local rand = math.random(1,100)
|
if self.checkcounter%3 == 0 then
|
||||||
if rand > 65 then -- 1/3 of cases
|
|
||||||
self:_RefreshSAMTable()
|
self:_RefreshSAMTable()
|
||||||
end
|
end
|
||||||
|
self.checkcounter = self.checkcounter + 1
|
||||||
|
local instatusred = 0
|
||||||
|
local instatusgreen = 0
|
||||||
|
local activeshorads = 0
|
||||||
-- switch SAMs on/off if (n)one of the detected groups is inside their reach
|
-- switch SAMs on/off if (n)one of the detected groups is inside their reach
|
||||||
if self.automode then
|
if self.automode then
|
||||||
local samset = self.SAM_Table_Long -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
local samset = self.SAM_Table_Long -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
||||||
self:_CheckLoop(samset,detset,dlink,self.maxlongrange)
|
local instatusredl, instatusgreenl, activeshoradsl = self:_CheckLoop(samset,detset,dlink,self.maxlongrange)
|
||||||
local samset = self.SAM_Table_Medium -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
local samset = self.SAM_Table_Medium -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
||||||
self:_CheckLoop(samset,detset,dlink,self.maxmidrange)
|
local instatusredm, instatusgreenm, activeshoradsm = self:_CheckLoop(samset,detset,dlink,self.maxmidrange)
|
||||||
local samset = self.SAM_Table_Short -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
local samset = self.SAM_Table_Short -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
||||||
self:_CheckLoop(samset,detset,dlink,self.maxshortrange)
|
local instatusreds, instatusgreens, activeshoradss = self:_CheckLoop(samset,detset,dlink,self.maxshortrange)
|
||||||
|
local samset = self.SAM_Table_PointDef -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
||||||
|
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxpointdefrange)
|
||||||
else
|
else
|
||||||
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
||||||
self:_CheckLoop(samset,detset,dlink,self.maxclassic)
|
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxclassic)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function GetReport()
|
||||||
|
local statusreport = REPORT:New("\nMANTIS Status "..self.name)
|
||||||
|
statusreport:Add("+-----------------------------+")
|
||||||
|
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
||||||
|
statusreport:Add(string.format("+ SAM in GREEN State: %2d",instatusgreen))
|
||||||
|
if self.Shorad then
|
||||||
|
statusreport:Add(string.format("+ SHORAD active: %2d",activeshorads))
|
||||||
|
end
|
||||||
|
statusreport:Add("+-----------------------------+")
|
||||||
|
return statusreport
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.debug or self.verbose then
|
||||||
|
local statusreport = GetReport()
|
||||||
|
MESSAGE:New(statusreport:Text(),10):ToAll():ToLog()
|
||||||
|
elseif reporttolog == true then
|
||||||
|
local statusreport = GetReport()
|
||||||
|
MESSAGE:New(statusreport:Text(),10):ToLog()
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1895,14 +2039,36 @@ do
|
|||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
-- check detection
|
-- check detection
|
||||||
if not self.state2flag then
|
if not self.state2flag then
|
||||||
self:_Check(self.Detection,self.DLink)
|
self:_Check(self.Detection,self.DLink,self.logsamstatus)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ check Awacs
|
local EWRAlive = self:_CheckAnyEWRAlive()
|
||||||
if self.advAwacs and not self.state2flag then
|
|
||||||
self:_Check(self.AWACS_Detection,false)
|
local function FindSAMSRTR()
|
||||||
|
for i=1,1000 do
|
||||||
|
local randomsam = self.SAM_Group:GetRandom()
|
||||||
|
if randomsam and randomsam:IsAlive() then
|
||||||
|
if randomsam:IsSAM() then return randomsam end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Switch on a random SR/TR if no EWR left over
|
||||||
|
if not EWRAlive then
|
||||||
|
local randomsam = FindSAMSRTR() -- Wrapper.Group#GROUP
|
||||||
|
if randomsam and randomsam:IsAlive() then
|
||||||
|
if self.UseEmOnOff then
|
||||||
|
randomsam:EnableEmission(true)
|
||||||
|
else
|
||||||
|
randomsam:OptionAlarmStateRed()
|
||||||
|
end
|
||||||
|
local name = randomsam:GetName()
|
||||||
|
if self.SamStateTracker[name] ~= "RED" then
|
||||||
|
self:__RedState(1,randomsam)
|
||||||
|
self.SamStateTracker[name] = "RED"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
--]]
|
|
||||||
|
|
||||||
-- relocate HQ and EWR
|
-- relocate HQ and EWR
|
||||||
if self.autorelocate then
|
if self.autorelocate then
|
||||||
@@ -1912,8 +2078,6 @@ do
|
|||||||
|
|
||||||
local halfintv = math.floor(timepassed / relointerval)
|
local halfintv = math.floor(timepassed / relointerval)
|
||||||
|
|
||||||
--self:T({timepassed=timepassed, halfintv=halfintv})
|
|
||||||
|
|
||||||
if halfintv >= 1 then
|
if halfintv >= 1 then
|
||||||
self.TimeStamp = timer.getAbsTime()
|
self.TimeStamp = timer.getAbsTime()
|
||||||
self:_Relocate()
|
self:_Relocate()
|
||||||
@@ -2042,7 +2206,7 @@ do
|
|||||||
local Shorad = self.Shorad
|
local Shorad = self.Shorad
|
||||||
local radius = self.checkradius
|
local radius = self.checkradius
|
||||||
local ontime = self.ShoradTime
|
local ontime = self.ShoradTime
|
||||||
Shorad:WakeUpShorad(Name, radius, ontime)
|
Shorad:WakeUpShorad(Name, radius, ontime, nil, true)
|
||||||
self:__ShoradActivated(1,Name, radius, ontime)
|
self:__ShoradActivated(1,Name, radius, ontime)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -53,6 +53,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
|
||||||
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
|
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -107,6 +107,9 @@
|
|||||||
-- @field Sound.SRS#MSRSQUEUE instructsrsQ SRS queue for range instructor.
|
-- @field Sound.SRS#MSRSQUEUE instructsrsQ SRS queue for range instructor.
|
||||||
-- @field #number Coalition Coalition side for the menu, if any.
|
-- @field #number Coalition Coalition side for the menu, if any.
|
||||||
-- @field Core.Menu#MENU_MISSION menuF10root Specific user defined root F10 menu.
|
-- @field Core.Menu#MENU_MISSION menuF10root Specific user defined root F10 menu.
|
||||||
|
-- @field #number ceilingaltitude Range ceiling altitude in ft MSL. Aircraft above this altitude are not considered to be in the range. Default is 20000 ft.
|
||||||
|
-- @field #boolean ceilingenabled Range has a ceiling and is not unlimited. Default is false.
|
||||||
|
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *Don't only practice your art, but force your way into its secrets; art deserves that, for it and knowledge can raise man to the Divine.* - Ludwig van Beethoven
|
--- *Don't only practice your art, but force your way into its secrets; art deserves that, for it and knowledge can raise man to the Divine.* - Ludwig van Beethoven
|
||||||
@@ -273,6 +276,10 @@
|
|||||||
-- -- Create a range object.
|
-- -- Create a range object.
|
||||||
-- GoldwaterRange=RANGE:New("Goldwater Range")
|
-- GoldwaterRange=RANGE:New("Goldwater Range")
|
||||||
--
|
--
|
||||||
|
-- -- Set and enable the range ceiling altitude in feet MSL. If aircraft are above this altitude they are not considered to be in the range.
|
||||||
|
-- GoldwaterRange:SetRangeCeiling(20000)
|
||||||
|
-- GoldwaterRange:EnableRangeCeiling(true)
|
||||||
|
--
|
||||||
-- -- Distance between strafe target and foul line. You have to specify the names of the unit or static objects.
|
-- -- Distance between strafe target and foul line. You have to specify the names of the unit or static objects.
|
||||||
-- -- Note that this could also be done manually by simply measuring the distance between the target and the foul line in the ME.
|
-- -- Note that this could also be done manually by simply measuring the distance between the target and the foul line in the ME.
|
||||||
-- GoldwaterRange:GetFoullineDistance("GWR Strafe Pit Left 1", "GWR Foul Line Left")
|
-- GoldwaterRange:GetFoullineDistance("GWR Strafe Pit Left 1", "GWR Foul Line Left")
|
||||||
@@ -358,6 +365,8 @@ RANGE = {
|
|||||||
targetpath = nil,
|
targetpath = nil,
|
||||||
targetprefix = nil,
|
targetprefix = nil,
|
||||||
Coalition = nil,
|
Coalition = nil,
|
||||||
|
ceilingaltitude = 20000,
|
||||||
|
ceilingenabled = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Default range parameters.
|
--- Default range parameters.
|
||||||
@@ -1085,6 +1094,37 @@ function RANGE:SetRangeZone( zone )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set range ceiling altitude in feet MSL.
|
||||||
|
-- @param #RANGE self
|
||||||
|
-- @param #number altitude (optional) Ceiling altitude of the range in ft MSL. Default 20000ft MSL
|
||||||
|
-- @return #RANGE self
|
||||||
|
function RANGE:SetRangeCeiling( altitude )
|
||||||
|
self:T(self.lid.."SetRangeCeiling")
|
||||||
|
if altitude and type(altitude) == "number" then
|
||||||
|
self.ceilingaltitude=altitude
|
||||||
|
else
|
||||||
|
self:E(self.lid.."Altitude either not provided or is not a number, using default setting (20000).")
|
||||||
|
self.ceilingaltitude=20000
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Enable range ceiling. Aircraft must be below the ceiling altitude to be considered in the range zone.
|
||||||
|
-- @param #RANGE self
|
||||||
|
-- @param #boolean enabled True if you would like to enable the ceiling check. If no value give, will Default to false.
|
||||||
|
-- @return #RANGE self
|
||||||
|
function RANGE:EnableRangeCeiling( enabled )
|
||||||
|
self:T(self.lid.."EnableRangeCeiling")
|
||||||
|
if enabled and type(enabled) == "boolean" then
|
||||||
|
self.ceilingenabled=enabled
|
||||||
|
else
|
||||||
|
self:E(self.lid.."Enabled either not provide or is not a boolean, using default setting (false).")
|
||||||
|
self.ceilingenabled=false
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set smoke color for marking bomb targets. By default bomb targets are marked by red smoke.
|
--- Set smoke color for marking bomb targets. By default bomb targets are marked by red smoke.
|
||||||
-- @param #RANGE self
|
-- @param #RANGE self
|
||||||
-- @param Utilities.Utils#SMOKECOLOR colorid Color id. Default `SMOKECOLOR.Red`.
|
-- @param Utilities.Utils#SMOKECOLOR colorid Color id. Default `SMOKECOLOR.Red`.
|
||||||
@@ -1893,7 +1933,7 @@ function RANGE:OnEventHit( EventData )
|
|||||||
local _currentTarget = self.strafeStatus[_unitID] --#RANGE.StrafeStatus
|
local _currentTarget = self.strafeStatus[_unitID] --#RANGE.StrafeStatus
|
||||||
|
|
||||||
-- Player has rolled in on a strafing target.
|
-- Player has rolled in on a strafing target.
|
||||||
if _currentTarget and target:IsAlive() then
|
if _currentTarget and target and target:IsAlive() then
|
||||||
|
|
||||||
local playerPos = _unit:GetCoordinate()
|
local playerPos = _unit:GetCoordinate()
|
||||||
local targetPos = target:GetCoordinate()
|
local targetPos = target:GetCoordinate()
|
||||||
@@ -2062,7 +2102,12 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
|
|||||||
result.attackHdg = attackHdg
|
result.attackHdg = attackHdg
|
||||||
result.attackVel = attackVel
|
result.attackVel = attackVel
|
||||||
result.attackAlt = attackAlt
|
result.attackAlt = attackAlt
|
||||||
result.date=os and os.date() or "n/a"
|
if os and os.date then
|
||||||
|
result.date=os.date()
|
||||||
|
else
|
||||||
|
self:E(self.lid.."os or os.date() not available")
|
||||||
|
result.date = "n/a"
|
||||||
|
end
|
||||||
|
|
||||||
-- Add to table.
|
-- Add to table.
|
||||||
table.insert( _results, result )
|
table.insert( _results, result )
|
||||||
@@ -3112,7 +3157,10 @@ function RANGE:_CheckPlayers()
|
|||||||
|
|
||||||
if unit and unit:IsAlive() then
|
if unit and unit:IsAlive() then
|
||||||
|
|
||||||
if unit:IsInZone( self.rangezone ) then
|
local unitalt = unit:GetAltitude(false)
|
||||||
|
local unitaltinfeet = UTILS.MetersToFeet(unitalt)
|
||||||
|
|
||||||
|
if unit:IsInZone(self.rangezone) and (not self.ceilingenabled or unitaltinfeet < self.ceilingaltitude) then
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
-- Player INSIDE Range Zone --
|
-- Player INSIDE Range Zone --
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
--
|
--
|
||||||
-- ### Authors: **applevangelist**, **FlightControl**
|
-- ### Authors: **applevangelist**, **FlightControl**
|
||||||
--
|
--
|
||||||
-- Last Update: Oct 2024
|
-- Last Update: Dec 2024
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -80,6 +80,7 @@ SEAD = {
|
|||||||
["AGM_122"] = "AGM_122",
|
["AGM_122"] = "AGM_122",
|
||||||
["AGM_84"] = "AGM_84",
|
["AGM_84"] = "AGM_84",
|
||||||
["AGM_45"] = "AGM_45",
|
["AGM_45"] = "AGM_45",
|
||||||
|
["AGM_65"] = "AGM_65",
|
||||||
["ALARM"] = "ALARM",
|
["ALARM"] = "ALARM",
|
||||||
["LD-10"] = "LD-10",
|
["LD-10"] = "LD-10",
|
||||||
["X_58"] = "X_58",
|
["X_58"] = "X_58",
|
||||||
@@ -99,6 +100,7 @@ SEAD = {
|
|||||||
-- km and mach
|
-- km and mach
|
||||||
["AGM_88"] = { 150, 3},
|
["AGM_88"] = { 150, 3},
|
||||||
["AGM_45"] = { 12, 2},
|
["AGM_45"] = { 12, 2},
|
||||||
|
["AGM_65"] = { 16, 0.9},
|
||||||
["AGM_122"] = { 16.5, 2.3},
|
["AGM_122"] = { 16.5, 2.3},
|
||||||
["AGM_84"] = { 280, 0.8},
|
["AGM_84"] = { 280, 0.8},
|
||||||
["ALARM"] = { 45, 2},
|
["ALARM"] = { 45, 2},
|
||||||
@@ -155,7 +157,7 @@ function SEAD:New( SEADGroupPrefixes, Padding )
|
|||||||
self:AddTransition("*", "ManageEvasion", "*")
|
self:AddTransition("*", "ManageEvasion", "*")
|
||||||
self:AddTransition("*", "CalculateHitZone", "*")
|
self:AddTransition("*", "CalculateHitZone", "*")
|
||||||
|
|
||||||
self:I("*** SEAD - Started Version 0.4.8")
|
self:I("*** SEAD - Started Version 0.4.9")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -468,6 +470,7 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
local SEADWeaponName = EventData.WeaponName or "None" -- return weapon type
|
local SEADWeaponName = EventData.WeaponName or "None" -- return weapon type
|
||||||
|
|
||||||
if self:_CheckHarms(SEADWeaponName) then
|
if self:_CheckHarms(SEADWeaponName) then
|
||||||
|
--UTILS.PrintTableToLog(EventData)
|
||||||
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
|
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
if not SEADPlane then return self end -- case IniUnit is empty
|
if not SEADPlane then return self end -- case IniUnit is empty
|
||||||
@@ -493,7 +496,7 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
if not _target or self.debug then -- AGM-88 or 154 w/o target data
|
if not _target or self.debug then -- AGM-88 or 154 w/o target data
|
||||||
self:E("***** SEAD - No target data for " .. (SEADWeaponName or "None"))
|
self:E("***** SEAD - No target data for " .. (SEADWeaponName or "None"))
|
||||||
if string.find(SEADWeaponName,"AGM_88",1,true) or string.find(SEADWeaponName,"AGM_154",1,true) then
|
if string.find(SEADWeaponName,"AGM_88",1,true) or string.find(SEADWeaponName,"AGM_154",1,true) then
|
||||||
self:I("**** Tracking AGM-88/154 with no target data.")
|
self:T("**** Tracking AGM-88/154 with no target data.")
|
||||||
local pos0 = SEADPlane:GetCoordinate()
|
local pos0 = SEADPlane:GetCoordinate()
|
||||||
local fheight = SEADPlane:GetHeight()
|
local fheight = SEADPlane:GetHeight()
|
||||||
self:__CalculateHitZone(20,SEADWeapon,pos0,fheight,SEADGroup,SEADWeaponName)
|
self:__CalculateHitZone(20,SEADWeapon,pos0,fheight,SEADGroup,SEADWeaponName)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
-- @image Functional.Shorad.jpg
|
-- @image Functional.Shorad.jpg
|
||||||
--
|
--
|
||||||
-- Date: Nov 2021
|
-- Date: Nov 2021
|
||||||
-- Last Update: Nov 2023
|
-- Last Update: Jan 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **SHORAD** class, extends Core.Base#BASE
|
--- **SHORAD** class, extends Core.Base#BASE
|
||||||
@@ -113,7 +113,7 @@ SHORAD = {
|
|||||||
SkateNumber = 3,
|
SkateNumber = 3,
|
||||||
SkateZones = nil,
|
SkateZones = nil,
|
||||||
minscootdist = 100,
|
minscootdist = 100,
|
||||||
minscootdist = 3000,
|
maxscootdist = 3000,
|
||||||
scootrandomcoord = false,
|
scootrandomcoord = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +443,9 @@ do
|
|||||||
for _,_groups in pairs (shoradset) do
|
for _,_groups in pairs (shoradset) do
|
||||||
local groupname = _groups:GetName()
|
local groupname = _groups:GetName()
|
||||||
if string.find(groupname, tgtgrp, 1, true) then
|
if string.find(groupname, tgtgrp, 1, true) then
|
||||||
returnname = true
|
if _groups:IsSAM() then
|
||||||
|
returnname = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return returnname
|
return returnname
|
||||||
@@ -470,6 +472,7 @@ do
|
|||||||
-- @param #number Radius Radius of the #ZONE
|
-- @param #number Radius Radius of the #ZONE
|
||||||
-- @param #number ActiveTimer Number of seconds to stay active
|
-- @param #number ActiveTimer Number of seconds to stay active
|
||||||
-- @param #number TargetCat (optional) Category, i.e. Object.Category.UNIT or Object.Category.STATIC
|
-- @param #number TargetCat (optional) Category, i.e. Object.Category.UNIT or Object.Category.STATIC
|
||||||
|
-- @param #boolean ShotAt If true, function is called after a shot
|
||||||
-- @return #SHORAD self
|
-- @return #SHORAD self
|
||||||
-- @usage Use this function to integrate with other systems, example
|
-- @usage Use this function to integrate with other systems, example
|
||||||
--
|
--
|
||||||
@@ -479,7 +482,7 @@ do
|
|||||||
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
||||||
-- mymantis:AddShorad(myshorad,720)
|
-- mymantis:AddShorad(myshorad,720)
|
||||||
-- mymantis:Start()
|
-- mymantis:Start()
|
||||||
function SHORAD:onafterWakeUpShorad(From, Event, To, TargetGroup, Radius, ActiveTimer, TargetCat)
|
function SHORAD:onafterWakeUpShorad(From, Event, To, TargetGroup, Radius, ActiveTimer, TargetCat, ShotAt)
|
||||||
self:T(self.lid .. " WakeUpShorad")
|
self:T(self.lid .. " WakeUpShorad")
|
||||||
self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
|
self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
|
||||||
local targetcat = TargetCat or Object.Category.UNIT
|
local targetcat = TargetCat or Object.Category.UNIT
|
||||||
@@ -521,7 +524,27 @@ do
|
|||||||
-- go through set and find the one(s) to activate
|
-- go through set and find the one(s) to activate
|
||||||
local TDiff = 4
|
local TDiff = 4
|
||||||
for _,_group in pairs (shoradset) do
|
for _,_group in pairs (shoradset) do
|
||||||
if _group:IsAnyInZone(targetzone) then
|
|
||||||
|
local groupname = _group:GetName()
|
||||||
|
|
||||||
|
if groupname == TargetGroup and ShotAt==true then
|
||||||
|
-- Shot at a SHORAD group
|
||||||
|
if self.UseEmOnOff then
|
||||||
|
_group:EnableEmission(false)
|
||||||
|
end
|
||||||
|
_group:OptionAlarmStateGreen()
|
||||||
|
self.ActiveGroups[groupname] = nil
|
||||||
|
local text = string.format("Shot at SHORAD %s! Evading!", _group:GetName())
|
||||||
|
self:T(text)
|
||||||
|
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
||||||
|
|
||||||
|
--Shoot and Scoot
|
||||||
|
if self.shootandscoot then
|
||||||
|
self:__ShootAndScoot(1,_group)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif _group:IsAnyInZone(targetzone) or groupname == TargetGroup then
|
||||||
|
-- shot at a group we protect
|
||||||
local text = string.format("Waking up SHORAD %s", _group:GetName())
|
local text = string.format("Waking up SHORAD %s", _group:GetName())
|
||||||
self:T(text)
|
self:T(text)
|
||||||
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
||||||
@@ -529,7 +552,6 @@ do
|
|||||||
_group:EnableEmission(true)
|
_group:EnableEmission(true)
|
||||||
end
|
end
|
||||||
_group:OptionAlarmStateRed()
|
_group:OptionAlarmStateRed()
|
||||||
local groupname = _group:GetName()
|
|
||||||
if self.ActiveGroups[groupname] == nil then -- no timer yet for this group
|
if self.ActiveGroups[groupname] == nil then -- no timer yet for this group
|
||||||
self.ActiveGroups[groupname] = { Timing = ActiveTimer }
|
self.ActiveGroups[groupname] = { Timing = ActiveTimer }
|
||||||
local endtime = timer.getTime() + (ActiveTimer * math.random(75,100) / 100 ) -- randomize wakeup a bit
|
local endtime = timer.getTime() + (ActiveTimer * math.random(75,100) / 100 ) -- randomize wakeup a bit
|
||||||
@@ -607,7 +629,7 @@ do
|
|||||||
_targetgroupname = tgtgrp:GetName() -- group name
|
_targetgroupname = tgtgrp:GetName() -- group name
|
||||||
_targetskill = tgtgrp:GetUnit(1):GetSkill()
|
_targetskill = tgtgrp:GetUnit(1):GetSkill()
|
||||||
self:T("*** Found Target = ".. _targetgroupname)
|
self:T("*** Found Target = ".. _targetgroupname)
|
||||||
self:WakeUpShorad(_targetgroupname, self.Radius, self.ActiveTimer, Object.Category.UNIT)
|
self:WakeUpShorad(_targetgroupname, self.Radius, self.ActiveTimer, Object.Category.UNIT,true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -736,7 +758,7 @@ do
|
|||||||
-- if being shot at, find closest SHORADs to activate
|
-- if being shot at, find closest SHORADs to activate
|
||||||
if shotatsams or shotatus then
|
if shotatsams or shotatus then
|
||||||
self:T({shotatsams=shotatsams,shotatus=shotatus})
|
self:T({shotatsams=shotatsams,shotatus=shotatus})
|
||||||
self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer, targetcat)
|
self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer, targetcat, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6047,7 +6047,7 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
if #parking<#template.units and not airstart then
|
if parking and #parking<#template.units and not airstart then
|
||||||
local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units)
|
local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units)
|
||||||
self:_DebugMessage(text)
|
self:_DebugMessage(text)
|
||||||
return nil
|
return nil
|
||||||
@@ -6089,7 +6089,7 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
|
|||||||
terminal=parking[i].TerminalID
|
terminal=parking[i].TerminalID
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Debug then
|
if self.Debug and terminal then
|
||||||
local text=string.format("Spawnplace unit %s terminal %d.", unit.name, terminal)
|
local text=string.format("Spawnplace unit %s terminal %d.", unit.name, terminal)
|
||||||
coord:MarkToAll(text)
|
coord:MarkToAll(text)
|
||||||
env.info(text)
|
env.info(text)
|
||||||
@@ -8122,9 +8122,11 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
|||||||
-- Debug output for occupied spots.
|
-- Debug output for occupied spots.
|
||||||
if self.Debug then
|
if self.Debug then
|
||||||
local coord=problem.coord --Core.Point#COORDINATE
|
local coord=problem.coord --Core.Point#COORDINATE
|
||||||
local text=string.format("Obstacle %s [type=%s] blocking spot=%d! Size=%.1f m and distance=%.1f m.", problem.name, problem.type, _termid, problem.size, problem.dist)
|
if coord then
|
||||||
self:I(self.lid..text)
|
local text=string.format("Obstacle %s [type=%s] blocking spot=%d! Size=%.1f m and distance=%.1f m.", problem.name, problem.type, _termid, problem.size, problem.dist)
|
||||||
coord:MarkToAll(string.format(text))
|
self:I(self.lid..text)
|
||||||
|
coord:MarkToAll(text)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
self:T(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid))
|
self:T(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ _SCHEDULEDISPATCHER = SCHEDULEDISPATCHER:New() -- Core.ScheduleDispatcher#SCHEDU
|
|||||||
_DATABASE = DATABASE:New() -- Core.Database#DATABASE
|
_DATABASE = DATABASE:New() -- Core.Database#DATABASE
|
||||||
|
|
||||||
--- Settings
|
--- Settings
|
||||||
_SETTINGS = SETTINGS:Set()
|
_SETTINGS = SETTINGS:Set() -- Core.Settings#SETTINGS
|
||||||
_SETTINGS:SetPlayerMenuOn()
|
_SETTINGS:SetPlayerMenuOn()
|
||||||
|
|
||||||
--- Register cargos.
|
--- Register cargos.
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Enums.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Enums.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Utils.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Utils.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Profiler.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Profiler.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Templates.lua' )
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/STTS.lua' )
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/FiFo.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/FiFo.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Socket.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Socket.lua' )
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
-- * Option to present information in imperial or metric units
|
-- * Option to present information in imperial or metric units
|
||||||
-- * Runway length and airfield elevation (optional)
|
-- * Runway length and airfield elevation (optional)
|
||||||
-- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, PRMG, RSBN) (optional)
|
-- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, PRMG, RSBN) (optional)
|
||||||
-- * SRS Simple-Text-To-Speech (STTS) integration (no sound files necessary)
|
-- * SRS Simple-Text-To-Speech (MSRS) integration (no sound files necessary)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -501,6 +501,7 @@ ATIS.Alphabet = {
|
|||||||
-- @field #number Kola +15° (East).
|
-- @field #number Kola +15° (East).
|
||||||
-- @field #number Afghanistan +3° (East).
|
-- @field #number Afghanistan +3° (East).
|
||||||
-- @field #number Iraq +4.4° (East).
|
-- @field #number Iraq +4.4° (East).
|
||||||
|
-- @field #number GermanyCW +0.1° (East).
|
||||||
ATIS.RunwayM2T = {
|
ATIS.RunwayM2T = {
|
||||||
Caucasus = 0,
|
Caucasus = 0,
|
||||||
Nevada = 12,
|
Nevada = 12,
|
||||||
@@ -513,7 +514,8 @@ ATIS.RunwayM2T = {
|
|||||||
SinaiMap = 5,
|
SinaiMap = 5,
|
||||||
Kola = 15,
|
Kola = 15,
|
||||||
Afghanistan = 3,
|
Afghanistan = 3,
|
||||||
Iraq=4.4
|
Iraq=4.4,
|
||||||
|
GermanyCW=0.1,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Whether ICAO phraseology is used for ATIS broadcasts.
|
--- Whether ICAO phraseology is used for ATIS broadcasts.
|
||||||
@@ -530,6 +532,7 @@ ATIS.RunwayM2T = {
|
|||||||
-- @field #boolean Kola true.
|
-- @field #boolean Kola true.
|
||||||
-- @field #boolean Afghanistan true.
|
-- @field #boolean Afghanistan true.
|
||||||
-- @field #boolean Iraq true.
|
-- @field #boolean Iraq true.
|
||||||
|
-- @field #boolean GermanyCW true.
|
||||||
ATIS.ICAOPhraseology = {
|
ATIS.ICAOPhraseology = {
|
||||||
Caucasus = true,
|
Caucasus = true,
|
||||||
Nevada = false,
|
Nevada = false,
|
||||||
@@ -543,6 +546,7 @@ ATIS.ICAOPhraseology = {
|
|||||||
Kola = true,
|
Kola = true,
|
||||||
Afghanistan = true,
|
Afghanistan = true,
|
||||||
Iraq = true,
|
Iraq = true,
|
||||||
|
GermanyCW = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Nav point data.
|
--- Nav point data.
|
||||||
@@ -2049,12 +2053,14 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
local sunrise = coord:GetSunrise()
|
local sunrise = coord:GetSunrise()
|
||||||
--self:I(sunrise)
|
--self:I(sunrise)
|
||||||
local SUNRISE = "no time"
|
local SUNRISE = "no time"
|
||||||
|
local NorthPolar = true
|
||||||
if tostring(sunrise) ~= "N/S" and tostring(sunrise) ~= "N/R" then
|
if tostring(sunrise) ~= "N/S" and tostring(sunrise) ~= "N/R" then
|
||||||
sunrise = UTILS.Split( sunrise, ":" )
|
sunrise = UTILS.Split( sunrise, ":" )
|
||||||
SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] )
|
SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] )
|
||||||
if self.useSRS then
|
if self.useSRS then
|
||||||
SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours )
|
SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours )
|
||||||
end
|
end
|
||||||
|
NorthPolar = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local sunset = coord:GetSunset()
|
local sunset = coord:GetSunset()
|
||||||
@@ -2066,6 +2072,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
if self.useSRS then
|
if self.useSRS then
|
||||||
SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours )
|
SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours )
|
||||||
end
|
end
|
||||||
|
NorthPolar = false
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------
|
---------------------------------
|
||||||
@@ -2405,7 +2412,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
local sunrise = self.gettext:GetEntry("SUNRISEAT",self.locale)
|
local sunrise = self.gettext:GetEntry("SUNRISEAT",self.locale)
|
||||||
--subtitle = string.format( "Sunrise at %s local time", SUNRISE )
|
--subtitle = string.format( "Sunrise at %s local time", SUNRISE )
|
||||||
subtitle = string.format( sunrise, SUNRISE )
|
subtitle = string.format( sunrise, SUNRISE )
|
||||||
if not self.useSRS then
|
if not self.useSRS and NorthPolar == false then
|
||||||
self:Transmission( self.Sound.SunriseAt, 0.5, subtitle )
|
self:Transmission( self.Sound.SunriseAt, 0.5, subtitle )
|
||||||
self.radioqueue:Number2Transmission( SUNRISE, nil, 0.2 )
|
self.radioqueue:Number2Transmission( SUNRISE, nil, 0.2 )
|
||||||
self:Transmission( self.Sound.TimeLocal, 0.2 )
|
self:Transmission( self.Sound.TimeLocal, 0.2 )
|
||||||
@@ -2416,7 +2423,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
local sunset = self.gettext:GetEntry("SUNSETAT",self.locale)
|
local sunset = self.gettext:GetEntry("SUNSETAT",self.locale)
|
||||||
--subtitle = string.format( "Sunset at %s local time", SUNSET )
|
--subtitle = string.format( "Sunset at %s local time", SUNSET )
|
||||||
subtitle = string.format( sunset, SUNSET )
|
subtitle = string.format( sunset, SUNSET )
|
||||||
if not self.useSRS then
|
if not self.useSRS and NorthPolar == false then
|
||||||
self:Transmission( self.Sound.SunsetAt, 0.5, subtitle )
|
self:Transmission( self.Sound.SunsetAt, 0.5, subtitle )
|
||||||
self.radioqueue:Number2Transmission( SUNSET, nil, 0.5 )
|
self.radioqueue:Number2Transmission( SUNSET, nil, 0.5 )
|
||||||
self:Transmission( self.Sound.TimeLocal, 0.2 )
|
self:Transmission( self.Sound.TimeLocal, 0.2 )
|
||||||
@@ -2791,7 +2798,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
|
|
||||||
end
|
end
|
||||||
_RUNACT = subtitle
|
_RUNACT = subtitle
|
||||||
alltext = alltext .. ";\n" .. subtitle
|
--alltext = alltext .. ";\n" .. subtitle
|
||||||
|
|
||||||
-- Runway length.
|
-- Runway length.
|
||||||
if self.rwylength then
|
if self.rwylength then
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_\(CVN-73\)) (CVN-73) [Super Carrier Module]
|
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_\(CVN-73\)) (CVN-73) [Super Carrier Module]
|
||||||
-- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module]
|
-- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module]
|
||||||
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_\(CV-59\)) (CV-59) [Heatblur Carrier Module]
|
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_\(CV-59\)) (CV-59) [Heatblur Carrier Module]
|
||||||
|
-- * [Essex Class](https://en.wikipedia.org/wiki/Essex-class_aircraft_carrier) (CV-11) [Magnitude 3 Carrier Module]
|
||||||
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_\(R12\)) (R12)
|
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_\(R12\)) (R12)
|
||||||
-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_\(R05\)) (R05)
|
-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_\(R05\)) (R05)
|
||||||
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_\(LHA-1\)) (LHA-1)
|
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_\(LHA-1\)) (LHA-1)
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI)
|
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI)
|
||||||
-- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI)
|
-- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI)
|
||||||
-- * [FE/A-18E/F/G Superhornet](https://forum.dcs.world/topic/316971-cjs-super-hornet-community-mod-v20-official-thread/) (CJS mod) (Player & AI)
|
-- * [FE/A-18E/F/G Superhornet](https://forum.dcs.world/topic/316971-cjs-super-hornet-community-mod-v20-official-thread/) (CJS mod) (Player & AI)
|
||||||
|
-- * [F4U-1D Corsair](https://forum.dcs.world/forum/781-f4u-1d/) (Player & AI)
|
||||||
-- * F/A-18C Hornet (AI)
|
-- * F/A-18C Hornet (AI)
|
||||||
-- * F-14A Tomcat (AI)
|
-- * F-14A Tomcat (AI)
|
||||||
-- * E-2D Hawkeye (AI)
|
-- * E-2D Hawkeye (AI)
|
||||||
@@ -1283,6 +1285,8 @@ AIRBOSS = {
|
|||||||
-- @field #string RHINOE F/A-18E Superhornet (mod).
|
-- @field #string RHINOE F/A-18E Superhornet (mod).
|
||||||
-- @field #string RHINOF F/A-18F Superhornet (mod).
|
-- @field #string RHINOF F/A-18F Superhornet (mod).
|
||||||
-- @field #string GROWLER FEA-18G Superhornet (mod).
|
-- @field #string GROWLER FEA-18G Superhornet (mod).
|
||||||
|
-- @field #string CORSAIR F4U-1D Corsair.
|
||||||
|
-- @field #string CORSAIR_CW F4U-1D Corsair Mk.4 (clipped wing).
|
||||||
AIRBOSS.AircraftCarrier={
|
AIRBOSS.AircraftCarrier={
|
||||||
AV8B="AV8BNA",
|
AV8B="AV8BNA",
|
||||||
HORNET="FA-18C_hornet",
|
HORNET="FA-18C_hornet",
|
||||||
@@ -1299,6 +1303,8 @@ AIRBOSS.AircraftCarrier={
|
|||||||
RHINOE="FA-18E",
|
RHINOE="FA-18E",
|
||||||
RHINOF="FA-18F",
|
RHINOF="FA-18F",
|
||||||
GROWLER="EA-18G",
|
GROWLER="EA-18G",
|
||||||
|
CORSAIR="F4U-1D",
|
||||||
|
CORSAIR_CW="F4U-1D CW",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Carrier types.
|
--- Carrier types.
|
||||||
@@ -1310,6 +1316,7 @@ AIRBOSS.AircraftCarrier={
|
|||||||
-- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module]
|
-- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module]
|
||||||
-- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module]
|
-- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module]
|
||||||
-- @field #string VINSON USS Carl Vinson (CVN-70) [Deprecated!]
|
-- @field #string VINSON USS Carl Vinson (CVN-70) [Deprecated!]
|
||||||
|
-- @field #string ESSEX Essex class carrier (e.g. USS Yorktown (CV-10)) [Magnitude 3 Carrier Module]
|
||||||
-- @field #string HERMES HMS Hermes (R12) [V/STOL Carrier]
|
-- @field #string HERMES HMS Hermes (R12) [V/STOL Carrier]
|
||||||
-- @field #string INVINCIBLE HMS Invincible (R05) [V/STOL Carrier]
|
-- @field #string INVINCIBLE HMS Invincible (R05) [V/STOL Carrier]
|
||||||
-- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier]
|
-- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier]
|
||||||
@@ -1325,6 +1332,7 @@ AIRBOSS.CarrierType = {
|
|||||||
STENNIS = "Stennis",
|
STENNIS = "Stennis",
|
||||||
FORRESTAL = "Forrestal",
|
FORRESTAL = "Forrestal",
|
||||||
VINSON = "VINSON",
|
VINSON = "VINSON",
|
||||||
|
ESSEX = "Essex",
|
||||||
HERMES = "HERMES81",
|
HERMES = "HERMES81",
|
||||||
INVINCIBLE = "hms_invincible",
|
INVINCIBLE = "hms_invincible",
|
||||||
TARAWA = "LHA_Tarawa",
|
TARAWA = "LHA_Tarawa",
|
||||||
@@ -1731,10 +1739,10 @@ AIRBOSS.Difficulty = {
|
|||||||
-- @field #table trapsheet Groove data table recorded every 0.5 seconds.
|
-- @field #table trapsheet Groove data table recorded every 0.5 seconds.
|
||||||
-- @field #boolean trapon If true, save trap sheets.
|
-- @field #boolean trapon If true, save trap sheets.
|
||||||
-- @field #string debriefschedulerID Debrief scheduler ID.
|
-- @field #string debriefschedulerID Debrief scheduler ID.
|
||||||
--
|
--
|
||||||
-- @field Sound.SRS#MSRS SRS
|
-- @field Sound.SRS#MSRS SRS
|
||||||
-- @field Sound.SRS#MSRSQUEUE SRSQ
|
-- @field Sound.SRS#MSRSQUEUE SRSQ
|
||||||
--
|
--
|
||||||
-- @extends #AIRBOSS.FlightGroup
|
-- @extends #AIRBOSS.FlightGroup
|
||||||
|
|
||||||
--- Main group level radio menu: F10 Other/Airboss.
|
--- Main group level radio menu: F10 Other/Airboss.
|
||||||
@@ -1747,7 +1755,7 @@ AIRBOSS.MenuF10Root = nil
|
|||||||
|
|
||||||
--- Airboss class version.
|
--- Airboss class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AIRBOSS.version = "1.3.3"
|
AIRBOSS.version = "1.4.0"
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -1912,6 +1920,9 @@ function AIRBOSS:New( carriername, alias )
|
|||||||
-- Set max section members. Default 2.
|
-- Set max section members. Default 2.
|
||||||
self:SetMaxSectionSize()
|
self:SetMaxSectionSize()
|
||||||
|
|
||||||
|
-- Set max section distance. Default 100 meters.
|
||||||
|
self:SetMaxSectionDistance()
|
||||||
|
|
||||||
-- Set max flights per stack. Default is 2.
|
-- Set max flights per stack. Default is 2.
|
||||||
self:SetMaxFlightsPerStack()
|
self:SetMaxFlightsPerStack()
|
||||||
|
|
||||||
@@ -2010,6 +2021,8 @@ function AIRBOSS:New( carriername, alias )
|
|||||||
elseif self.carriertype == AIRBOSS.CarrierType.VINSON then
|
elseif self.carriertype == AIRBOSS.CarrierType.VINSON then
|
||||||
-- Carl Vinson is legacy now.
|
-- Carl Vinson is legacy now.
|
||||||
self:_InitStennis()
|
self:_InitStennis()
|
||||||
|
elseif self.carriertype == AIRBOSS.CarrierType.ESSEX then
|
||||||
|
self:_InitEssex()
|
||||||
elseif self.carriertype == AIRBOSS.CarrierType.HERMES then
|
elseif self.carriertype == AIRBOSS.CarrierType.HERMES then
|
||||||
-- Hermes parameters.
|
-- Hermes parameters.
|
||||||
self:_InitHermes()
|
self:_InitHermes()
|
||||||
@@ -2539,7 +2552,7 @@ function AIRBOSS:AddRecoveryWindow( starttime, stoptime, case, holdingoffset, tu
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
if Tstop <= Tnow then
|
if Tstop <= Tnow then
|
||||||
string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) )
|
string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2863,23 +2876,28 @@ end
|
|||||||
function AIRBOSS:SetGlideslopeErrorThresholds(_max,_min, High, HIGH, Low, LOW)
|
function AIRBOSS:SetGlideslopeErrorThresholds(_max,_min, High, HIGH, Low, LOW)
|
||||||
|
|
||||||
--Check if V/STOL Carrier
|
--Check if V/STOL Carrier
|
||||||
if self.carriertype == AIRBOSS.CarrierType.INVINCIBLE or self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
|
if self.carriertype == AIRBOSS.CarrierType.INVINCIBLE or
|
||||||
|
self.carriertype == AIRBOSS.CarrierType.HERMES or
|
||||||
|
self.carriertype == AIRBOSS.CarrierType.TARAWA or
|
||||||
|
self.carriertype == AIRBOSS.CarrierType.AMERICA or
|
||||||
|
self.carriertype == AIRBOSS.CarrierType.JCARLOS or
|
||||||
|
self.carriertype == AIRBOSS.CarrierType.CANBERRA then
|
||||||
|
|
||||||
-- allow a larger GSE for V/STOL operations --Pene Testing
|
-- allow a larger GSE for V/STOL operations --Pene Testing
|
||||||
self.gle._max=_max or 0.7
|
self.gle._max=_max or 0.7
|
||||||
self.gle.High=High or 1.4
|
self.gle.High=High or 1.4
|
||||||
self.gle.HIGH=HIGH or 1.9
|
self.gle.HIGH=HIGH or 1.9
|
||||||
self.gle._min=_min or -0.5
|
self.gle._min=_min or -0.5
|
||||||
self.gle.Low=Low or -1.2
|
self.gle.Low=Low or -1.2
|
||||||
self.gle.LOW=LOW or -1.5
|
self.gle.LOW=LOW or -1.5
|
||||||
-- CVN values
|
|
||||||
else
|
else
|
||||||
self.gle._max=_max or 0.4
|
-- CVN values
|
||||||
self.gle.High=High or 0.8
|
self.gle._max=_max or 0.4
|
||||||
self.gle.HIGH=HIGH or 1.5
|
self.gle.High=High or 0.8
|
||||||
self.gle._min=_min or -0.3
|
self.gle.HIGH=HIGH or 1.5
|
||||||
self.gle.Low=Low or -0.6
|
self.gle._min=_min or -0.3
|
||||||
self.gle.LOW=LOW or -0.9
|
self.gle.Low=Low or -0.6
|
||||||
|
self.gle.LOW=LOW or -0.9
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -3066,7 +3084,7 @@ end
|
|||||||
-- @param #number Port Port of the SRS server, defaults to 5002.
|
-- @param #number Port Port of the SRS server, defaults to 5002.
|
||||||
-- @param #string Culture (Optional, Airboss Culture) Culture, defaults to "en-US".
|
-- @param #string Culture (Optional, Airboss Culture) Culture, defaults to "en-US".
|
||||||
-- @param #string Gender (Optional, Airboss Gender) Gender, e.g. "male" or "female". Defaults to "male".
|
-- @param #string Gender (Optional, Airboss Gender) Gender, e.g. "male" or "female". Defaults to "male".
|
||||||
-- @param #string Voice (Optional, Airboss Voice) Set to use a specific voice. Will **override gender and culture** settings.
|
-- @param #string Voice (Optional, Airboss Voice) Set to use a specific voice. Will **override gender and culture** settings.
|
||||||
-- @param #string GoogleCreds (Optional) Path to Google credentials, e.g. "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourgooglekey.json".
|
-- @param #string GoogleCreds (Optional) Path to Google credentials, e.g. "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourgooglekey.json".
|
||||||
-- @param #number Volume (Optional) E.g. 0.75. Defaults to 1.0 (loudest).
|
-- @param #number Volume (Optional) E.g. 0.75. Defaults to 1.0 (loudest).
|
||||||
-- @param #table AltBackend (Optional) See MSRS for details.
|
-- @param #table AltBackend (Optional) See MSRS for details.
|
||||||
@@ -3097,10 +3115,10 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum
|
|||||||
-- SRSQUEUE
|
-- SRSQUEUE
|
||||||
self.SRSQ = MSRSQUEUE:New("AIRBOSS")
|
self.SRSQ = MSRSQUEUE:New("AIRBOSS")
|
||||||
self.SRSQ:SetTransmitOnlyWithPlayers(true)
|
self.SRSQ:SetTransmitOnlyWithPlayers(true)
|
||||||
if not self.PilotRadio then
|
if not self.PilotRadio then
|
||||||
self:SetSRSPilotVoice()
|
self:SetSRSPilotVoice()
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM.
|
--- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM.
|
||||||
@@ -3343,6 +3361,22 @@ function AIRBOSS:SetMaxSectionSize( nmax )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set maximum distance up to which section members are allowed (default: 100 meters).
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #number dmax Max distance in meters (default 100 m). Minimum is 10 m, maximum is 5000 m.
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:SetMaxSectionDistance( dmax )
|
||||||
|
if dmax then
|
||||||
|
if dmax < 10 then
|
||||||
|
dmax = 10
|
||||||
|
elseif dmax > 5000 then
|
||||||
|
dmax = 5000
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.maxsectiondistance = dmax or 100
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set max number of flights per stack. All members of a section count as one "flight".
|
--- Set max number of flights per stack. All members of a section count as one "flight".
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #number nmax Number of max allowed flights per stack. Default is two. Minimum is one, maximum is 4.
|
-- @param #number nmax Number of max allowed flights per stack. Default is two. Minimum is one, maximum is 4.
|
||||||
@@ -4608,6 +4642,51 @@ function AIRBOSS:_InitForrestal()
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Init parameters for Essec class carriers.
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
function AIRBOSS:_InitEssex()
|
||||||
|
|
||||||
|
-- Init Nimitz as default.
|
||||||
|
self:_InitNimitz()
|
||||||
|
|
||||||
|
-- Carrier Parameters.
|
||||||
|
self.carrierparam.sterndist = -126
|
||||||
|
self.carrierparam.deckheight = 19.27 --DCS World\CoreMods\tech\M3 WWII PTO units\Database\Essex_Class_Carrier_1944.lua
|
||||||
|
|
||||||
|
-- Total size of the carrier (approx as rectangle).
|
||||||
|
self.carrierparam.totlength = 268
|
||||||
|
self.carrierparam.totwidthport = 23
|
||||||
|
self.carrierparam.totwidthstarboard = 23
|
||||||
|
|
||||||
|
-- Landing runway.
|
||||||
|
self.carrierparam.rwyangle = 0.0
|
||||||
|
self.carrierparam.rwylength = 265
|
||||||
|
self.carrierparam.rwywidth = 20
|
||||||
|
|
||||||
|
-- Wires.
|
||||||
|
self.carrierparam.wire1 = 21.9
|
||||||
|
self.carrierparam.wire2 = 28.3
|
||||||
|
self.carrierparam.wire3 = 34.7
|
||||||
|
self.carrierparam.wire4 = 41.1
|
||||||
|
self.carrierparam.wire5 = 47.4
|
||||||
|
self.carrierparam.wire6 = 53.7
|
||||||
|
self.carrierparam.wire7 = 59.0
|
||||||
|
|
||||||
|
self.carrierparam.wire8 = 64.1
|
||||||
|
self.carrierparam.wire9 = 72.7
|
||||||
|
self.carrierparam.wire10 = 78.0
|
||||||
|
self.carrierparam.wire11 = 85.5
|
||||||
|
|
||||||
|
self.carrierparam.wire12 = 105.9
|
||||||
|
self.carrierparam.wire13 = 113.3
|
||||||
|
self.carrierparam.wire14 = 121.0
|
||||||
|
self.carrierparam.wire15 = 128.5
|
||||||
|
|
||||||
|
-- Landing distance.
|
||||||
|
self.carrierparam.landingdist = self.carrierparam.sterndist+self.carrierparam.wire3
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Init parameters for R12 HMS Hermes carrier.
|
--- Init parameters for R12 HMS Hermes carrier.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
function AIRBOSS:_InitHermes()
|
function AIRBOSS:_InitHermes()
|
||||||
@@ -5310,7 +5389,8 @@ function AIRBOSS:_GetAircraftAoA( playerData )
|
|||||||
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
||||||
local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC
|
local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC
|
||||||
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
||||||
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
||||||
|
local corsair = playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR or playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR_CW
|
||||||
|
|
||||||
-- Table with AoA values.
|
-- Table with AoA values.
|
||||||
local aoa = {} -- #AIRBOSS.AircraftAoA
|
local aoa = {} -- #AIRBOSS.AircraftAoA
|
||||||
@@ -5355,7 +5435,6 @@ function AIRBOSS:_GetAircraftAoA( playerData )
|
|||||||
aoa.Fast = 8.25 -- =17.5/2
|
aoa.Fast = 8.25 -- =17.5/2
|
||||||
aoa.FAST = 8.00 -- =16.5/2
|
aoa.FAST = 8.00 -- =16.5/2
|
||||||
elseif harrier then
|
elseif harrier then
|
||||||
|
|
||||||
-- AV-8B Harrier parameters. Tuning done on the Fast AoA to allow for abeam and ninety at Nozzles 55. Pene testing
|
-- AV-8B Harrier parameters. Tuning done on the Fast AoA to allow for abeam and ninety at Nozzles 55. Pene testing
|
||||||
aoa.SLOW = 16.0
|
aoa.SLOW = 16.0
|
||||||
aoa.Slow = 13.5
|
aoa.Slow = 13.5
|
||||||
@@ -5364,7 +5443,15 @@ function AIRBOSS:_GetAircraftAoA( playerData )
|
|||||||
aoa.OnSpeedMin = 9.5
|
aoa.OnSpeedMin = 9.5
|
||||||
aoa.Fast = 8.0
|
aoa.Fast = 8.0
|
||||||
aoa.FAST = 7.5
|
aoa.FAST = 7.5
|
||||||
|
elseif corsair then
|
||||||
|
-- F4U-1D Corsair parameters.
|
||||||
|
aoa.SLOW = 16.0
|
||||||
|
aoa.Slow = 13.5
|
||||||
|
aoa.OnSpeedMax = 12.5
|
||||||
|
aoa.OnSpeed = 10.0
|
||||||
|
aoa.OnSpeedMin = 9.5
|
||||||
|
aoa.Fast = 8.0
|
||||||
|
aoa.FAST = 7.5
|
||||||
end
|
end
|
||||||
|
|
||||||
return aoa
|
return aoa
|
||||||
@@ -5477,6 +5564,7 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
||||||
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
||||||
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
||||||
|
local corsair = playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR or playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR_CW
|
||||||
|
|
||||||
-- Return values.
|
-- Return values.
|
||||||
local alt
|
local alt
|
||||||
@@ -5536,6 +5624,9 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
elseif goshawk then
|
elseif goshawk then
|
||||||
alt = UTILS.FeetToMeters( 800 )
|
alt = UTILS.FeetToMeters( 800 )
|
||||||
speed = UTILS.KnotsToMps( 300 )
|
speed = UTILS.KnotsToMps( 300 )
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 300 )
|
||||||
|
speed = UTILS.KnotsToMps( 120 )
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif step == AIRBOSS.PatternStep.BREAKENTRY then
|
elseif step == AIRBOSS.PatternStep.BREAKENTRY then
|
||||||
@@ -5549,6 +5640,9 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
elseif goshawk then
|
elseif goshawk then
|
||||||
alt = UTILS.FeetToMeters( 800 )
|
alt = UTILS.FeetToMeters( 800 )
|
||||||
speed = UTILS.KnotsToMps( 300 )
|
speed = UTILS.KnotsToMps( 300 )
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 200 )
|
||||||
|
speed = UTILS.KnotsToMps( 110 )
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif step == AIRBOSS.PatternStep.EARLYBREAK then
|
elseif step == AIRBOSS.PatternStep.EARLYBREAK then
|
||||||
@@ -5557,6 +5651,9 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
alt = UTILS.FeetToMeters( 800 )
|
alt = UTILS.FeetToMeters( 800 )
|
||||||
elseif skyhawk then
|
elseif skyhawk then
|
||||||
alt = UTILS.FeetToMeters( 600 )
|
alt = UTILS.FeetToMeters( 600 )
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 200 )
|
||||||
|
speed = UTILS.KnotsToMps( 100 )
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif step == AIRBOSS.PatternStep.LATEBREAK then
|
elseif step == AIRBOSS.PatternStep.LATEBREAK then
|
||||||
@@ -5565,6 +5662,9 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
alt = UTILS.FeetToMeters( 800 )
|
alt = UTILS.FeetToMeters( 800 )
|
||||||
elseif skyhawk then
|
elseif skyhawk then
|
||||||
alt = UTILS.FeetToMeters( 600 )
|
alt = UTILS.FeetToMeters( 600 )
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 150 )
|
||||||
|
speed = UTILS.KnotsToMps( 100 )
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif step == AIRBOSS.PatternStep.ABEAM then
|
elseif step == AIRBOSS.PatternStep.ABEAM then
|
||||||
@@ -5573,6 +5673,9 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
alt = UTILS.FeetToMeters( 600 )
|
alt = UTILS.FeetToMeters( 600 )
|
||||||
elseif skyhawk then
|
elseif skyhawk then
|
||||||
alt = UTILS.FeetToMeters( 500 )
|
alt = UTILS.FeetToMeters( 500 )
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 150 )
|
||||||
|
speed = UTILS.KnotsToMps( 90 )
|
||||||
end
|
end
|
||||||
|
|
||||||
aoa = aoaac.OnSpeed
|
aoa = aoaac.OnSpeed
|
||||||
@@ -5597,6 +5700,9 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
alt = UTILS.FeetToMeters( 500 )
|
alt = UTILS.FeetToMeters( 500 )
|
||||||
elseif harrier then
|
elseif harrier then
|
||||||
alt = UTILS.FeetToMeters( 425 )
|
alt = UTILS.FeetToMeters( 425 )
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 90 )
|
||||||
|
speed = UTILS.KnotsToMps( 90 )
|
||||||
end
|
end
|
||||||
|
|
||||||
aoa = aoaac.OnSpeed
|
aoa = aoaac.OnSpeed
|
||||||
@@ -5609,6 +5715,8 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
alt = UTILS.FeetToMeters( 430 ) -- Tomcat should be a bit higher as it intercepts the GS a bit higher.
|
alt = UTILS.FeetToMeters( 430 ) -- Tomcat should be a bit higher as it intercepts the GS a bit higher.
|
||||||
elseif skyhawk then
|
elseif skyhawk then
|
||||||
alt = UTILS.FeetToMeters( 370 ) -- ?
|
alt = UTILS.FeetToMeters( 370 ) -- ?
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 80 )
|
||||||
end
|
end
|
||||||
-- Harrier wont get into wake pos. Runway is not angled and it stays port.
|
-- Harrier wont get into wake pos. Runway is not angled and it stays port.
|
||||||
|
|
||||||
@@ -5624,6 +5732,8 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
alt = UTILS.FeetToMeters( 300 ) -- ?
|
alt = UTILS.FeetToMeters( 300 ) -- ?
|
||||||
elseif harrier then
|
elseif harrier then
|
||||||
alt=UTILS.FeetToMeters(312)-- 300-325 ft
|
alt=UTILS.FeetToMeters(312)-- 300-325 ft
|
||||||
|
elseif corsair then
|
||||||
|
alt = UTILS.FeetToMeters( 80 )
|
||||||
end
|
end
|
||||||
|
|
||||||
aoa = aoaac.OnSpeed
|
aoa = aoaac.OnSpeed
|
||||||
@@ -6500,6 +6610,8 @@ function AIRBOSS:_LandAI( flight )
|
|||||||
Speed = UTILS.KnotsToKmph( 175 )
|
Speed = UTILS.KnotsToKmph( 175 )
|
||||||
elseif flight.actype == AIRBOSS.AircraftCarrier.S3B or flight.actype == AIRBOSS.AircraftCarrier.S3BTANKER then
|
elseif flight.actype == AIRBOSS.AircraftCarrier.S3B or flight.actype == AIRBOSS.AircraftCarrier.S3BTANKER then
|
||||||
Speed = UTILS.KnotsToKmph( 140 )
|
Speed = UTILS.KnotsToKmph( 140 )
|
||||||
|
elseif flight.actype == AIRBOSS.AircraftCarrier.CORSAIR or flight.actype == AIRBOSS.AircraftCarrier.CORSAIR_CW then
|
||||||
|
Speed = UTILS.KnotsToKmph( 100 )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Carrier position.
|
-- Carrier position.
|
||||||
@@ -8722,13 +8834,13 @@ function AIRBOSS:OnEventRemoveUnit( EventData )
|
|||||||
|
|
||||||
-- Nil checks.
|
-- Nil checks.
|
||||||
if EventData == nil then
|
if EventData == nil then
|
||||||
self:E( self.lid .. "ERROR: EventData=nil in event REMOVEUNIT!" )
|
self:T( self.lid .. "ERROR: EventData=nil in event REMOVEUNIT!" )
|
||||||
self:E( EventData )
|
self:T( EventData )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if EventData.IniUnit == nil then
|
if EventData.IniUnit == nil then
|
||||||
self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event REMOVEUNIT!" )
|
self:T( self.lid .. "ERROR: EventData.IniUnit=nil in event REMOVEUNIT!" )
|
||||||
self:E( EventData )
|
self:T( EventData )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -10295,6 +10407,9 @@ function AIRBOSS:_GetSternCoord()
|
|||||||
elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then
|
elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then
|
||||||
-- Forrestal
|
-- Forrestal
|
||||||
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7.5, FB + 90, true, true )
|
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7.5, FB + 90, true, true )
|
||||||
|
elseif self.carriertype == AIRBOSS.CarrierType.ESSEX then
|
||||||
|
-- Forrestal
|
||||||
|
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( -1, FB + 90, true, true )
|
||||||
else
|
else
|
||||||
-- Nimitz SC: translate 8 meters starboard wrt Final bearing.
|
-- Nimitz SC: translate 8 meters starboard wrt Final bearing.
|
||||||
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 9.5, FB + 90, true, true )
|
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 9.5, FB + 90, true, true )
|
||||||
@@ -11596,7 +11711,7 @@ function AIRBOSS:GetHeadingIntoWind_old( vdeck, magnetic, coord )
|
|||||||
local function adjustDegreesForWindSpeed(windSpeed)
|
local function adjustDegreesForWindSpeed(windSpeed)
|
||||||
local degreesAdjustment = 0
|
local degreesAdjustment = 0
|
||||||
-- the windspeeds are in m/s
|
-- the windspeeds are in m/s
|
||||||
|
|
||||||
-- +0 degrees at 15m/s = 37kts
|
-- +0 degrees at 15m/s = 37kts
|
||||||
-- +0 degrees at 14m/s = 35kts
|
-- +0 degrees at 14m/s = 35kts
|
||||||
-- +0 degrees at 13m/s = 33kts
|
-- +0 degrees at 13m/s = 33kts
|
||||||
@@ -11611,7 +11726,7 @@ function AIRBOSS:GetHeadingIntoWind_old( vdeck, magnetic, coord )
|
|||||||
-- +20 degrees at 4m/s = 26kts
|
-- +20 degrees at 4m/s = 26kts
|
||||||
-- +20 degrees at 3m/s = 26kts
|
-- +20 degrees at 3m/s = 26kts
|
||||||
-- +30 degrees at 2m/s = 26kts 1s
|
-- +30 degrees at 2m/s = 26kts 1s
|
||||||
|
|
||||||
if windSpeed > 0 and windSpeed < 3 then
|
if windSpeed > 0 and windSpeed < 3 then
|
||||||
degreesAdjustment = 30
|
degreesAdjustment = 30
|
||||||
elseif windSpeed >= 3 and windSpeed < 5 then
|
elseif windSpeed >= 3 and windSpeed < 5 then
|
||||||
@@ -11623,7 +11738,7 @@ function AIRBOSS:GetHeadingIntoWind_old( vdeck, magnetic, coord )
|
|||||||
elseif windSpeed >= 13 then
|
elseif windSpeed >= 13 then
|
||||||
degreesAdjustment = 0
|
degreesAdjustment = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
return degreesAdjustment
|
return degreesAdjustment
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -11682,60 +11797,60 @@ function AIRBOSS:GetHeadingIntoWind_new( vdeck, magnetic, coord )
|
|||||||
local h=self:GetHeading(magnetic)
|
local h=self:GetHeading(magnetic)
|
||||||
return h, math.min(vdeck, Vmax)
|
return h, math.min(vdeck, Vmax)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Convert wind speed to knots.
|
-- Convert wind speed to knots.
|
||||||
vwind=UTILS.MpsToKnots(vwind)
|
vwind=UTILS.MpsToKnots(vwind)
|
||||||
|
|
||||||
-- Wind to in knots.
|
-- Wind to in knots.
|
||||||
local windto=(windfrom+180)%360
|
local windto=(windfrom+180)%360
|
||||||
|
|
||||||
-- Offset angle in rad. We also define the rotation to be clock-wise, which requires a minus sign.
|
-- Offset angle in rad. We also define the rotation to be clock-wise, which requires a minus sign.
|
||||||
local alpha=math.rad(-Offset)
|
local alpha=math.rad(-Offset)
|
||||||
|
|
||||||
-- Constant.
|
-- Constant.
|
||||||
local C = math.sqrt(math.cos(alpha)^2 / math.sin(alpha)^2 + 1)
|
local C = math.sqrt(math.cos(alpha)^2 / math.sin(alpha)^2 + 1)
|
||||||
|
|
||||||
|
|
||||||
-- Upper limit of desired speed due to max boat speed.
|
-- Upper limit of desired speed due to max boat speed.
|
||||||
local vdeckMax=vwind + math.cos(alpha) * Vmax
|
local vdeckMax=vwind + math.cos(alpha) * Vmax
|
||||||
|
|
||||||
-- Lower limit of desired speed due to min boat speed.
|
-- Lower limit of desired speed due to min boat speed.
|
||||||
local vdeckMin=vwind + math.cos(alpha) * Vmin
|
local vdeckMin=vwind + math.cos(alpha) * Vmin
|
||||||
|
|
||||||
|
|
||||||
-- Speed of ship so it matches the desired speed.
|
-- Speed of ship so it matches the desired speed.
|
||||||
local v=0
|
local v=0
|
||||||
|
|
||||||
-- Angle wrt. to wind TO-direction
|
-- Angle wrt. to wind TO-direction
|
||||||
local theta=0
|
local theta=0
|
||||||
|
|
||||||
if vdeck>vdeckMax then
|
if vdeck>vdeckMax then
|
||||||
-- Boat cannot go fast enough
|
-- Boat cannot go fast enough
|
||||||
|
|
||||||
-- Set max speed.
|
-- Set max speed.
|
||||||
v=Vmax
|
v=Vmax
|
||||||
|
|
||||||
-- Calculate theta.
|
-- Calculate theta.
|
||||||
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
||||||
|
|
||||||
elseif vdeck<vdeckMin then
|
elseif vdeck<vdeckMin then
|
||||||
-- Boat cannot go slow enought
|
-- Boat cannot go slow enought
|
||||||
|
|
||||||
-- Set min speed.
|
-- Set min speed.
|
||||||
v=Vmin
|
v=Vmin
|
||||||
|
|
||||||
-- Calculatge theta.
|
-- Calculatge theta.
|
||||||
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
||||||
|
|
||||||
elseif vdeck*math.sin(alpha)>vwind then
|
elseif vdeck*math.sin(alpha)>vwind then
|
||||||
-- Too little wind
|
-- Too little wind
|
||||||
|
|
||||||
-- Set theta to 90°
|
-- Set theta to 90°
|
||||||
theta=math.pi/2
|
theta=math.pi/2
|
||||||
|
|
||||||
-- Set speed.
|
-- Set speed.
|
||||||
v = math.sqrt(vdeck^2 - vwind^2)
|
v = math.sqrt(vdeck^2 - vwind^2)
|
||||||
|
|
||||||
else
|
else
|
||||||
-- Normal case
|
-- Normal case
|
||||||
theta = math.asin(vdeck * math.sin(alpha) / vwind)
|
theta = math.asin(vdeck * math.sin(alpha) / vwind)
|
||||||
@@ -11744,9 +11859,9 @@ function AIRBOSS:GetHeadingIntoWind_new( vdeck, magnetic, coord )
|
|||||||
|
|
||||||
-- Magnetic heading.
|
-- Magnetic heading.
|
||||||
local magvar= magnetic and self.magvar or 0
|
local magvar= magnetic and self.magvar or 0
|
||||||
|
|
||||||
-- Ship heading so cross wind is min for the given wind.
|
-- Ship heading so cross wind is min for the given wind.
|
||||||
local intowind = (540 + (windto - magvar + math.deg(theta) )) % 360
|
local intowind = (540 + (windto - magvar + math.deg(theta) )) % 360
|
||||||
|
|
||||||
return intowind, v
|
return intowind, v
|
||||||
end
|
end
|
||||||
@@ -12204,7 +12319,7 @@ function AIRBOSS:_LSOgrade( playerData )
|
|||||||
-- Normal laning part at the beginning
|
-- Normal laning part at the beginning
|
||||||
local Gb = GXX .. " " .. GIM
|
local Gb = GXX .. " " .. GIM
|
||||||
|
|
||||||
-- Number of deviations that occurred at the the beginning of the landing (XX or IM). These are graded like in non-VTOL landings, i.e. on deviations is
|
-- Number of deviations that occurred at the the beginning of the landing (XX or IM). These are graded like in non-VTOL landings, i.e. on deviations is
|
||||||
local N=nXX+nIM
|
local N=nXX+nIM
|
||||||
local nL=count(Gb, '_')/2
|
local nL=count(Gb, '_')/2
|
||||||
local nS=count(Gb, '%(')
|
local nS=count(Gb, '%(')
|
||||||
@@ -12222,7 +12337,7 @@ function AIRBOSS:_LSOgrade( playerData )
|
|||||||
|
|
||||||
if nL>0 or nLv>1 then
|
if nL>0 or nLv>1 then
|
||||||
-- Larger deviations at XX or IM or at least one larger deviation IC or AR==> "No grade" 2.0 points.
|
-- Larger deviations at XX or IM or at least one larger deviation IC or AR==> "No grade" 2.0 points.
|
||||||
-- In other words, we allow one larger deviation at IC+AR
|
-- In other words, we allow one larger deviation at IC+AR
|
||||||
grade="--"
|
grade="--"
|
||||||
points=2.0
|
points=2.0
|
||||||
elseif nN>0 or nNv>1 or nLv==1 then
|
elseif nN>0 or nNv>1 or nLv==1 then
|
||||||
@@ -13718,7 +13833,7 @@ function AIRBOSS:CarrierTurnIntoWind( time, vdeck, uturn )
|
|||||||
local deltaH = self:_GetDeltaHeading( hdg, hiw )
|
local deltaH = self:_GetDeltaHeading( hdg, hiw )
|
||||||
|
|
||||||
-- Debug output
|
-- Debug output
|
||||||
self:I( self.lid .. string.format( "Carrier steaming into the wind (%.1f kts). Heading=%03d-->%03d (Delta=%.1f), Speed=%.1f knots, Distance=%.1f NM, Time=%d sec",
|
self:I( self.lid .. string.format( "Carrier steaming into the wind (%.1f kts). Heading=%03d-->%03d (Delta=%.1f), Speed=%.1f knots, Distance=%.1f NM, Time=%d sec",
|
||||||
UTILS.MpsToKnots( vwind ), hdg, hiw, deltaH, speedknots, distNM, speedknots, time ) )
|
UTILS.MpsToKnots( vwind ), hdg, hiw, deltaH, speedknots, distNM, speedknots, time ) )
|
||||||
|
|
||||||
-- Current coordinate.
|
-- Current coordinate.
|
||||||
@@ -14930,12 +15045,12 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
if radio == nil or call == nil then
|
if radio == nil or call == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.SRS then
|
if not self.SRS then
|
||||||
|
|
||||||
-- Create a new radio transmission item.
|
-- Create a new radio transmission item.
|
||||||
local transmission = {} -- #AIRBOSS.Radioitem
|
local transmission = {} -- #AIRBOSS.Radioitem
|
||||||
|
|
||||||
transmission.radio = radio
|
transmission.radio = radio
|
||||||
transmission.call = call
|
transmission.call = call
|
||||||
transmission.Tplay = timer.getAbsTime() + (delay or 0)
|
transmission.Tplay = timer.getAbsTime() + (delay or 0)
|
||||||
@@ -14943,49 +15058,49 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
transmission.isplaying = false
|
transmission.isplaying = false
|
||||||
transmission.Tstarted = nil
|
transmission.Tstarted = nil
|
||||||
transmission.loud = loud and call.loud
|
transmission.loud = loud and call.loud
|
||||||
|
|
||||||
-- Player onboard number if sender has one.
|
-- Player onboard number if sender has one.
|
||||||
if self:_IsOnboard( call.modexsender ) then
|
if self:_IsOnboard( call.modexsender ) then
|
||||||
self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall )
|
self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Play onboard number if receiver has one.
|
-- Play onboard number if receiver has one.
|
||||||
if self:_IsOnboard( call.modexreceiver ) then
|
if self:_IsOnboard( call.modexreceiver ) then
|
||||||
self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall )
|
self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add transmission to the right queue.
|
-- Add transmission to the right queue.
|
||||||
local caller = ""
|
local caller = ""
|
||||||
if radio.alias == "LSO" then
|
if radio.alias == "LSO" then
|
||||||
|
|
||||||
table.insert( self.RQLSO, transmission )
|
table.insert( self.RQLSO, transmission )
|
||||||
|
|
||||||
caller = "LSOCall"
|
caller = "LSOCall"
|
||||||
|
|
||||||
-- Schedule radio queue checks.
|
-- Schedule radio queue checks.
|
||||||
if not self.RQLid then
|
if not self.RQLid then
|
||||||
self:T( self.lid .. string.format( "Starting LSO radio queue." ) )
|
self:T( self.lid .. string.format( "Starting LSO radio queue." ) )
|
||||||
self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 )
|
self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 )
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif radio.alias == "MARSHAL" then
|
elseif radio.alias == "MARSHAL" then
|
||||||
|
|
||||||
table.insert( self.RQMarshal, transmission )
|
table.insert( self.RQMarshal, transmission )
|
||||||
|
|
||||||
caller = "MarshalCall"
|
caller = "MarshalCall"
|
||||||
|
|
||||||
if not self.RQMid then
|
if not self.RQMid then
|
||||||
self:T( self.lid .. string.format( "Starting Marhal radio queue." ) )
|
self:T( self.lid .. string.format( "Starting Marhal radio queue." ) )
|
||||||
self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 )
|
self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Append radio click sound at the end of the transmission.
|
-- Append radio click sound at the end of the transmission.
|
||||||
if click then
|
if click then
|
||||||
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- SRS transmission
|
-- SRS transmission
|
||||||
@@ -14996,7 +15111,7 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
local voice = nil
|
local voice = nil
|
||||||
local gender = nil
|
local gender = nil
|
||||||
local culture = nil
|
local culture = nil
|
||||||
|
|
||||||
if radio.alias == "AIRBOSS" then
|
if radio.alias == "AIRBOSS" then
|
||||||
frequency = self.AirbossRadio.frequency
|
frequency = self.AirbossRadio.frequency
|
||||||
modulation = self.AirbossRadio.modulation
|
modulation = self.AirbossRadio.modulation
|
||||||
@@ -15004,13 +15119,13 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
gender = self.AirbossRadio.gender
|
gender = self.AirbossRadio.gender
|
||||||
culture = self.AirbossRadio.culture
|
culture = self.AirbossRadio.culture
|
||||||
end
|
end
|
||||||
|
|
||||||
if radio.alias == "MARSHAL" then
|
if radio.alias == "MARSHAL" then
|
||||||
voice = self.MarshalRadio.voice
|
voice = self.MarshalRadio.voice
|
||||||
gender = self.MarshalRadio.gender
|
gender = self.MarshalRadio.gender
|
||||||
culture = self.MarshalRadio.culture
|
culture = self.MarshalRadio.culture
|
||||||
end
|
end
|
||||||
|
|
||||||
if radio.alias == "LSO" then
|
if radio.alias == "LSO" then
|
||||||
frequency = self.LSORadio.frequency
|
frequency = self.LSORadio.frequency
|
||||||
modulation = self.LSORadio.modulation
|
modulation = self.LSORadio.modulation
|
||||||
@@ -15018,7 +15133,7 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
gender = self.LSORadio.gender
|
gender = self.LSORadio.gender
|
||||||
culture = self.LSORadio.culture
|
culture = self.LSORadio.culture
|
||||||
end
|
end
|
||||||
|
|
||||||
if pilotcall then
|
if pilotcall then
|
||||||
voice = self.PilotRadio.voice
|
voice = self.PilotRadio.voice
|
||||||
gender = self.PilotRadio.gender
|
gender = self.PilotRadio.gender
|
||||||
@@ -15032,16 +15147,16 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
modulation = self.AirbossRadio.modulation
|
modulation = self.AirbossRadio.modulation
|
||||||
radio.alias = "AIRBOSS"
|
radio.alias = "AIRBOSS"
|
||||||
end
|
end
|
||||||
|
|
||||||
local volume = nil
|
local volume = nil
|
||||||
|
|
||||||
if loud then
|
if loud then
|
||||||
volume = 1.0
|
volume = 1.0
|
||||||
end
|
end
|
||||||
|
|
||||||
--local text = tostring(call.modexreceiver).."; "..radio.alias.."; "..call.subtitle
|
--local text = tostring(call.modexreceiver).."; "..radio.alias.."; "..call.subtitle
|
||||||
local text = call.subtitle
|
local text = call.subtitle
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
local srstext = self:_GetNiceSRSText(text)
|
local srstext = self:_GetNiceSRSText(text)
|
||||||
self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, nil, 0.1, nil, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias)
|
self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, nil, 0.1, nil, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias)
|
||||||
end
|
end
|
||||||
@@ -15061,11 +15176,11 @@ function AIRBOSS:SetSRSPilotVoice( Voice, Gender, Culture )
|
|||||||
self.PilotRadio.voice = Voice or MSRS.Voices.Microsoft.David
|
self.PilotRadio.voice = Voice or MSRS.Voices.Microsoft.David
|
||||||
self.PilotRadio.gender = Gender or "male"
|
self.PilotRadio.gender = Gender or "male"
|
||||||
self.PilotRadio.culture = Culture or "en-US"
|
self.PilotRadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
if (not Voice) and self.SRS and self.SRS:GetProvider() == MSRS.Provider.GOOGLE then
|
if (not Voice) and self.SRS and self.SRS:GetProvider() == MSRS.Provider.GOOGLE then
|
||||||
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -15379,44 +15494,44 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio
|
|||||||
-- SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay)
|
-- SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay)
|
||||||
self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear )
|
self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear )
|
||||||
else
|
else
|
||||||
|
|
||||||
if not self.SRS then
|
if not self.SRS then
|
||||||
-- Wait until previous sound finished.
|
-- Wait until previous sound finished.
|
||||||
local wait = 0
|
local wait = 0
|
||||||
|
|
||||||
-- Onboard number to get the attention.
|
-- Onboard number to get the attention.
|
||||||
if receiver == playerData.onboard then
|
if receiver == playerData.onboard then
|
||||||
|
|
||||||
-- Which voice over number to use.
|
-- Which voice over number to use.
|
||||||
if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then
|
if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then
|
||||||
|
|
||||||
-- User sound of board number.
|
-- User sound of board number.
|
||||||
wait = wait + self:_Number2Sound( playerData, sender, receiver )
|
wait = wait + self:_Number2Sound( playerData, sender, receiver )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Negative.
|
-- Negative.
|
||||||
if string.find( text:lower(), "negative" ) then
|
if string.find( text:lower(), "negative" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.NEGATIVE.duration
|
wait = wait + self.MarshalCall.NEGATIVE.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Affirm.
|
-- Affirm.
|
||||||
if string.find( text:lower(), "affirm" ) then
|
if string.find( text:lower(), "affirm" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.AFFIRMATIVE.duration
|
wait = wait + self.MarshalCall.AFFIRMATIVE.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Roger.
|
-- Roger.
|
||||||
if string.find( text:lower(), "roger" ) then
|
if string.find( text:lower(), "roger" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.ROGER.duration
|
wait = wait + self.MarshalCall.ROGER.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Play click sound to end message.
|
-- Play click sound to end message.
|
||||||
if wait > 0 then
|
if wait > 0 then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.CLICK )
|
local filename = self:_RadioFilename( self.MarshalCall.CLICK )
|
||||||
@@ -15429,7 +15544,7 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio
|
|||||||
local voice = self.MarshalRadio.voice
|
local voice = self.MarshalRadio.voice
|
||||||
local gender = self.MarshalRadio.gender
|
local gender = self.MarshalRadio.gender
|
||||||
local culture = self.MarshalRadio.culture
|
local culture = self.MarshalRadio.culture
|
||||||
|
|
||||||
if not sender then sender = "AIRBOSS" end
|
if not sender then sender = "AIRBOSS" end
|
||||||
|
|
||||||
if string.find(sender,"AIRBOSS" ) then
|
if string.find(sender,"AIRBOSS" ) then
|
||||||
@@ -17047,7 +17162,7 @@ function AIRBOSS:_RemoveSectionMember( playerData, sectionmember )
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set all flights within 100 meters to be part of my section.
|
--- Set all flights within maxsectiondistance meters to be part of my section (default: 100 meters).
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #string _unitName Name of the player unit.
|
-- @param #string _unitName Name of the player unit.
|
||||||
function AIRBOSS:_SetSection( _unitName )
|
function AIRBOSS:_SetSection( _unitName )
|
||||||
@@ -17065,7 +17180,7 @@ function AIRBOSS:_SetSection( _unitName )
|
|||||||
local mycoord = _unit:GetCoordinate()
|
local mycoord = _unit:GetCoordinate()
|
||||||
|
|
||||||
-- Max distance up to which section members are allowed.
|
-- Max distance up to which section members are allowed.
|
||||||
local dmax = 100
|
local dmax = self.maxsectiondistance
|
||||||
|
|
||||||
-- Check if player is in Marshal or pattern queue already.
|
-- Check if player is in Marshal or pattern queue already.
|
||||||
local text
|
local text
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Last Update Sep 2024
|
-- Last Update May 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
-- mycsar.immortalcrew = true -- Set to true to make wounded crew immortal.
|
-- mycsar.immortalcrew = true -- Set to true to make wounded crew immortal.
|
||||||
-- mycsar.invisiblecrew = false -- Set to true to make wounded crew insvisible.
|
-- mycsar.invisiblecrew = false -- Set to true to make wounded crew insvisible.
|
||||||
-- mycsar.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters.
|
-- mycsar.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters.
|
||||||
-- mycsar.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes.
|
-- mycsar.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes. Will also try to add ZONE and STATIC objects with this prefix once at startup.
|
||||||
-- mycsar.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined.
|
-- mycsar.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined.
|
||||||
-- mycsar.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages.
|
-- mycsar.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages.
|
||||||
-- mycsar.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons.
|
-- mycsar.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons.
|
||||||
@@ -263,6 +263,7 @@ CSAR = {
|
|||||||
rescuedpilots = 0,
|
rescuedpilots = 0,
|
||||||
limitmaxdownedpilots = true,
|
limitmaxdownedpilots = true,
|
||||||
maxdownedpilots = 10,
|
maxdownedpilots = 10,
|
||||||
|
useFIFOLimitReplacement = false, -- If true, it will remove the oldest downed pilot when a new one is added, if the limit is reached.
|
||||||
allheligroupset = nil,
|
allheligroupset = nil,
|
||||||
topmenuname = "CSAR",
|
topmenuname = "CSAR",
|
||||||
ADFRadioPwr = 1000,
|
ADFRadioPwr = 1000,
|
||||||
@@ -313,7 +314,7 @@ CSAR.AircraftType["CH-47Fbl1"] = 31
|
|||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CSAR.version="1.0.29"
|
CSAR.version="1.0.33"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@@ -468,7 +469,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
-- added 1.0.15
|
-- added 1.0.15
|
||||||
self.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
|
self.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
|
||||||
|
|
||||||
self.ADFRadioPwr = 1000
|
self.ADFRadioPwr = 500
|
||||||
|
|
||||||
-- added 1.0.16
|
-- added 1.0.16
|
||||||
self.PilotWeight = 80
|
self.PilotWeight = 80
|
||||||
@@ -809,6 +810,8 @@ end
|
|||||||
-- @param #boolean noMessage
|
-- @param #boolean noMessage
|
||||||
-- @param #string _description Description
|
-- @param #string _description Description
|
||||||
-- @param #boolean forcedesc Use the description only for the pilot track entry
|
-- @param #boolean forcedesc Use the description only for the pilot track entry
|
||||||
|
-- @return Wrapper.Group#GROUP PilotInField Pilot GROUP object
|
||||||
|
-- @return #string AliasName Alias display name
|
||||||
function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description, forcedesc )
|
function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description, forcedesc )
|
||||||
self:T(self.lid .. " _AddCsar")
|
self:T(self.lid .. " _AddCsar")
|
||||||
self:T({_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description})
|
self:T({_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description})
|
||||||
@@ -878,7 +881,7 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
|
|||||||
|
|
||||||
self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc.
|
self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc.
|
||||||
|
|
||||||
return self
|
return _spawnedGroup, _alias
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Function to add a CSAR object into the scene at a zone coordinate. For mission designers wanting to add e.g. PoWs to the scene.
|
--- (Internal) Function to add a CSAR object into the scene at a zone coordinate. For mission designers wanting to add e.g. PoWs to the scene.
|
||||||
@@ -1142,19 +1145,8 @@ function CSAR:_EventHandler(EventData)
|
|||||||
self:T("Double Ejection!")
|
self:T("Double Ejection!")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- limit no of pilots in the field.
|
|
||||||
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
|
||||||
self:T("Maxed Downed Pilot!")
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- TODO: Over water check --- EVENTS.LandingAfterEjection NOT triggered by DCS, so handle csarUsePara = true case
|
|
||||||
-- might create dual pilots in edge cases
|
|
||||||
|
|
||||||
local wetfeet = false
|
|
||||||
|
|
||||||
local initdcscoord = nil
|
local initdcscoord = nil
|
||||||
local initcoord = nil
|
local initcoord = nil
|
||||||
if _event.id == EVENTS.Ejection then
|
if _event.id == EVENTS.Ejection then
|
||||||
@@ -1166,6 +1158,36 @@ function CSAR:_EventHandler(EventData)
|
|||||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||||
self:T({initdcscoord})
|
self:T({initdcscoord})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remove downed pilot if already exists to replace with new one.
|
||||||
|
if _event.IniPlayerName then
|
||||||
|
local PilotTable = self.downedPilots --#CSAR.DownedPilot
|
||||||
|
local _foundPilot = nil
|
||||||
|
for _,_pilot in pairs(PilotTable) do
|
||||||
|
if _pilot.player == _event.IniPlayerName and _pilot.alive == true then
|
||||||
|
_foundPilot = _pilot
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if _foundPilot then
|
||||||
|
self:T("Downed pilot already exists!")
|
||||||
|
_foundPilot.group:Destroy(false)
|
||||||
|
self:_RemoveNameFromDownedPilots(_foundPilot.name)
|
||||||
|
self:_CheckDownedPilotTable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- limit no of pilots in the field.
|
||||||
|
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
||||||
|
self:T("Maxed Downed Pilot!")
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- TODO: Over water check --- EVENTS.LandingAfterEjection NOT triggered by DCS, so handle csarUsePara = true case
|
||||||
|
-- might create dual pilots in edge cases
|
||||||
|
|
||||||
|
local wetfeet = false
|
||||||
|
|
||||||
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
||||||
local surface = initcoord:GetSurfaceType()
|
local surface = initcoord:GetSurfaceType()
|
||||||
@@ -1829,8 +1851,9 @@ end
|
|||||||
--- (Internal) Function to get string of a group\'s position.
|
--- (Internal) Function to get string of a group\'s position.
|
||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object.
|
-- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object.
|
||||||
|
-- @param Wrapper.Unit#UNIT _Unit Requesting helo pilot unit
|
||||||
-- @return #string Coordinates as Text
|
-- @return #string Coordinates as Text
|
||||||
function CSAR:_GetPositionOfWounded(_woundedGroup)
|
function CSAR:_GetPositionOfWounded(_woundedGroup,_Unit)
|
||||||
self:T(self.lid .. " _GetPositionOfWounded")
|
self:T(self.lid .. " _GetPositionOfWounded")
|
||||||
local _coordinate = _woundedGroup:GetCoordinate()
|
local _coordinate = _woundedGroup:GetCoordinate()
|
||||||
local _coordinatesText = "None"
|
local _coordinatesText = "None"
|
||||||
@@ -1845,6 +1868,26 @@ function CSAR:_GetPositionOfWounded(_woundedGroup)
|
|||||||
_coordinatesText = _coordinate:ToStringBULLS(self.coalition)
|
_coordinatesText = _coordinate:ToStringBULLS(self.coalition)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if _Unit and _Unit:GetPlayerName() then
|
||||||
|
local playername = _Unit:GetPlayerName()
|
||||||
|
if playername then
|
||||||
|
local settings = _DATABASE:GetPlayerSettings(playername) or _SETTINGS
|
||||||
|
if settings then
|
||||||
|
self:T("Get Settings ok!")
|
||||||
|
if settings:IsA2G_MGRS() then
|
||||||
|
_coordinatesText = _coordinate:ToStringMGRS(settings)
|
||||||
|
elseif settings:IsA2G_LL_DMS() then
|
||||||
|
_coordinatesText = _coordinate:ToStringLLDMS(settings)
|
||||||
|
elseif settings:IsA2G_LL_DDM() then
|
||||||
|
_coordinatesText = _coordinate:ToStringLLDDM(settings)
|
||||||
|
elseif settings:IsA2G_BR() then
|
||||||
|
-- attention this is the distance from the ASKING unit to target, not from RECCE to target!
|
||||||
|
local startcoordinate = _Unit:GetCoordinate()
|
||||||
|
_coordinatesText = _coordinate:ToStringBR(startcoordinate,settings)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
return _coordinatesText
|
return _coordinatesText
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1870,13 +1913,17 @@ function CSAR:_DisplayActiveSAR(_unitName)
|
|||||||
self:T({Table=_value})
|
self:T({Table=_value})
|
||||||
local _woundedGroup = _value.group
|
local _woundedGroup = _value.group
|
||||||
if _woundedGroup and _value.alive then
|
if _woundedGroup and _value.alive then
|
||||||
local _coordinatesText = self:_GetPositionOfWounded(_woundedGroup)
|
local _coordinatesText = self:_GetPositionOfWounded(_woundedGroup,_heli)
|
||||||
local _helicoord = _heli:GetCoordinate()
|
local _helicoord = _heli:GetCoordinate()
|
||||||
local _woundcoord = _woundedGroup:GetCoordinate()
|
local _woundcoord = _woundedGroup:GetCoordinate()
|
||||||
local _distance = self:_GetDistance(_helicoord, _woundcoord)
|
local _distance = self:_GetDistance(_helicoord, _woundcoord)
|
||||||
self:T({_distance = _distance})
|
self:T({_distance = _distance})
|
||||||
local distancetext = ""
|
local distancetext = ""
|
||||||
if _SETTINGS:IsImperial() then
|
local settings = _SETTINGS
|
||||||
|
if _heli:GetPlayerName() then
|
||||||
|
settings = _DATABASE:GetPlayerSettings(_heli:GetPlayerName()) or _SETTINGS
|
||||||
|
end
|
||||||
|
if settings:IsImperial() then
|
||||||
distancetext = string.format("%.1fnm",UTILS.MetersToNM(_distance))
|
distancetext = string.format("%.1fnm",UTILS.MetersToNM(_distance))
|
||||||
else
|
else
|
||||||
distancetext = string.format("%.1fkm", _distance/1000.0)
|
distancetext = string.format("%.1fkm", _distance/1000.0)
|
||||||
@@ -2089,56 +2136,50 @@ end
|
|||||||
--- (Internal) Determine distance to closest MASH.
|
--- (Internal) Determine distance to closest MASH.
|
||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT
|
-- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT
|
||||||
-- @return #CSAR self
|
-- @return #number Distance in meters
|
||||||
|
-- @return #string MASH Name as string
|
||||||
function CSAR:_GetClosestMASH(_heli)
|
function CSAR:_GetClosestMASH(_heli)
|
||||||
self:T(self.lid .. " _GetClosestMASH")
|
self:T(self.lid .. " _GetClosestMASH")
|
||||||
local _mashset = self.mash -- Core.Set#SET_GROUP
|
local _mashset = self.mash -- Core.Set#SET_GROUP
|
||||||
local _mashes = _mashset:GetSetObjects() -- #table
|
local MashSets = {}
|
||||||
|
--local _mashes = _mashset.Set-- #table
|
||||||
|
table.insert(MashSets,_mashset.Set)
|
||||||
|
table.insert(MashSets,self.zonemashes.Set)
|
||||||
|
table.insert(MashSets,self.staticmashes.Set)
|
||||||
local _shortestDistance = -1
|
local _shortestDistance = -1
|
||||||
local _distance = 0
|
local _distance = 0
|
||||||
local _helicoord = _heli:GetCoordinate()
|
local _helicoord = _heli:GetCoordinate()
|
||||||
|
local MashName = nil
|
||||||
local function GetCloseAirbase(coordinate,Coalition,Category)
|
|
||||||
|
|
||||||
local a=coordinate:GetVec3()
|
|
||||||
local distmin=math.huge
|
|
||||||
local airbase=nil
|
|
||||||
for DCSairbaseID, DCSairbase in pairs(world.getAirbases(Coalition)) do
|
|
||||||
local b=DCSairbase:getPoint()
|
|
||||||
|
|
||||||
local c=UTILS.VecSubstract(a,b)
|
|
||||||
local dist=UTILS.VecNorm(c)
|
|
||||||
|
|
||||||
if dist<distmin and (Category==nil or Category==DCSairbase:getDesc().category) then
|
|
||||||
distmin=dist
|
|
||||||
airbase=DCSairbase
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
return distmin
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.allowFARPRescue then
|
if self.allowFARPRescue then
|
||||||
local position = _heli:GetCoordinate()
|
local position = _heli:GetCoordinate()
|
||||||
local afb,distance = position:GetClosestAirbase(nil,self.coalition)
|
local afb,distance = position:GetClosestAirbase(nil,self.coalition)
|
||||||
_shortestDistance = distance
|
_shortestDistance = distance
|
||||||
|
MashName = (afb ~= nil) and afb:GetName() or "Unknown"
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, _mashUnit in pairs(_mashes) do
|
for _,_mashes in pairs(MashSets) do
|
||||||
if _mashUnit and _mashUnit:IsAlive() then
|
for _, _mashUnit in pairs(_mashes or {}) do
|
||||||
local _mashcoord = _mashUnit:GetCoordinate()
|
local _mashcoord
|
||||||
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
if _mashUnit and (not _mashUnit:IsInstanceOf("ZONE_BASE")) and _mashUnit:IsAlive() then
|
||||||
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
_mashcoord = _mashUnit:GetCoordinate()
|
||||||
_shortestDistance = _distance
|
elseif _mashUnit and _mashUnit:IsInstanceOf("ZONE_BASE") then
|
||||||
end
|
_mashcoord = _mashUnit:GetCoordinate()
|
||||||
end
|
end
|
||||||
|
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
||||||
|
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
||||||
|
_shortestDistance = _distance
|
||||||
|
MashName = _mashUnit:GetName() or "Unknown"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if _shortestDistance ~= -1 then
|
if _shortestDistance ~= -1 then
|
||||||
return _shortestDistance
|
return _shortestDistance, MashName
|
||||||
else
|
else
|
||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Display onboarded rescued pilots.
|
--- (Internal) Display onboarded rescued pilots.
|
||||||
@@ -2296,9 +2337,9 @@ end
|
|||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param Wrapper.Group#GROUP _group Group #GROUP object.
|
-- @param Wrapper.Group#GROUP _group Group #GROUP object.
|
||||||
-- @param #number _freq Frequency to use
|
-- @param #number _freq Frequency to use
|
||||||
-- @param #string _name Beacon Name to use
|
-- @param #string BeaconName Beacon Name to use
|
||||||
-- @return #CSAR self
|
-- @return #CSAR self
|
||||||
function CSAR:_AddBeaconToGroup(_group, _freq, _name)
|
function CSAR:_AddBeaconToGroup(_group, _freq, BeaconName)
|
||||||
self:T(self.lid .. " _AddBeaconToGroup")
|
self:T(self.lid .. " _AddBeaconToGroup")
|
||||||
if self.CreateRadioBeacons == false then return end
|
if self.CreateRadioBeacons == false then return end
|
||||||
local _group = _group
|
local _group = _group
|
||||||
@@ -2319,10 +2360,11 @@ function CSAR:_AddBeaconToGroup(_group, _freq, _name)
|
|||||||
if _radioUnit then
|
if _radioUnit then
|
||||||
local name = _radioUnit:GetName()
|
local name = _radioUnit:GetName()
|
||||||
local Frequency = _freq -- Freq in Hertz
|
local Frequency = _freq -- Freq in Hertz
|
||||||
local name = _radioUnit:GetName()
|
--local name = _radioUnit:GetName()
|
||||||
local Sound = "l10n/DEFAULT/"..self.radioSound
|
local Sound = "l10n/DEFAULT/"..self.radioSound
|
||||||
local vec3 = _radioUnit:GetVec3() or _radioUnit:GetPositionVec3() or {x=0,y=0,z=0}
|
local vec3 = _radioUnit:GetVec3() or _radioUnit:GetPositionVec3() or {x=0,y=0,z=0}
|
||||||
trigger.action.radioTransmission(Sound, vec3, 0, false, Frequency, self.ADFRadioPwr or 1000,_name) -- Beacon in MP only runs for exactly 30secs straight
|
self:I(self.lid..string.format("Added Radio Beacon %d Hertz | Name %s | Position {%d,%d,%d}",Frequency,BeaconName,vec3.x,vec3.y,vec3.z))
|
||||||
|
trigger.action.radioTransmission(Sound, vec3, 0, true, Frequency, self.ADFRadioPwr or 500,BeaconName) -- Beacon in MP only runs for exactly 30secs straight
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2343,9 +2385,13 @@ function CSAR:_RefreshRadioBeacons()
|
|||||||
local group = pilot.group
|
local group = pilot.group
|
||||||
local frequency = pilot.frequency or 0 -- thanks to @Thrud
|
local frequency = pilot.frequency or 0 -- thanks to @Thrud
|
||||||
local bname = pilot.BeaconName or pilot.name..math.random(1,100000)
|
local bname = pilot.BeaconName or pilot.name..math.random(1,100000)
|
||||||
trigger.action.stopRadioTransmission(bname)
|
--trigger.action.stopRadioTransmission(bname)
|
||||||
if group and group:IsAlive() and frequency > 0 then
|
if group and group:IsAlive() and frequency > 0 then
|
||||||
self:_AddBeaconToGroup(group,frequency,bname)
|
--self:_AddBeaconToGroup(group,frequency,bname)
|
||||||
|
else
|
||||||
|
if frequency > 0 then
|
||||||
|
trigger.action.stopRadioTransmission(bname)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2375,11 +2421,26 @@ function CSAR:_ReachedPilotLimit()
|
|||||||
local limit = self.maxdownedpilots
|
local limit = self.maxdownedpilots
|
||||||
local islimited = self.limitmaxdownedpilots
|
local islimited = self.limitmaxdownedpilots
|
||||||
local count = self:_CountActiveDownedPilots()
|
local count = self:_CountActiveDownedPilots()
|
||||||
if islimited and (count >= limit) then
|
if islimited and (count >= limit) then
|
||||||
return true
|
if self.useFIFOLimitReplacement then
|
||||||
else
|
local oldIndex = -1
|
||||||
return false
|
local oldDownedPilot = nil
|
||||||
end
|
for _index, _downedpilot in pairs(self.downedPilots) do
|
||||||
|
oldIndex = _index
|
||||||
|
oldDownedPilot = _downedpilot
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if oldDownedPilot then
|
||||||
|
oldDownedPilot.group:Destroy(false)
|
||||||
|
oldDownedPilot.alive = false
|
||||||
|
self:_CheckDownedPilotTable()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
|
--- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
|
||||||
@@ -2425,7 +2486,26 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
|
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
|
||||||
end
|
end
|
||||||
|
|
||||||
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also?
|
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
|
|
||||||
|
self.staticmashes = SET_STATIC:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
|
self.zonemashes = SET_ZONE:New():FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
|
|
||||||
|
--[[
|
||||||
|
if staticmashes:Count() > 0 then
|
||||||
|
for _,_mash in pairs(staticmashes.Set) do
|
||||||
|
self.mash:AddObject(_mash)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if zonemashes:Count() > 0 then
|
||||||
|
self:T("Adding zones to self.mash SET")
|
||||||
|
for _,_mash in pairs(zonemashes.Set) do
|
||||||
|
self.mash:AddObject(_mash)
|
||||||
|
end
|
||||||
|
self:T("Objects in SET: "..self.mash:Count())
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
if not self.coordinate then
|
if not self.coordinate then
|
||||||
local csarhq = self.mash:GetRandom()
|
local csarhq = self.mash:GetRandom()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -997,6 +997,8 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
|||||||
|
|
||||||
-- Init status updates in 10 seconds.
|
-- Init status updates in 10 seconds.
|
||||||
self:__Status(10)
|
self:__Status(10)
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -963,6 +963,8 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
|
|
||||||
-- Init status check
|
-- Init status check
|
||||||
self:__Status(1)
|
self:__Status(1)
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after Status event. Checks player status.
|
--- On after Status event. Checks player status.
|
||||||
|
|||||||
@@ -380,7 +380,8 @@ function RADIOQUEUE:Broadcast(transmission)
|
|||||||
self:T(self.lid..string.format("Broadcasting from aircraft %s", sender:GetName()))
|
self:T(self.lid..string.format("Broadcasting from aircraft %s", sender:GetName()))
|
||||||
|
|
||||||
|
|
||||||
if not self.senderinit then
|
--if not self.senderinit then
|
||||||
|
-- TODO Seems to be a DCS bug - if I explode ANY unit in a group the BC assignment gets lost
|
||||||
|
|
||||||
-- Command to set the Frequency for the transmission.
|
-- Command to set the Frequency for the transmission.
|
||||||
local commandFrequency={
|
local commandFrequency={
|
||||||
@@ -394,7 +395,7 @@ function RADIOQUEUE:Broadcast(transmission)
|
|||||||
sender:SetCommand(commandFrequency)
|
sender:SetCommand(commandFrequency)
|
||||||
|
|
||||||
self.senderinit=true
|
self.senderinit=true
|
||||||
end
|
--end
|
||||||
|
|
||||||
-- Set subtitle only if duration>0 sec.
|
-- Set subtitle only if duration>0 sec.
|
||||||
local subtitle=nil
|
local subtitle=nil
|
||||||
|
|||||||
@@ -267,6 +267,135 @@ MSRS.version="0.3.3"
|
|||||||
--- Voices
|
--- Voices
|
||||||
-- @type MSRS.Voices
|
-- @type MSRS.Voices
|
||||||
MSRS.Voices = {
|
MSRS.Voices = {
|
||||||
|
Amazon = {
|
||||||
|
Generative = {
|
||||||
|
en_AU = {
|
||||||
|
Olivia = "Olivia",
|
||||||
|
},
|
||||||
|
en_GB = {
|
||||||
|
Amy = "Amy",
|
||||||
|
},
|
||||||
|
en_US = {
|
||||||
|
Danielle = "Danielle",
|
||||||
|
Joanna = "Joanna",
|
||||||
|
Ruth = "Ruth",
|
||||||
|
Stephen = "Stephen",
|
||||||
|
},
|
||||||
|
fr_FR = {
|
||||||
|
["Léa"] = "Léa",
|
||||||
|
["Rémi"] = "Rémi",
|
||||||
|
},
|
||||||
|
de_DE = {
|
||||||
|
Vicki = "Vicki",
|
||||||
|
Daniel = "Daniel",
|
||||||
|
},
|
||||||
|
it_IT = {
|
||||||
|
Bianca = "Bianca",
|
||||||
|
Adriano = "Adriano",
|
||||||
|
},
|
||||||
|
es_ES = {
|
||||||
|
Lucia = "Lucia",
|
||||||
|
Sergio = "Sergio",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
LongForm = {
|
||||||
|
en_US = {
|
||||||
|
Danielle = "Danielle",
|
||||||
|
Gregory = "Gregory",
|
||||||
|
Ivy = "Ivy",
|
||||||
|
Ruth = "Ruth",
|
||||||
|
Patrick = "Patrick",
|
||||||
|
},
|
||||||
|
es_ES = {
|
||||||
|
Alba = "Alba",
|
||||||
|
["Raúl"] = "Raúl",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Neural = {
|
||||||
|
en_AU = {
|
||||||
|
Olivia = "Olivia",
|
||||||
|
},
|
||||||
|
en_GB = {
|
||||||
|
Amy = "Amy",
|
||||||
|
Emma = "Emma",
|
||||||
|
Brian = "Brian",
|
||||||
|
Arthur = "Arthur",
|
||||||
|
},
|
||||||
|
en_US = {
|
||||||
|
Danielle = "Danielle",
|
||||||
|
Gregory = "Gregory",
|
||||||
|
Ivy = "Ivy",
|
||||||
|
Joanna = "Joanna",
|
||||||
|
Kendra = "Kendra",
|
||||||
|
Kimberly = "Kimberly",
|
||||||
|
Salli = "Salli",
|
||||||
|
Joey = "Joey",
|
||||||
|
Kevin = "Kevin",
|
||||||
|
Ruth = "Ruth",
|
||||||
|
Stephen = "Stephen",
|
||||||
|
},
|
||||||
|
fr_FR = {
|
||||||
|
["Léa"] = "Léa",
|
||||||
|
["Rémi"] = "Rémi",
|
||||||
|
},
|
||||||
|
de_DE = {
|
||||||
|
Vicki = "Vicki",
|
||||||
|
Daniel = "Daniel",
|
||||||
|
},
|
||||||
|
it_IT = {
|
||||||
|
Bianca = "Bianca",
|
||||||
|
Adriano = "Adriano",
|
||||||
|
},
|
||||||
|
es_ES = {
|
||||||
|
Lucia = "Lucia",
|
||||||
|
Sergio = "Sergio",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Standard = {
|
||||||
|
en_AU = {
|
||||||
|
Nicole = "Nicole",
|
||||||
|
Russel = "Russel",
|
||||||
|
},
|
||||||
|
en_GB = {
|
||||||
|
Amy = "Amy",
|
||||||
|
Emma = "Emma",
|
||||||
|
Brian = "Brian",
|
||||||
|
},
|
||||||
|
en_IN = {
|
||||||
|
Aditi = "Aditi",
|
||||||
|
Raveena = "Raveena",
|
||||||
|
},
|
||||||
|
en_US = {
|
||||||
|
Ivy = "Ivy",
|
||||||
|
Joanna = "Joanna",
|
||||||
|
Kendra = "Kendra",
|
||||||
|
Kimberly = "Kimberly",
|
||||||
|
Salli = "Salli",
|
||||||
|
Joey = "Joey",
|
||||||
|
Kevin = "Kevin",
|
||||||
|
},
|
||||||
|
fr_FR = {
|
||||||
|
Celine = "Celine",
|
||||||
|
["Léa"] = "Léa",
|
||||||
|
Mathieu = "Mathieu",
|
||||||
|
},
|
||||||
|
de_DE = {
|
||||||
|
Marlene = "Marlene",
|
||||||
|
Vicki = "Vicki",
|
||||||
|
Hans = "Hans",
|
||||||
|
},
|
||||||
|
it_IT = {
|
||||||
|
Carla = "Carla",
|
||||||
|
Bianca = "Bianca",
|
||||||
|
Giorgio = "Giorgio",
|
||||||
|
},
|
||||||
|
es_ES = {
|
||||||
|
Conchita = "Conchita",
|
||||||
|
Lucia = "Lucia",
|
||||||
|
Enrique = "Enrique",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
Microsoft = { -- working ones if not using gRPC and MS
|
Microsoft = { -- working ones if not using gRPC and MS
|
||||||
["Hedda"] = "Microsoft Hedda Desktop", -- de-DE
|
["Hedda"] = "Microsoft Hedda Desktop", -- de-DE
|
||||||
["Hazel"] = "Microsoft Hazel Desktop", -- en-GB
|
["Hazel"] = "Microsoft Hazel Desktop", -- en-GB
|
||||||
@@ -318,11 +447,14 @@ MSRS.Voices = {
|
|||||||
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- [6] MALE
|
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- [6] MALE
|
||||||
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- [7] MALE
|
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- [7] MALE
|
||||||
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- [8] FEMALE
|
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- [8] FEMALE
|
||||||
["en_GB_Standard_A"] = 'en-GB-Standard-A', -- [9] FEMALE
|
-- 2025 changes
|
||||||
["en_GB_Standard_B"] = 'en-GB-Standard-B', -- [10] MALE
|
["en_GB_Standard_A"] = 'en-GB-Standard-N', -- [9] FEMALE
|
||||||
["en_GB_Standard_C"] = 'en-GB-Standard-C', -- [11] FEMALE
|
["en_GB_Standard_B"] = 'en-GB-Standard-O', -- [10] MALE
|
||||||
["en_GB_Standard_D"] = 'en-GB-Standard-D', -- [12] MALE
|
["en_GB_Standard_C"] = 'en-GB-Standard-N', -- [11] FEMALE
|
||||||
["en_GB_Standard_F"] = 'en-GB-Standard-F', -- [13] FEMALE
|
["en_GB_Standard_D"] = 'en-GB-Standard-O', -- [12] MALE
|
||||||
|
["en_GB_Standard_F"] = 'en-GB-Standard-N', -- [13] FEMALE
|
||||||
|
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- [12] MALE
|
||||||
|
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- [13] FEMALE
|
||||||
["en_US_Standard_A"] = 'en-US-Standard-A', -- [14] MALE
|
["en_US_Standard_A"] = 'en-US-Standard-A', -- [14] MALE
|
||||||
["en_US_Standard_B"] = 'en-US-Standard-B', -- [15] MALE
|
["en_US_Standard_B"] = 'en-US-Standard-B', -- [15] MALE
|
||||||
["en_US_Standard_C"] = 'en-US-Standard-C', -- [16] FEMALE
|
["en_US_Standard_C"] = 'en-US-Standard-C', -- [16] FEMALE
|
||||||
@@ -333,25 +465,36 @@ MSRS.Voices = {
|
|||||||
["en_US_Standard_H"] = 'en-US-Standard-H', -- [21] FEMALE
|
["en_US_Standard_H"] = 'en-US-Standard-H', -- [21] FEMALE
|
||||||
["en_US_Standard_I"] = 'en-US-Standard-I', -- [22] MALE
|
["en_US_Standard_I"] = 'en-US-Standard-I', -- [22] MALE
|
||||||
["en_US_Standard_J"] = 'en-US-Standard-J', -- [23] MALE
|
["en_US_Standard_J"] = 'en-US-Standard-J', -- [23] MALE
|
||||||
["fr_FR_Standard_A"] = "fr-FR-Standard-A", -- Female
|
-- 2025 catalog changes
|
||||||
["fr_FR_Standard_B"] = "fr-FR-Standard-B", -- Male
|
["fr_FR_Standard_A"] = "fr-FR-Standard-F", -- Female
|
||||||
["fr_FR_Standard_C"] = "fr-FR-Standard-C", -- Female
|
["fr_FR_Standard_B"] = "fr-FR-Standard-G", -- Male
|
||||||
["fr_FR_Standard_D"] = "fr-FR-Standard-D", -- Male
|
["fr_FR_Standard_C"] = "fr-FR-Standard-F", -- Female
|
||||||
["fr_FR_Standard_E"] = "fr-FR-Standard-E", -- Female
|
["fr_FR_Standard_D"] = "fr-FR-Standard-G", -- Male
|
||||||
["de_DE_Standard_A"] = "de-DE-Standard-A", -- Female
|
["fr_FR_Standard_E"] = "fr-FR-Standard-F", -- Female
|
||||||
["de_DE_Standard_B"] = "de-DE-Standard-B", -- Male
|
["fr_FR_Standard_G"] = "fr-FR-Standard-G", -- Male
|
||||||
["de_DE_Standard_C"] = "de-DE-Standard-C", -- Female
|
["fr_FR_Standard_F"] = "fr-FR-Standard-F", -- Female
|
||||||
["de_DE_Standard_D"] = "de-DE-Standard-D", -- Male
|
-- 2025 catalog changes
|
||||||
["de_DE_Standard_E"] = "de-DE-Standard-E", -- Male
|
["de_DE_Standard_A"] = "de-DE-Standard-G", -- Female
|
||||||
["de_DE_Standard_F"] = "de-DE-Standard-F", -- Female
|
["de_DE_Standard_B"] = "de-DE-Standard-H", -- Male
|
||||||
["es_ES_Standard_A"] = "es-ES-Standard-A", -- Female
|
["de_DE_Standard_C"] = "de-DE-Standard-G", -- Female
|
||||||
["es_ES_Standard_B"] = "es-ES-Standard-B", -- Male
|
["de_DE_Standard_D"] = "de-DE-Standard-H", -- Male
|
||||||
["es_ES_Standard_C"] = "es-ES-Standard-C", -- Female
|
["de_DE_Standard_E"] = "de-DE-Standard-H", -- Male
|
||||||
["es_ES_Standard_D"] = "es-ES-Standard-D", -- Female
|
["de_DE_Standard_F"] = "de-DE-Standard-G", -- Female
|
||||||
["it_IT_Standard_A"] = "it-IT-Standard-A", -- Female
|
["de_DE_Standard_H"] = "de-DE-Standard-H", -- Male
|
||||||
["it_IT_Standard_B"] = "it-IT-Standard-B", -- Female
|
["de_DE_Standard_G"] = "de-DE-Standard-G", -- Female
|
||||||
["it_IT_Standard_C"] = "it-IT-Standard-C", -- Male
|
["es_ES_Standard_A"] = "es-ES-Standard-E", -- Female
|
||||||
["it_IT_Standard_D"] = "it-IT-Standard-D", -- Male
|
["es_ES_Standard_B"] = "es-ES-Standard-F", -- Male
|
||||||
|
["es_ES_Standard_C"] = "es-ES-Standard-E", -- Female
|
||||||
|
["es_ES_Standard_D"] = "es-ES-Standard-F", -- Male
|
||||||
|
["es_ES_Standard_E"] = "es-ES-Standard-E", -- Female
|
||||||
|
["es_ES_Standard_F"] = "es-ES-Standard-F", -- Male
|
||||||
|
-- 2025 catalog changes
|
||||||
|
["it_IT_Standard_A"] = "it-IT-Standard-E", -- Female
|
||||||
|
["it_IT_Standard_B"] = "it-IT-Standard-E", -- Female
|
||||||
|
["it_IT_Standard_C"] = "it-IT-Standard-F", -- Male
|
||||||
|
["it_IT_Standard_D"] = "it-IT-Standard-F", -- Male
|
||||||
|
["it_IT_Standard_E"] = "it-IT-Standard-E", -- Female
|
||||||
|
["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', -- [1] FEMALE
|
||||||
@@ -362,12 +505,15 @@ MSRS.Voices = {
|
|||||||
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- [6] MALE
|
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- [6] MALE
|
||||||
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- [7] MALE
|
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- [7] MALE
|
||||||
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- [8] FEMALE
|
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- [8] FEMALE
|
||||||
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-A', -- [9] FEMALE
|
-- 2025 changes
|
||||||
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-B', -- [10] MALE
|
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-N', -- [9] FEMALE
|
||||||
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-C', -- [11] FEMALE
|
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-O', -- [10] MALE
|
||||||
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-D', -- [12] MALE
|
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-N', -- [11] FEMALE
|
||||||
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-F', -- [13] FEMALE
|
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-O', -- [12] MALE
|
||||||
["en_US_Wavenet_A"] = 'en-US-Wavenet-A', -- [14] MALE
|
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
||||||
|
["en_GB_Wavenet_O"] = 'en-GB-Wavenet-O', -- [12] MALE
|
||||||
|
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
||||||
|
["en_US_Wavenet_A"] = 'en-US-Wavenet-N', -- [14] MALE
|
||||||
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- [15] MALE
|
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- [15] MALE
|
||||||
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- [16] FEMALE
|
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- [16] FEMALE
|
||||||
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- [17] MALE
|
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- [17] MALE
|
||||||
@@ -377,24 +523,35 @@ MSRS.Voices = {
|
|||||||
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- [21] FEMALE
|
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- [21] FEMALE
|
||||||
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- [22] MALE
|
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- [22] MALE
|
||||||
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- [23] MALE
|
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- [23] MALE
|
||||||
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-A", -- Female
|
-- 2025 catalog changes
|
||||||
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-B", -- Male
|
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-F", -- Female
|
||||||
["fr_FR_Wavenet_C"] = "fr-FR-Wavenet-C", -- Female
|
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-G", -- Male
|
||||||
["fr_FR_Wavenet_D"] = "fr-FR-Wavenet-D", -- Male
|
["fr_FR_Wavenet_C"] = "fr-FR-Wavenet-F", -- Female
|
||||||
["fr_FR_Wavenet_E"] = "fr-FR-Wavenet-E", -- Female
|
["fr_FR_Wavenet_D"] = "fr-FR-Wavenet-G", -- Male
|
||||||
["de_DE_Wavenet_A"] = "de-DE-Wavenet-A", -- Female
|
["fr_FR_Wavenet_E"] = "fr-FR-Wavenet-F", -- Female
|
||||||
["de_DE_Wavenet_B"] = "de-DE-Wavenet-B", -- Male
|
["fr_FR_Wavenet_G"] = "fr-FR-Wavenet-G", -- Male
|
||||||
["de_DE_Wavenet_C"] = "de-DE-Wavenet-C", -- Female
|
["fr_FR_Wavenet_F"] = "fr-FR-Wavenet-F", -- Female
|
||||||
["de_DE_Wavenet_D"] = "de-DE-Wavenet-D", -- Male
|
-- 2025 catalog changes
|
||||||
["de_DE_Wavenet_E"] = "de-DE-Wavenet-E", -- Male
|
["de_DE_Wavenet_A"] = "de-DE-Wavenet-G", -- Female
|
||||||
["de_DE_Wavenet_F"] = "de-DE-Wavenet-F", -- Female
|
["de_DE_Wavenet_B"] = "de-DE-Wavenet-H", -- Male
|
||||||
["es_ES_Wavenet_B"] = "es-ES-Wavenet-B", -- Male
|
["de_DE_Wavenet_C"] = "de-DE-Wavenet-G", -- Female
|
||||||
["es_ES_Wavenet_C"] = "es-ES-Wavenet-C", -- Female
|
["de_DE_Wavenet_D"] = "de-DE-Wavenet-H", -- Male
|
||||||
["es_ES_Wavenet_D"] = "es-ES-Wavenet-D", -- Female
|
["de_DE_Wavenet_E"] = "de-DE-Wavenet-H", -- Male
|
||||||
["it_IT_Wavenet_A"] = "it-IT-Wavenet-A", -- Female
|
["de_DE_Wavenet_F"] = "de-DE-Wavenet-G", -- Female
|
||||||
["it_IT_Wavenet_B"] = "it-IT-Wavenet-B", -- Female
|
["de_DE_Wavenet_H"] = "de-DE-Wavenet-H", -- Male
|
||||||
["it_IT_Wavenet_C"] = "it-IT-Wavenet-C", -- Male
|
["de_DE_Wavenet_G"] = "de-DE-Wavenet-G", -- Female
|
||||||
["it_IT_Wavenet_D"] = "it-IT-Wavenet-D", -- Male
|
["es_ES_Wavenet_B"] = "es-ES-Wavenet-E", -- Male
|
||||||
|
["es_ES_Wavenet_C"] = "es-ES-Wavenet-F", -- Female
|
||||||
|
["es_ES_Wavenet_D"] = "es-ES-Wavenet-E", -- Female
|
||||||
|
["es_ES_Wavenet_E"] = "es-ES-Wavenet-E", -- Male
|
||||||
|
["es_ES_Wavenet_F"] = "es-ES-Wavenet-F", -- Female
|
||||||
|
-- 2025 catalog changes
|
||||||
|
["it_IT_Wavenet_A"] = "it-IT-Wavenet-E", -- Female
|
||||||
|
["it_IT_Wavenet_B"] = "it-IT-Wavenet-E", -- Female
|
||||||
|
["it_IT_Wavenet_C"] = "it-IT-Wavenet-F", -- Male
|
||||||
|
["it_IT_Wavenet_D"] = "it-IT-Wavenet-F", -- Male
|
||||||
|
["it_IT_Wavenet_E"] = "it-IT-Wavenet-E", -- Female
|
||||||
|
["it_IT_Wavenet_F"] = "it-IT-Wavenet-F", -- Male
|
||||||
} ,
|
} ,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -946,7 +1103,7 @@ end
|
|||||||
-- - `MSRS.Provider.WINDOWS`: Microsoft Windows (default)
|
-- - `MSRS.Provider.WINDOWS`: Microsoft Windows (default)
|
||||||
-- - `MSRS.Provider.GOOGLE`: Google Cloud
|
-- - `MSRS.Provider.GOOGLE`: Google Cloud
|
||||||
-- - `MSRS.Provider.AZURE`: Microsoft Azure (only with DCS-gRPC backend)
|
-- - `MSRS.Provider.AZURE`: Microsoft Azure (only with DCS-gRPC backend)
|
||||||
-- - `MSRS.Provier.AMAZON`: Amazone Web Service (only with DCS-gRPC backend)
|
-- - `MSRS.Provier.AMAZON`: Amazon Web Service (only with DCS-gRPC backend)
|
||||||
--
|
--
|
||||||
-- Note that all providers except Microsoft Windows need as additonal information the credentials of your account.
|
-- Note that all providers except Microsoft Windows need as additonal information the credentials of your account.
|
||||||
--
|
--
|
||||||
@@ -1156,7 +1313,8 @@ function MSRS:PlaySoundFile(Soundfile, Delay)
|
|||||||
|
|
||||||
-- Append file.
|
-- Append file.
|
||||||
command=command..' --file="'..tostring(soundfile)..'"'
|
command=command..' --file="'..tostring(soundfile)..'"'
|
||||||
|
command=string.gsub(command,"--ssml","-h")
|
||||||
|
|
||||||
-- Execute command.
|
-- Execute command.
|
||||||
self:_ExecCommand(command)
|
self:_ExecCommand(command)
|
||||||
|
|
||||||
@@ -1414,7 +1572,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
|
|||||||
elseif self.provider==MSRS.Provider.WINDOWS then
|
elseif self.provider==MSRS.Provider.WINDOWS then
|
||||||
-- Nothing to do.
|
-- Nothing to do.
|
||||||
else
|
else
|
||||||
self:E("ERROR: SRS only supports WINWOWS and GOOGLE as TTS providers! Use DCS-gRPC backend for other providers such as ")
|
self:E("ERROR: SRS only supports WINDOWS and GOOGLE as TTS providers! Use DCS-gRPC backend for other providers such as AWS and Azure.")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not UTILS.FileExists(fullPath) then
|
if not UTILS.FileExists(fullPath) then
|
||||||
@@ -1449,7 +1607,7 @@ function MSRS:_ExecCommand(command)
|
|||||||
if self.UsePowerShell == true then
|
if self.UsePowerShell == true then
|
||||||
filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".ps1"
|
filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".ps1"
|
||||||
batContent = command .. "\'"
|
batContent = command .. "\'"
|
||||||
self:I({batContent=batContent})
|
self:T({batContent=batContent})
|
||||||
end
|
end
|
||||||
|
|
||||||
local script=io.open(filename, "w+")
|
local script=io.open(filename, "w+")
|
||||||
@@ -1632,11 +1790,11 @@ function MSRS:_DCSgRPCtts(Text, Frequencies, Gender, Culture, Voice, Volume, Lab
|
|||||||
ssml=string.format("<voice%s%s>%s</voice>", gender, language, Text)
|
ssml=string.format("<voice%s%s>%s</voice>", gender, language, Text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,freq in pairs(Frequencies) do
|
for _,freq in pairs(Frequencies) do
|
||||||
self:F("Calling GRPC.tts with the following parameter:")
|
self:T("Calling GRPC.tts with the following parameter:")
|
||||||
self:F({ssml=ssml, freq=freq, options=options})
|
self:T({ssml=ssml, freq=freq, options=options})
|
||||||
self:F(options.provider[provider])
|
self:T(options.provider[provider])
|
||||||
GRPC.tts(ssml, freq*1e6, options)
|
GRPC.tts(ssml, freq*1e6, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1958,7 +2116,7 @@ end
|
|||||||
-- @param Core.Point#COORDINATE coordinate Coordinate to be used
|
-- @param Core.Point#COORDINATE coordinate Coordinate to be used
|
||||||
-- @return #MSRSQUEUE.Transmission Radio transmission table.
|
-- @return #MSRSQUEUE.Transmission Radio transmission table.
|
||||||
function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgroups, subtitle, subduration, frequency, modulation, gender, culture, voice, volume, label,coordinate)
|
function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgroups, subtitle, subduration, frequency, modulation, gender, culture, voice, volume, label,coordinate)
|
||||||
|
self:T({Text=text, Dur=duration, start=tstart, int=interval, sub=subgroups, subt=subtitle, sudb=subduration, F=frequency, M=modulation, G=gender, C=culture, V=voice, Vol=volume, L=label})
|
||||||
if self.TransmitOnlyWithPlayers then
|
if self.TransmitOnlyWithPlayers then
|
||||||
if self.PlayerSet and self.PlayerSet:CountAlive() == 0 then
|
if self.PlayerSet and self.PlayerSet:CountAlive() == 0 then
|
||||||
return self
|
return self
|
||||||
@@ -1998,7 +2156,7 @@ function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgr
|
|||||||
transmission.volume = volume or msrs.volume
|
transmission.volume = volume or msrs.volume
|
||||||
transmission.label = label or msrs.Label
|
transmission.label = label or msrs.Label
|
||||||
transmission.coordinate = coordinate or msrs.coordinate
|
transmission.coordinate = coordinate or msrs.coordinate
|
||||||
|
|
||||||
-- Add transmission to queue.
|
-- Add transmission to queue.
|
||||||
self:AddTransmission(transmission)
|
self:AddTransmission(transmission)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
-- ## Features:
|
-- ## Features:
|
||||||
--
|
--
|
||||||
-- * Create a SOUNDFILE object (mp3 or ogg) to be played via DCS or SRS transmissions
|
-- * Create a SOUNDFILE object (mp3 or ogg) to be played via DCS or SRS transmissions
|
||||||
-- * Create a SOUNDTEXT object for text-to-speech output vis SRS Simple-Text-To-Speech (STTS)
|
-- * Create a SOUNDTEXT object for text-to-speech output vis SRS Simple-Text-To-Speech (MSRS)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
--- Governs multiple missions, the tasking and the reporting.
|
--- Governs multiple missions, the tasking and the reporting.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- Command centers govern missions, communicates the task assignments between human players of the coalition, and manages the menu flow.
|
-- Command centers govern missions, communicates the task assignments between human players of the coalition, and manages the menu flow.
|
||||||
-- It can assign a random task to a player when requested.
|
-- It can assign a random task to a player when requested.
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
-- The @{#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
|
-- The @{#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
|
||||||
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
|
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 1.1) DETECTION_MANAGER constructor:
|
-- 1.1) DETECTION_MANAGER constructor:
|
||||||
-- -----------------------------------
|
-- -----------------------------------
|
||||||
-- * @{#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
|
-- * @{#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
--- Models goals to be achieved and can contain multiple tasks to be executed to achieve the goals.
|
--- Models goals to be achieved and can contain multiple tasks to be executed to achieve the goals.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- A mission contains multiple tasks and can be of different task types.
|
-- A mission contains multiple tasks and can be of different task types.
|
||||||
-- These tasks need to be assigned to human players to be executed.
|
-- These tasks need to be assigned to human players to be executed.
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # 1) Tasking from a player perspective.
|
-- # 1) Tasking from a player perspective.
|
||||||
--
|
--
|
||||||
-- Tasking can be controlled by using the "other" menu in the radio menu of the player group.
|
-- Tasking can be controlled by using the "other" menu in the radio menu of the player group.
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
---
|
---
|
||||||
-- # TASKINFO class, extends @{Core.Base#BASE}
|
-- # TASKINFO class, extends @{Core.Base#BASE}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ## The TASKINFO class implements the methods to contain information and display information of a task.
|
-- ## The TASKINFO class implements the methods to contain information and display information of a task.
|
||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ do -- TASK_A2A
|
|||||||
|
|
||||||
--- Defines Air To Air tasks for a @{Core.Set} of Target Units,
|
--- Defines Air To Air tasks for a @{Core.Set} of Target Units,
|
||||||
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The TASK_A2A is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
-- The TASK_A2A is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
||||||
--
|
--
|
||||||
-- * **None**: Start of the process
|
-- * **None**: Start of the process
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||||
|
|
||||||
--- Orchestrates the dynamic dispatching of tasks upon groups of detected units determined a @{Core.Set} of EWR installation groups.
|
--- Orchestrates the dynamic dispatching of tasks upon groups of detected units determined a @{Core.Set} of EWR installation groups.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ do -- TASK_A2G
|
|||||||
|
|
||||||
--- The TASK_A2G class defines Air To Ground tasks for a @{Core.Set} of Target Units,
|
--- The TASK_A2G class defines Air To Ground tasks for a @{Core.Set} of Target Units,
|
||||||
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The TASK_A2G is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
-- The TASK_A2G is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
||||||
--
|
--
|
||||||
-- * **None**: Start of the process
|
-- * **None**: Start of the process
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||||
|
|
||||||
--- Orchestrates dynamic **A2G Task Dispatching** based on the detection results of a linked @{Functional.Detection} object.
|
--- Orchestrates dynamic **A2G Task Dispatching** based on the detection results of a linked @{Functional.Detection} object.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- It uses the Tasking System within the MOOSE framework, which is a multi-player Tasking Orchestration system.
|
-- It uses the Tasking System within the MOOSE framework, which is a multi-player Tasking Orchestration system.
|
||||||
-- It provides a truly dynamic battle environment for pilots and ground commanders to engage upon,
|
-- It provides a truly dynamic battle environment for pilots and ground commanders to engage upon,
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ## Test Missions:
|
-- ## Test Missions:
|
||||||
--
|
--
|
||||||
-- Test missions can be located on the main GITHUB site.
|
-- Test missions can be located on the main GITHUB site.
|
||||||
@@ -1176,7 +1178,7 @@ do -- TASK_CARGO
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
|
--@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
|
||||||
function TASK_CARGO:SetSmokeColor(SmokeColor)
|
function TASK_CARGO:SetSmokeColor(SmokeColor)
|
||||||
-- Makes sure Coloe is set
|
-- Makes sure Coloe is set
|
||||||
if SmokeColor == nil then
|
if SmokeColor == nil then
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ do -- TASK_CAPTURE_DISPATCHER
|
|||||||
|
|
||||||
--- Implements the dynamic dispatching of capture zone tasks.
|
--- Implements the dynamic dispatching of capture zone tasks.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The **TASK_CAPTURE_DISPATCHER** allows you to setup various tasks for let human
|
-- The **TASK_CAPTURE_DISPATCHER** allows you to setup various tasks for let human
|
||||||
-- players capture zones in a co-operation effort.
|
-- players capture zones in a co-operation effort.
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ do -- TASK_ZONE_GOAL
|
|||||||
|
|
||||||
--- # TASK_ZONE_GOAL class, extends @{Tasking.Task#TASK}
|
--- # TASK_ZONE_GOAL class, extends @{Tasking.Task#TASK}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
|
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
|
||||||
-- The TASK_ZONE_GOAL is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
-- The TASK_ZONE_GOAL is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -44,6 +44,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Please read through the @{Tasking.Task_CARGO} process to understand the mechanisms of tasking and cargo tasking and handling.
|
-- Please read through the @{Tasking.Task_CARGO} process to understand the mechanisms of tasking and cargo tasking and handling.
|
||||||
--
|
--
|
||||||
-- The cargo will be a downed pilot, which is located somwhere on the battlefield. Use the menus system and facilities to
|
-- The cargo will be a downed pilot, which is located somwhere on the battlefield. Use the menus system and facilities to
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
|
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
|
||||||
-- players transport cargo as part of a task.
|
-- players transport cargo as part of a task.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- The cargo dispatcher will implement for you mechanisms to create cargo transportation tasks:
|
-- The cargo dispatcher will implement for you mechanisms to create cargo transportation tasks:
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--- **Tasking** - Models tasks for players to transport cargo.
|
--- **Tasking** - Models tasks for players to transport cargo.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- **Specific features:**
|
-- **Specific features:**
|
||||||
--
|
--
|
||||||
-- * Creates a task to transport #Cargo.Cargo to and between deployment zones.
|
-- * Creates a task to transport #Cargo.Cargo to and between deployment zones.
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 1) @{Tasking.Task_Manager#TASK_MANAGER} class, extends @{Core.Fsm#FSM}
|
-- 1) @{Tasking.Task_Manager#TASK_MANAGER} class, extends @{Core.Fsm#FSM}
|
||||||
-- ===
|
-- ===
|
||||||
-- The @{Tasking.Task_Manager#TASK_MANAGER} class defines the core functions to report tasks to groups.
|
-- The @{Tasking.Task_Manager#TASK_MANAGER} class defines the core functions to report tasks to groups.
|
||||||
|
|||||||
@@ -1166,6 +1166,127 @@ ENUMS.Storage.weapons.bombs.AGM_62 = "weapons.bombs.AGM_62"
|
|||||||
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_WHITE = "weapons.containers.{US_M10_SMOKE_TANK_WHITE}"
|
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_WHITE = "weapons.containers.{US_M10_SMOKE_TANK_WHITE}"
|
||||||
ENUMS.Storage.weapons.missiles.MICA_T = "weapons.missiles.MICA_T"
|
ENUMS.Storage.weapons.missiles.MICA_T = "weapons.missiles.MICA_T"
|
||||||
ENUMS.Storage.weapons.containers.HVAR_rocket = "weapons.containers.HVAR_rocket"
|
ENUMS.Storage.weapons.containers.HVAR_rocket = "weapons.containers.HVAR_rocket"
|
||||||
|
-- 2025
|
||||||
|
ENUMS.Storage.weapons.containers.LANTIRN = "weapons.containers.LANTIRN"
|
||||||
|
ENUMS.Storage.weapons.missiles.AGM_78B = "weapons.missiles.AGM_78B"
|
||||||
|
ENUMS.Storage.weapons.containers.uh_60l_pilot = "weapons.containers.uh-60l_pilot"
|
||||||
|
ENUMS.Storage.weapons.missiles.AIM_92E = "weapons.missiles.AIM-92E"
|
||||||
|
ENUMS.Storage.weapons.missiles.KD_63B = "weapons.missiles.KD_63B"
|
||||||
|
ENUMS.Storage.weapons.bombs.Type_200A = "weapons.bombs.Type_200A"
|
||||||
|
ENUMS.Storage.weapons.missiles.HB_AIM_7E_2 = "weapons.missiles.HB-AIM-7E-2"
|
||||||
|
ENUMS.Storage.weapons.containers.Spear = "weapons.containers.Spear"
|
||||||
|
ENUMS.Storage.weapons.missiles.LS_6 = "weapons.missiles.LS_6"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ALE_40_0_120 = "weapons.containers.HB_ALE_40_0_120"
|
||||||
|
ENUMS.Storage.weapons.containers.Fantasm = "weapons.containers.Fantasm"
|
||||||
|
ENUMS.Storage.weapons.nurs.FFAR_Mk61 = "weapons.nurs.FFAR_Mk61"
|
||||||
|
ENUMS.Storage.weapons.bombs.HB_F4E_GBU15V1 = "weapons.bombs.HB_F4E_GBU15V1"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_F14_EXT_AN_APQ_167 = "weapons.containers.HB_F14_EXT_AN_APQ-167"
|
||||||
|
ENUMS.Storage.weapons.nurs.LWL_RP = "weapons.nurs.LWL_RP"
|
||||||
|
ENUMS.Storage.weapons.bombs.AGM_62_I = "weapons.bombs.AGM_62_I"
|
||||||
|
ENUMS.Storage.weapons.containers.ETHER = "weapons.containers.ETHER"
|
||||||
|
ENUMS.Storage.weapons.containers.TANGAZH = "weapons.containers.TANGAZH"
|
||||||
|
ENUMS.Storage.weapons.bombs.LYSBOMB_11086 = "weapons.bombs.LYSBOMB 11086"
|
||||||
|
ENUMS.Storage.weapons.containers.Stub_Wing = "weapons.containers.Stub_Wing"
|
||||||
|
ENUMS.Storage.weapons.missiles.AIM_9E = "weapons.missiles.AIM-9E"
|
||||||
|
ENUMS.Storage.weapons.missiles.C_701T = "weapons.missiles.C_701T"
|
||||||
|
ENUMS.Storage.weapons.bombs.BAP_100 = "weapons.bombs.BAP_100"
|
||||||
|
ENUMS.Storage.weapons.missiles.CM_802AKG = "weapons.missiles.CM-802AKG"
|
||||||
|
ENUMS.Storage.weapons.missiles.CM_400AKG = "weapons.missiles.CM-400AKG"
|
||||||
|
ENUMS.Storage.weapons.missiles.C_802AK = "weapons.missiles.C_802AK"
|
||||||
|
ENUMS.Storage.weapons.missiles.KD_63 = "weapons.missiles.KD_63"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ORD_Pave_Spike_Fast = "weapons.containers.HB_ORD_Pave_Spike_Fast"
|
||||||
|
ENUMS.Storage.weapons.missiles.SPIKE_ER2 = "weapons.missiles.SPIKE_ER2"
|
||||||
|
ENUMS.Storage.weapons.containers.KINGAL = "weapons.containers.KINGAL"
|
||||||
|
ENUMS.Storage.weapons.containers.LANTIRN_F14_TARGET = "weapons.containers.LANTIRN-F14-TARGET"
|
||||||
|
ENUMS.Storage.weapons.containers.SPS_141 = "weapons.containers.SPS-141"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_3B_GROUP = "weapons.bombs.BLU-3B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ALE_40_30_0 = "weapons.containers.HB_ALE_40_30_0"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_HIGH_PERFORMANCE_CENTERLINE_600_GAL = "weapons.droptanks.HB_HIGH_PERFORMANCE_CENTERLINE_600_GAL"
|
||||||
|
ENUMS.Storage.weapons.containers.ALQ_184 = "weapons.containers.ALQ-184"
|
||||||
|
ENUMS.Storage.weapons.missiles.AGM_45B = "weapons.missiles.AGM_45B"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_3_GROUP = "weapons.bombs.BLU-3_GROUP"
|
||||||
|
ENUMS.Storage.weapons.missiles.SPIKE_ER = "weapons.missiles.SPIKE_ER"
|
||||||
|
ENUMS.Storage.weapons.nurs.ARAKM70BAPPX = "weapons.nurs.ARAKM70BAPPX"
|
||||||
|
ENUMS.Storage.weapons.bombs.LYSBOMB_11088 = "weapons.bombs.LYSBOMB 11088"
|
||||||
|
ENUMS.Storage.weapons.bombs.LYSBOMB_11087 = "weapons.bombs.LYSBOMB 11087"
|
||||||
|
ENUMS.Storage.weapons.missiles.KD_20 = "weapons.missiles.KD_20"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_F_4E_EXT_WingTank = "weapons.droptanks.HB_F-4E_EXT_WingTank"
|
||||||
|
ENUMS.Storage.weapons.missiles.Rb_04 = "weapons.missiles.Rb_04"
|
||||||
|
ENUMS.Storage.weapons.containers.AAQ_33 = "weapons.containers.AAQ-33"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_F_4E_EXT_Center_Fuel_Tank_EMPTY = "weapons.droptanks.HB_F-4E_EXT_Center_Fuel_Tank_EMPTY"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_F_4E_EXT_WingTank_R_EMPTY = "weapons.droptanks.HB_F-4E_EXT_WingTank_R_EMPTY"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_F_4E_EXT_WingTank_EMPTY = "weapons.droptanks.HB_F-4E_EXT_WingTank_EMPTY"
|
||||||
|
ENUMS.Storage.weapons.containers.uh_60l_copilot = "weapons.containers.uh-60l_copilot"
|
||||||
|
ENUMS.Storage.weapons.droptanks.JAYHAWK_80gal_Fuel_Tankv2 = "weapons.droptanks.JAYHAWK_80gal_Fuel_Tankv2"
|
||||||
|
ENUMS.Storage.weapons.containers.supply_m134 = "weapons.containers.supply_m134"
|
||||||
|
ENUMS.Storage.weapons.containers.Seahawk_Pylon = "weapons.containers.Seahawk_Pylon"
|
||||||
|
ENUMS.Storage.weapons.nurs.LWL_MPP = "weapons.nurs.LWL_MPP"
|
||||||
|
ENUMS.Storage.weapons.nurs.S_5KP = "weapons.nurs.S_5KP"
|
||||||
|
ENUMS.Storage.weapons.missiles.AIM_92J = "weapons.missiles.AIM-92J"
|
||||||
|
ENUMS.Storage.weapons.missiles.HB_AIM_7E = "weapons.missiles.HB-AIM-7E"
|
||||||
|
ENUMS.Storage.weapons.containers.ALQ_131 = "weapons.containers.ALQ-131"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_F14_EXT_TARPS = "weapons.containers.HB_F14_EXT_TARPS"
|
||||||
|
ENUMS.Storage.weapons.containers.MH60_SOAR = "weapons.containers.MH60_SOAR"
|
||||||
|
ENUMS.Storage.weapons.missiles.YJ_83 = "weapons.missiles.YJ-83"
|
||||||
|
ENUMS.Storage.weapons.bombs.GBU_8_B = "weapons.bombs.GBU_8_B"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_F14_EXT_ECA = "weapons.containers.HB_F14_EXT_ECA"
|
||||||
|
ENUMS.Storage.weapons.bombs.BAP_100 = "weapons.bombs.BAP-100"
|
||||||
|
ENUMS.Storage.weapons.nurs.M261_MPSM_Rocket = "weapons.nurs.M261_MPSM_Rocket"
|
||||||
|
ENUMS.Storage.weapons.droptanks.SEAHAWK_120_Fuel_Tank = "weapons.droptanks.SEAHAWK_120_Fuel_Tank"
|
||||||
|
ENUMS.Storage.weapons.containers.SHPIL = "weapons.containers.SHPIL"
|
||||||
|
ENUMS.Storage.weapons.bombs.GBU_39 = "weapons.bombs.GBU_39"
|
||||||
|
ENUMS.Storage.weapons.nurs.S_5M = "weapons.nurs.S_5M"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ALE_40_15_90 = "weapons.containers.HB_ALE_40_15_90"
|
||||||
|
ENUMS.Storage.weapons.missiles.AIM_7E = "weapons.missiles.AIM-7E"
|
||||||
|
ENUMS.Storage.weapons.missiles.AIM_9P3 = "weapons.missiles.AIM-9P3"
|
||||||
|
ENUMS.Storage.weapons.missiles.AGM_12B = "weapons.missiles.AGM_12B"
|
||||||
|
ENUMS.Storage.weapons.missiles.CM_802AKG = "weapons.missiles.CM_802AKG"
|
||||||
|
ENUMS.Storage.weapons.droptanks.JAYHAWK_120_Fuel_Dual_Tank = "weapons.droptanks.JAYHAWK_120_Fuel_Dual_Tank"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_F_4E_EXT_Center_Fuel_Tank = "weapons.droptanks.HB_F-4E_EXT_Center_Fuel_Tank"
|
||||||
|
ENUMS.Storage.weapons.containers.PAVETACK = "weapons.containers.PAVETACK"
|
||||||
|
ENUMS.Storage.weapons.missiles.LS_6_500 = "weapons.missiles.LS_6_500"
|
||||||
|
ENUMS.Storage.weapons.bombs.LYSBOMB_11089 = "weapons.bombs.LYSBOMB 11089"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_4B_GROUP = "weapons.bombs.BLU-4B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.containers.ah_64d_radar = "weapons.containers.ah-64d_radar"
|
||||||
|
ENUMS.Storage.weapons.containers.F_18_LDT_POD = "weapons.containers.F-18-LDT-POD"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ALE_40_30_60 = "weapons.containers.HB_ALE_40_30_60"
|
||||||
|
ENUMS.Storage.weapons.bombs.LS_6_100 = "weapons.bombs.LS_6_100"
|
||||||
|
ENUMS.Storage.weapons.droptanks.HB_F_4E_EXT_WingTank_R = "weapons.droptanks.HB_F-4E_EXT_WingTank_R"
|
||||||
|
ENUMS.Storage.weapons.containers.SORBCIJA_R = "weapons.containers.SORBCIJA_R"
|
||||||
|
ENUMS.Storage.weapons.missiles.CATM_65K = "weapons.missiles.CATM_65K"
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ORD_Pave_Spike = "weapons.containers.HB_ORD_Pave_Spike"
|
||||||
|
ENUMS.Storage.weapons.containers.RobbieTank1 = "weapons.containers.RobbieTank1"
|
||||||
|
ENUMS.Storage.weapons.containers.SKY_SHADOW = "weapons.containers.SKY_SHADOW"
|
||||||
|
ENUMS.Storage.weapons.containers.SORBCIJA_L = "weapons.containers.SORBCIJA_L"
|
||||||
|
ENUMS.Storage.weapons.containers.Pavehawk = "weapons.containers.Pavehawk"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLG66_EG = "weapons.bombs.BLG66_EG"
|
||||||
|
ENUMS.Storage.weapons.missiles.AGM_12C_ED = "weapons.missiles.AGM_12C_ED"
|
||||||
|
ENUMS.Storage.weapons.missiles.AIM_92C = "weapons.missiles.AIM-92C"
|
||||||
|
ENUMS.Storage.weapons.containers.MPS_410 = "weapons.containers.MPS-410"
|
||||||
|
ENUMS.Storage.weapons.missiles.HJ_12 = "weapons.missiles.HJ-12"
|
||||||
|
ENUMS.Storage.weapons.containers.AAQ_28_LITENING = "weapons.containers.AAQ-28_LITENING"
|
||||||
|
ENUMS.Storage.weapons.containers.F_18_FLIR_POD = "weapons.containers.F-18-FLIR-POD"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_3B_GROUP = "weapons.bombs.BLU_3B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.containers.UH60L_Jayhawk = "weapons.containers.UH60L_Jayhawk"
|
||||||
|
ENUMS.Storage.weapons.containers.BOZ_100 = "weapons.containers.BOZ-100"
|
||||||
|
ENUMS.Storage.weapons.missiles.AGM_78A = "weapons.missiles.AGM_78A"
|
||||||
|
ENUMS.Storage.weapons.missiles.LAU_61_APKWS_M282 = "weapons.missiles.LAU_61_APKWS_M282"
|
||||||
|
ENUMS.Storage.weapons.bombs.BAP_100 = "weapons.bombs.BAP-100"
|
||||||
|
ENUMS.Storage.weapons.missiles.CM_802AKG = "weapons.missiles.CM-802AKG"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_3B_GROUP = "weapons.bombs.BLU_3B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_4B_GROUP = "weapons.bombs.BLU-4B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.nurs.S_5M = "weapons.nurs.S_5M"
|
||||||
|
ENUMS.Storage.weapons.missiles.AGM_12A = "weapons.missiles.AGM_12A"
|
||||||
|
ENUMS.Storage.weapons.droptanks.JAYHAWK_120_Fuel_Tank = "weapons.droptanks.JAYHAWK_120_Fuel_Tank"
|
||||||
|
ENUMS.Storage.weapons.bombs.GBU_15_V_1_B = "weapons.bombs.GBU_15_V_1_B"
|
||||||
|
ENUMS.Storage.weapons.missiles.HYDRA_70_M151_APKWS = {4,4,8,292}
|
||||||
|
ENUMS.Storage.weapons.missiles.HYDRA_70_M282_APKWS = {4,4,8,293}
|
||||||
|
-- dupes with typos
|
||||||
|
ENUMS.Storage.weapons.bombs.BAP100 = "weapons.bombs.BAP_100"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU3B_GROUP = "weapons.bombs.BLU-3B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.missiles.CM_802AKG = "weapons.missiles.CM_802AKG"
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_4B_GROUP = "weapons.bombs.BLU_4B_GROUP"
|
||||||
|
ENUMS.Storage.weapons.nurs.S5M = "weapons.nurs.S-5M"
|
||||||
-- Gazelle
|
-- Gazelle
|
||||||
ENUMS.Storage.weapons.Gazelle.HMP400_100RDS = {4,15,46,1771}
|
ENUMS.Storage.weapons.Gazelle.HMP400_100RDS = {4,15,46,1771}
|
||||||
ENUMS.Storage.weapons.Gazelle.HMP400_200RDS = {4,15,46,1770}
|
ENUMS.Storage.weapons.Gazelle.HMP400_200RDS = {4,15,46,1770}
|
||||||
@@ -1177,16 +1298,16 @@ ENUMS.Storage.weapons.Gazelle.GIAT_M261_HEAP = {4,15,46,1765}
|
|||||||
ENUMS.Storage.weapons.Gazelle.GIAT_M261_APHE = {4,15,46,1764}
|
ENUMS.Storage.weapons.Gazelle.GIAT_M261_APHE = {4,15,46,1764}
|
||||||
ENUMS.Storage.weapons.Gazelle.GAZELLE_IR_DEFLECTOR = {4,15,47,680}
|
ENUMS.Storage.weapons.Gazelle.GAZELLE_IR_DEFLECTOR = {4,15,47,680}
|
||||||
ENUMS.Storage.weapons.Gazelle.GAZELLE_FAS_SANDFILTER = {4,15,47,679}
|
ENUMS.Storage.weapons.Gazelle.GAZELLE_FAS_SANDFILTER = {4,15,47,679}
|
||||||
-- Chinook
|
-- Chinook (changed)
|
||||||
ENUMS.Storage.weapons.CH47.CH47_PORT_M60D = {4,15,46,2476}
|
ENUMS.Storage.weapons.CH47.CH47_PORT_M60D = {4,15,46,2489}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_STBD_M60D = {4,15,46,2477}
|
ENUMS.Storage.weapons.CH47.CH47_STBD_M60D = {4,15,46,2488}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_AFT_M60D = {4,15,46,2478}
|
ENUMS.Storage.weapons.CH47.CH47_AFT_M60D = {4,15,46,2490}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_PORT_M134D = {4,15,46,2482}
|
ENUMS.Storage.weapons.CH47.CH47_PORT_M134D = {4,15,46,2494}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_STBD_M134D = {4,15,46,2483}
|
ENUMS.Storage.weapons.CH47.CH47_STBD_M134D = {4,15,46,2495}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_AFT_M3M = {4,15,46,2484}
|
ENUMS.Storage.weapons.CH47.CH47_AFT_M3M = {4,15,46,2496} --
|
||||||
ENUMS.Storage.weapons.CH47.CH47_PORT_M240H = {4,15,46,2479}
|
ENUMS.Storage.weapons.CH47.CH47_PORT_M240H = {4,15,46,2492}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_STBD_M240H = {4,15,46,2480}
|
ENUMS.Storage.weapons.CH47.CH47_STBD_M240H = {4,15,46,2491}
|
||||||
ENUMS.Storage.weapons.CH47.CH47_AFT_M240H = {4,15,46,2481}
|
ENUMS.Storage.weapons.CH47.CH47_AFT_M240H = {4,15,46,2493}
|
||||||
-- Huey
|
-- Huey
|
||||||
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Right = {4,15,46,161}
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Right = {4,15,46,161}
|
||||||
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left = {4,15,46,160}
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left = {4,15,46,160}
|
||||||
@@ -1196,20 +1317,26 @@ ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left_Door = {4,15,46,174}
|
|||||||
ENUMS.Storage.weapons.UH1H.M60_MG_Left_Door = {4,15,46,176}
|
ENUMS.Storage.weapons.UH1H.M60_MG_Left_Door = {4,15,46,176}
|
||||||
-- Kiowa
|
-- Kiowa
|
||||||
ENUMS.Storage.weapons.OH58.FIM92 = {4,4,7,449}
|
ENUMS.Storage.weapons.OH58.FIM92 = {4,4,7,449}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P100 = {4,15,46,2608}
|
ENUMS.Storage.weapons.OH58.MG_M3P100 = {4,15,46,2611}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P200 = {4,15,46,2607}
|
ENUMS.Storage.weapons.OH58.MG_M3P200 = {4,15,46,2610}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P300 = {4,15,46,2606}
|
ENUMS.Storage.weapons.OH58.MG_M3P300 = {4,15,46,2609}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P400 = {4,15,46,2605}
|
ENUMS.Storage.weapons.OH58.MG_M3P400 = {4,15,46,2608}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P500 = {4,15,46,2604}
|
ENUMS.Storage.weapons.OH58.MG_M3P500 = {4,15,46,2607}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Blue = {4,5,9,486}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Blue = {4,5,9,488}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Green = {4,5,9,487}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Green = {4,5,9,489}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Red = {4,5,9,485}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Red = {4,5,9,487}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Violet = {4,5,9,488}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Violet = {4,5,9,490}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_White = {4,5,9,490}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_White = {4,5,9,492}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,489}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,491}
|
||||||
-- Apache
|
-- Apache
|
||||||
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2138}
|
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2114}
|
||||||
ENUMS.Storage.weapons.AH64D.Internal_Aux_FuelTank = {1,3,43,1700}
|
ENUMS.Storage.weapons.AH64D.Internal_Aux_FuelTank = {1,3,43,1700}
|
||||||
|
-- Other - but cannot set or track those. Harrier stuff?
|
||||||
|
ENUMS.Storage.weapons.droptanks.FuelTank_610gal = {1,3,43,10}
|
||||||
|
ENUMS.Storage.weapons.droptanks.FuelTank_370gal = {1,3,43,11}
|
||||||
|
ENUMS.Storage.weapons.containers.AV8BNA_GAU_12_AP_M79 = {4,15,46,824}
|
||||||
|
ENUMS.Storage.weapons.containers.AV8BNA_GAU_12_HE_M792 = {4,15,46,825}
|
||||||
|
ENUMS.Storage.weapons.containers.AV8BNA_GAU_12_SAPHEI_T = {4,15,46,300}
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @type ENUMS.FARPType
|
-- @type ENUMS.FARPType
|
||||||
@@ -1237,3 +1364,4 @@ ENUMS.FARPObjectTypeNamesAndShape ={
|
|||||||
[ENUMS.FARPType.HELIPADSINGLE] = { TypeName="SINGLE_HELIPAD", ShapeName="FARP"},
|
[ENUMS.FARPType.HELIPADSINGLE] = { TypeName="SINGLE_HELIPAD", ShapeName="FARP"},
|
||||||
[ENUMS.FARPType.PADSINGLE] = { TypeName="FARP_SINGLE_01", ShapeName="FARP_SINGLE_01"},
|
[ENUMS.FARPType.PADSINGLE] = { TypeName="FARP_SINGLE_01", ShapeName="FARP_SINGLE_01"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,259 +0,0 @@
|
|||||||
--- **Utilities** - DCS Simple Text-To-Speech (STTS).
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- @module Utilities.STTS
|
|
||||||
-- @image MOOSE.JPG
|
|
||||||
|
|
||||||
--- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world)
|
|
||||||
-- @type STTS
|
|
||||||
-- @field #string DIRECTORY Path of the SRS directory.
|
|
||||||
|
|
||||||
--- Simple Text-To-Speech
|
|
||||||
--
|
|
||||||
-- Version 0.4 - Compatible with SRS version 1.9.6.0+
|
|
||||||
--
|
|
||||||
-- # DCS Modification Required
|
|
||||||
--
|
|
||||||
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitization.
|
|
||||||
-- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)"
|
|
||||||
-- Do this without DCS running to allow mission scripts to use os functions.
|
|
||||||
--
|
|
||||||
-- *You WILL HAVE TO REAPPLY AFTER EVERY DCS UPDATE*
|
|
||||||
--
|
|
||||||
-- # USAGE:
|
|
||||||
--
|
|
||||||
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialize it
|
|
||||||
-- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission.
|
|
||||||
-- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts.
|
|
||||||
--
|
|
||||||
-- Example calls:
|
|
||||||
--
|
|
||||||
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2)
|
|
||||||
--
|
|
||||||
-- Arguments in order are:
|
|
||||||
--
|
|
||||||
-- * Message to say, make sure not to use a newline (\n) !
|
|
||||||
-- * Frequency in MHz
|
|
||||||
-- * Modulation - AM/FM
|
|
||||||
-- * Volume - 1.0 max, 0.5 half
|
|
||||||
-- * Name of the transmitter - ATC, RockFM etc
|
|
||||||
-- * Coalition - 0 spectator, 1 red 2 blue
|
|
||||||
-- * OPTIONAL - Vec3 Point i.e Unit.getByName("A UNIT"):getPoint() - needs Vec3 for Height! OR null if not needed
|
|
||||||
-- * OPTIONAL - Speed -10 to +10
|
|
||||||
-- * OPTIONAL - Gender male, female or neuter
|
|
||||||
-- * OPTIONAL - Culture - en-US, en-GB etc
|
|
||||||
-- * OPTIONAL - Voice - a specific voice by name. Run DCS-SR-ExternalAudio.exe with --help to get the ones you can use on the command line
|
|
||||||
-- * OPTIONAL - Google TTS - Switch to Google Text To Speech - Requires STTS.GOOGLE_CREDENTIALS path and Google project setup correctly
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ## Example
|
|
||||||
--
|
|
||||||
-- This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only
|
|
||||||
--
|
|
||||||
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,null,-5,"male","en-GB")
|
|
||||||
--
|
|
||||||
-- ## Example
|
|
||||||
--
|
|
||||||
-- This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT"
|
|
||||||
--
|
|
||||||
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,Unit.getByName("A UNIT"):getPoint(),-5,"male","en-GB")
|
|
||||||
--
|
|
||||||
-- Arguments in order are:
|
|
||||||
--
|
|
||||||
-- * FULL path to the MP3 OR OGG to play
|
|
||||||
-- * Frequency in MHz - to use multiple separate with a comma - Number of frequencies MUST match number of Modulations
|
|
||||||
-- * Modulation - AM/FM - to use multiple
|
|
||||||
-- * Volume - 1.0 max, 0.5 half
|
|
||||||
-- * Name of the transmitter - ATC, RockFM etc
|
|
||||||
-- * Coalition - 0 spectator, 1 red 2 blue
|
|
||||||
--
|
|
||||||
-- ## Example
|
|
||||||
--
|
|
||||||
-- This will play that MP3 on 255MHz AM & 31 FM at half volume with a client called "Multiple" and to Spectators only
|
|
||||||
--
|
|
||||||
-- STTS.PlayMP3("C:\\Users\\Ciaran\\Downloads\\PR-Music.mp3","255,31","AM,FM","0.5","Multiple",0)
|
|
||||||
--
|
|
||||||
-- @field #STTS
|
|
||||||
STTS = {
|
|
||||||
ClassName = "STTS",
|
|
||||||
DIRECTORY = "",
|
|
||||||
SRS_PORT = 5002,
|
|
||||||
GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json",
|
|
||||||
EXECUTABLE = "DCS-SR-ExternalAudio.exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
--- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER
|
|
||||||
STTS.DIRECTORY = "D:/DCS/_SRS"
|
|
||||||
|
|
||||||
--- LOCAL SRS PORT - DEFAULT IS 5002
|
|
||||||
STTS.SRS_PORT = 5002
|
|
||||||
|
|
||||||
--- Google credentials file
|
|
||||||
STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json"
|
|
||||||
|
|
||||||
--- DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
|
|
||||||
STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe"
|
|
||||||
|
|
||||||
--- Function for UUID.
|
|
||||||
function STTS.uuid()
|
|
||||||
local random = math.random
|
|
||||||
local template = 'yxxx-xxxxxxxxxxxx'
|
|
||||||
return string.gsub( template, '[xy]', function( c )
|
|
||||||
local v = (c == 'x') and random( 0, 0xf ) or random( 8, 0xb )
|
|
||||||
return string.format( '%x', v )
|
|
||||||
end )
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Round a number.
|
|
||||||
-- @param #number x Number.
|
|
||||||
-- @param #number n Precision.
|
|
||||||
function STTS.round( x, n )
|
|
||||||
n = math.pow( 10, n or 0 )
|
|
||||||
x = x * n
|
|
||||||
if x >= 0 then
|
|
||||||
x = math.floor( x + 0.5 )
|
|
||||||
else
|
|
||||||
x = math.ceil( x - 0.5 )
|
|
||||||
end
|
|
||||||
return x / n
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Function returns estimated speech time in seconds.
|
|
||||||
-- Assumptions for time calc: 100 Words per min, average of 5 letters for english word so
|
|
||||||
--
|
|
||||||
-- * 5 chars * 100wpm = 500 characters per min = 8.3 chars per second
|
|
||||||
--
|
|
||||||
-- So length of msg / 8.3 = number of seconds needed to read it. rounded down to 8 chars per sec map function:
|
|
||||||
--
|
|
||||||
-- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
|
|
||||||
--
|
|
||||||
-- @param #number length can also be passed as #string
|
|
||||||
-- @param #number speed Defaults to 1.0
|
|
||||||
-- @param #boolean isGoogle We're using Google TTS
|
|
||||||
function STTS.getSpeechTime(length,speed,isGoogle)
|
|
||||||
|
|
||||||
local maxRateRatio = 3
|
|
||||||
|
|
||||||
speed = speed or 1.0
|
|
||||||
isGoogle = isGoogle or false
|
|
||||||
|
|
||||||
local speedFactor = 1.0
|
|
||||||
if isGoogle then
|
|
||||||
speedFactor = speed
|
|
||||||
else
|
|
||||||
if speed ~= 0 then
|
|
||||||
speedFactor = math.abs( speed ) * (maxRateRatio - 1) / 10 + 1
|
|
||||||
end
|
|
||||||
if speed < 0 then
|
|
||||||
speedFactor = 1 / speedFactor
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local wpm = math.ceil( 100 * speedFactor )
|
|
||||||
local cps = math.floor( (wpm * 5) / 60 )
|
|
||||||
|
|
||||||
if type( length ) == "string" then
|
|
||||||
length = string.len( length )
|
|
||||||
end
|
|
||||||
|
|
||||||
return length/cps --math.ceil(length/cps)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Text to speech function.
|
|
||||||
function STTS.TextToSpeech( message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS )
|
|
||||||
if os == nil or io == nil then
|
|
||||||
env.info( "[DCS-STTS] LUA modules os or io are sanitized. skipping. " )
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
speed = speed or 1
|
|
||||||
gender = gender or "female"
|
|
||||||
culture = culture or ""
|
|
||||||
voice = voice or ""
|
|
||||||
coalition = coalition or "0"
|
|
||||||
name = name or "ROBOT"
|
|
||||||
volume = 1
|
|
||||||
speed = 1
|
|
||||||
|
|
||||||
message = message:gsub( "\"", "\\\"" )
|
|
||||||
|
|
||||||
local cmd = string.format( "start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name )
|
|
||||||
|
|
||||||
if voice ~= "" then
|
|
||||||
cmd = cmd .. string.format( " -V \"%s\"", voice )
|
|
||||||
else
|
|
||||||
|
|
||||||
if culture ~= "" then
|
|
||||||
cmd = cmd .. string.format( " -l %s", culture )
|
|
||||||
end
|
|
||||||
|
|
||||||
if gender ~= "" then
|
|
||||||
cmd = cmd .. string.format( " -g %s", gender )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if googleTTS == true then
|
|
||||||
cmd = cmd .. string.format( " -G \"%s\"", STTS.GOOGLE_CREDENTIALS )
|
|
||||||
end
|
|
||||||
|
|
||||||
if speed ~= 1 then
|
|
||||||
cmd = cmd .. string.format( " -s %s", speed )
|
|
||||||
end
|
|
||||||
|
|
||||||
if volume ~= 1.0 then
|
|
||||||
cmd = cmd .. string.format( " -v %s", volume )
|
|
||||||
end
|
|
||||||
|
|
||||||
if point and type( point ) == "table" and point.x then
|
|
||||||
local lat, lon, alt = coord.LOtoLL( point )
|
|
||||||
|
|
||||||
lat = STTS.round( lat, 4 )
|
|
||||||
lon = STTS.round( lon, 4 )
|
|
||||||
alt = math.floor( alt )
|
|
||||||
|
|
||||||
cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
|
|
||||||
end
|
|
||||||
|
|
||||||
cmd = cmd .. string.format( " -t \"%s\"", message )
|
|
||||||
|
|
||||||
if string.len( cmd ) > 255 then
|
|
||||||
local filename = os.getenv( 'TMP' ) .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat"
|
|
||||||
local script = io.open( filename, "w+" )
|
|
||||||
script:write( cmd .. " && exit" )
|
|
||||||
script:close()
|
|
||||||
cmd = string.format( "\"%s\"", filename )
|
|
||||||
timer.scheduleFunction( os.remove, filename, timer.getTime() + 1 )
|
|
||||||
end
|
|
||||||
|
|
||||||
if string.len( cmd ) > 255 then
|
|
||||||
env.info( "[DCS-STTS] - cmd string too long" )
|
|
||||||
env.info( "[DCS-STTS] TextToSpeech Command :\n" .. cmd .. "\n" )
|
|
||||||
end
|
|
||||||
os.execute( cmd )
|
|
||||||
|
|
||||||
return STTS.getSpeechTime( message, speed, googleTTS )
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Play mp3 function.
|
|
||||||
-- @param #string pathToMP3 Path to the sound file.
|
|
||||||
-- @param #string freqs Frequencies, e.g. "305, 256".
|
|
||||||
-- @param #string modulations Modulations, e.g. "AM, FM".
|
|
||||||
-- @param #string volume Volume, e.g. "0.5".
|
|
||||||
function STTS.PlayMP3( pathToMP3, freqs, modulations, volume, name, coalition, point )
|
|
||||||
|
|
||||||
local cmd = string.format( "start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1" )
|
|
||||||
|
|
||||||
if point and type( point ) == "table" and point.x then
|
|
||||||
local lat, lon, alt = coord.LOtoLL( point )
|
|
||||||
|
|
||||||
lat = STTS.round( lat, 4 )
|
|
||||||
lon = STTS.round( lon, 4 )
|
|
||||||
alt = math.floor( alt )
|
|
||||||
|
|
||||||
cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
|
|
||||||
end
|
|
||||||
|
|
||||||
env.info( "[DCS-STTS] MP3/OGG Command :\n" .. cmd .. "\n" )
|
|
||||||
os.execute( cmd )
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,612 +0,0 @@
|
|||||||
--- **Utilities** - Templates.
|
|
||||||
--
|
|
||||||
-- DCS unit templates
|
|
||||||
--
|
|
||||||
-- @module Utilities.Templates
|
|
||||||
-- @image MOOSE.JPG
|
|
||||||
|
|
||||||
--- TEMPLATE class.
|
|
||||||
-- @type TEMPLATE
|
|
||||||
-- @field #string ClassName Name of the class.
|
|
||||||
|
|
||||||
--- *Templates*
|
|
||||||
--
|
|
||||||
-- ===
|
|
||||||
--
|
|
||||||
-- 
|
|
||||||
--
|
|
||||||
-- Get DCS templates from thin air.
|
|
||||||
--
|
|
||||||
-- # Ground Units
|
|
||||||
--
|
|
||||||
-- Ground units.
|
|
||||||
--
|
|
||||||
-- # Naval Units
|
|
||||||
--
|
|
||||||
-- Ships are not implemented yet.
|
|
||||||
--
|
|
||||||
-- # Aircraft
|
|
||||||
--
|
|
||||||
-- ## Airplanes
|
|
||||||
--
|
|
||||||
-- Airplanes are not implemented yet.
|
|
||||||
--
|
|
||||||
-- ## Helicopters
|
|
||||||
--
|
|
||||||
-- Helicopters are not implemented yet.
|
|
||||||
--
|
|
||||||
-- @field #TEMPLATE
|
|
||||||
TEMPLATE = {
|
|
||||||
ClassName = "TEMPLATE",
|
|
||||||
Ground = {},
|
|
||||||
Naval = {},
|
|
||||||
Airplane = {},
|
|
||||||
Helicopter = {},
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Ground unit type names.
|
|
||||||
-- @type TEMPLATE.TypeGround
|
|
||||||
-- @param #string InfantryAK
|
|
||||||
TEMPLATE.TypeGround={
|
|
||||||
InfantryAK="Infantry AK",
|
|
||||||
ParatrooperAKS74="Paratrooper AKS-74",
|
|
||||||
ParatrooperRPG16="Paratrooper RPG-16",
|
|
||||||
SoldierWWIIUS="soldier_wwii_us",
|
|
||||||
InfantryM248="Infantry M249",
|
|
||||||
SoldierM4="Soldier M4",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Naval unit type names.
|
|
||||||
-- @type TEMPLATE.TypeNaval
|
|
||||||
-- @param #string Ticonderoga
|
|
||||||
TEMPLATE.TypeNaval={
|
|
||||||
Ticonderoga="TICONDEROG",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Rotary wing unit type names.
|
|
||||||
-- @type TEMPLATE.TypeAirplane
|
|
||||||
-- @param #string A10C
|
|
||||||
TEMPLATE.TypeAirplane={
|
|
||||||
A10C="A-10C",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Rotary wing unit type names.
|
|
||||||
-- @type TEMPLATE.TypeHelicopter
|
|
||||||
-- @param #string AH1W
|
|
||||||
TEMPLATE.TypeHelicopter={
|
|
||||||
AH1W="AH-1W",
|
|
||||||
}
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Ground Template
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--- Get template for ground units.
|
|
||||||
-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`.
|
|
||||||
-- @param #string GroupName Name of the spawned group. **Must be unique!**
|
|
||||||
-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to.
|
|
||||||
-- @param DCS#Vec3 Vec3 Position of the group and the first unit.
|
|
||||||
-- @param #number Nunits Number of units. Default 1.
|
|
||||||
-- @param #number Radius Spawn radius for additonal units in meters. Default 50 m.
|
|
||||||
-- @return #table Template Template table.
|
|
||||||
function TEMPLATE.GetGround(TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
-- Defaults.
|
|
||||||
TypeName=TypeName or TEMPLATE.TypeGround.SoldierM4
|
|
||||||
GroupName=GroupName or "Ground-1"
|
|
||||||
CountryID=CountryID or country.id.USA
|
|
||||||
Vec3=Vec3 or {x=0, y=0, z=0}
|
|
||||||
Nunits=Nunits or 1
|
|
||||||
Radius=Radius or 50
|
|
||||||
|
|
||||||
|
|
||||||
-- Get generic template.
|
|
||||||
local template=UTILS.DeepCopy(TEMPLATE.GenericGround)
|
|
||||||
|
|
||||||
-- Set group name.
|
|
||||||
template.name=GroupName
|
|
||||||
|
|
||||||
-- These are additional entries required by the MOOSE _DATABASE:Spawn() function.
|
|
||||||
template.CountryID=CountryID
|
|
||||||
template.CoalitionID=coalition.getCountryCoalition(template.CountryID)
|
|
||||||
template.CategoryID=Unit.Category.GROUND_UNIT
|
|
||||||
|
|
||||||
-- Set first unit.
|
|
||||||
template.units[1].type=TypeName
|
|
||||||
template.units[1].name=GroupName.."-1"
|
|
||||||
|
|
||||||
if Vec3 then
|
|
||||||
TEMPLATE.SetPositionFromVec3(template, Vec3)
|
|
||||||
end
|
|
||||||
|
|
||||||
TEMPLATE.SetUnits(template, Nunits, COORDINATE:NewFromVec3(Vec3), Radius)
|
|
||||||
|
|
||||||
return template
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Naval Template
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--- Get template for ground units.
|
|
||||||
-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`.
|
|
||||||
-- @param #string GroupName Name of the spawned group. **Must be unique!**
|
|
||||||
-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to.
|
|
||||||
-- @param DCS#Vec3 Vec3 Position of the group and the first unit.
|
|
||||||
-- @param #number Nunits Number of units. Default 1.
|
|
||||||
-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m.
|
|
||||||
-- @return #table Template Template table.
|
|
||||||
function TEMPLATE.GetNaval(TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
-- Defaults.
|
|
||||||
TypeName=TypeName or TEMPLATE.TypeNaval.Ticonderoga
|
|
||||||
GroupName=GroupName or "Naval-1"
|
|
||||||
CountryID=CountryID or country.id.USA
|
|
||||||
Vec3=Vec3 or {x=0, y=0, z=0}
|
|
||||||
Nunits=Nunits or 1
|
|
||||||
Radius=Radius or 500
|
|
||||||
|
|
||||||
|
|
||||||
-- Get generic template.
|
|
||||||
local template=UTILS.DeepCopy(TEMPLATE.GenericNaval)
|
|
||||||
|
|
||||||
-- Set group name.
|
|
||||||
template.name=GroupName
|
|
||||||
|
|
||||||
-- These are additional entries required by the MOOSE _DATABASE:Spawn() function.
|
|
||||||
template.CountryID=CountryID
|
|
||||||
template.CoalitionID=coalition.getCountryCoalition(template.CountryID)
|
|
||||||
template.CategoryID=Unit.Category.SHIP
|
|
||||||
|
|
||||||
-- Set first unit.
|
|
||||||
template.units[1].type=TypeName
|
|
||||||
template.units[1].name=GroupName.."-1"
|
|
||||||
|
|
||||||
if Vec3 then
|
|
||||||
TEMPLATE.SetPositionFromVec3(template, Vec3)
|
|
||||||
end
|
|
||||||
|
|
||||||
TEMPLATE.SetUnits(template, Nunits, COORDINATE:NewFromVec3(Vec3), Radius)
|
|
||||||
|
|
||||||
return template
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Aircraft Template
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--- Get template for fixed wing units.
|
|
||||||
-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`.
|
|
||||||
-- @param #string GroupName Name of the spawned group. **Must be unique!**
|
|
||||||
-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to.
|
|
||||||
-- @param DCS#Vec3 Vec3 Position of the group and the first unit.
|
|
||||||
-- @param #number Nunits Number of units. Default 1.
|
|
||||||
-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m.
|
|
||||||
-- @return #table Template Template table.
|
|
||||||
function TEMPLATE.GetAirplane(TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
-- Defaults.
|
|
||||||
TypeName=TypeName or TEMPLATE.TypeAirplane.A10C
|
|
||||||
GroupName=GroupName or "Airplane-1"
|
|
||||||
CountryID=CountryID or country.id.USA
|
|
||||||
Vec3=Vec3 or {x=0, y=1000, z=0}
|
|
||||||
Nunits=Nunits or 1
|
|
||||||
Radius=Radius or 100
|
|
||||||
|
|
||||||
local template=TEMPLATE._GetAircraft(true, TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
return template
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get template for fixed wing units.
|
|
||||||
-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`.
|
|
||||||
-- @param #string GroupName Name of the spawned group. **Must be unique!**
|
|
||||||
-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to.
|
|
||||||
-- @param DCS#Vec3 Vec3 Position of the group and the first unit.
|
|
||||||
-- @param #number Nunits Number of units. Default 1.
|
|
||||||
-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m.
|
|
||||||
-- @return #table Template Template table.
|
|
||||||
function TEMPLATE.GetHelicopter(TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
-- Defaults.
|
|
||||||
TypeName=TypeName or TEMPLATE.TypeHelicopter.AH1W
|
|
||||||
GroupName=GroupName or "Helicopter-1"
|
|
||||||
CountryID=CountryID or country.id.USA
|
|
||||||
Vec3=Vec3 or {x=0, y=500, z=0}
|
|
||||||
Nunits=Nunits or 1
|
|
||||||
Radius=Radius or 100
|
|
||||||
|
|
||||||
-- Limit unis to 4.
|
|
||||||
Nunits=math.min(Nunits, 4)
|
|
||||||
|
|
||||||
local template=TEMPLATE._GetAircraft(false, TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
return template
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Get template for aircraft units.
|
|
||||||
-- @param #boolean Airplane If true, this is a fixed wing. Else, rotary wing.
|
|
||||||
-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`.
|
|
||||||
-- @param #string GroupName Name of the spawned group. **Must be unique!**
|
|
||||||
-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to.
|
|
||||||
-- @param DCS#Vec3 Vec3 Position of the group and the first unit.
|
|
||||||
-- @param #number Nunits Number of units. Default 1.
|
|
||||||
-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m.
|
|
||||||
-- @return #table Template Template table.
|
|
||||||
function TEMPLATE._GetAircraft(Airplane, TypeName, GroupName, CountryID, Vec3, Nunits, Radius)
|
|
||||||
|
|
||||||
-- Defaults.
|
|
||||||
TypeName=TypeName
|
|
||||||
GroupName=GroupName or "Aircraft-1"
|
|
||||||
CountryID=CountryID or country.id.USA
|
|
||||||
Vec3=Vec3 or {x=0, y=0, z=0}
|
|
||||||
Nunits=Nunits or 1
|
|
||||||
Radius=Radius or 100
|
|
||||||
|
|
||||||
-- Get generic template.
|
|
||||||
local template=UTILS.DeepCopy(TEMPLATE.GenericAircraft)
|
|
||||||
|
|
||||||
-- Set group name.
|
|
||||||
template.name=GroupName
|
|
||||||
|
|
||||||
-- These are additional entries required by the MOOSE _DATABASE:Spawn() function.
|
|
||||||
template.CountryID=CountryID
|
|
||||||
template.CoalitionID=coalition.getCountryCoalition(template.CountryID)
|
|
||||||
if Airplane then
|
|
||||||
template.CategoryID=Unit.Category.AIRPLANE
|
|
||||||
else
|
|
||||||
template.CategoryID=Unit.Category.HELICOPTER
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set first unit.
|
|
||||||
template.units[1].type=TypeName
|
|
||||||
template.units[1].name=GroupName.."-1"
|
|
||||||
|
|
||||||
-- Set position.
|
|
||||||
if Vec3 then
|
|
||||||
TEMPLATE.SetPositionFromVec3(template, Vec3)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set number of units.
|
|
||||||
TEMPLATE.SetUnits(template, Nunits, COORDINATE:NewFromVec3(Vec3), Radius)
|
|
||||||
|
|
||||||
return template
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Misc Functions
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--- Set the position of the template.
|
|
||||||
-- @param #table Template The template to be modified.
|
|
||||||
-- @param DCS#Vec2 Vec2 2D Position vector with x and y components of the group.
|
|
||||||
function TEMPLATE.SetPositionFromVec2(Template, Vec2)
|
|
||||||
|
|
||||||
Template.x=Vec2.x
|
|
||||||
Template.y=Vec2.y
|
|
||||||
|
|
||||||
for _,unit in pairs(Template.units) do
|
|
||||||
unit.x=Vec2.x
|
|
||||||
unit.y=Vec2.y
|
|
||||||
end
|
|
||||||
|
|
||||||
Template.route.points[1].x=Vec2.x
|
|
||||||
Template.route.points[1].y=Vec2.y
|
|
||||||
Template.route.points[1].alt=0 --TODO: Use land height.
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the position of the template.
|
|
||||||
-- @param #table Template The template to be modified.
|
|
||||||
-- @param DCS#Vec3 Vec3 Position vector of the group.
|
|
||||||
function TEMPLATE.SetPositionFromVec3(Template, Vec3)
|
|
||||||
|
|
||||||
local Vec2={x=Vec3.x, y=Vec3.z}
|
|
||||||
|
|
||||||
TEMPLATE.SetPositionFromVec2(Template, Vec2)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the position of the template.
|
|
||||||
-- @param #table Template The template to be modified.
|
|
||||||
-- @param #number N Total number of units in the group.
|
|
||||||
-- @param Core.Point#COORDINATE Coordinate Position of the first unit.
|
|
||||||
-- @param #number Radius Radius in meters to randomly place the additional units.
|
|
||||||
function TEMPLATE.SetUnits(Template, N, Coordinate, Radius)
|
|
||||||
|
|
||||||
local units=Template.units
|
|
||||||
|
|
||||||
local unit1=units[1]
|
|
||||||
|
|
||||||
local Vec3=Coordinate:GetVec3()
|
|
||||||
|
|
||||||
unit1.x=Vec3.x
|
|
||||||
unit1.y=Vec3.z
|
|
||||||
unit1.alt=Vec3.y
|
|
||||||
|
|
||||||
for i=2,N do
|
|
||||||
units[i]=UTILS.DeepCopy(unit1)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1,N do
|
|
||||||
local unit=units[i]
|
|
||||||
unit.name=string.format("%s-%d", Template.name, i)
|
|
||||||
if i>1 then
|
|
||||||
local vec2=Coordinate:GetRandomCoordinateInRadius(Radius, 5):GetVec2()
|
|
||||||
unit.x=vec2.x
|
|
||||||
unit.y=vec2.y
|
|
||||||
unit.alt=unit1.alt
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the position of the template.
|
|
||||||
-- @param #table Template The template to be modified.
|
|
||||||
-- @param Wrapper.Airbase#AIRBASE AirBase The airbase where the aircraft are spawned.
|
|
||||||
-- @param #table ParkingSpots List of parking spot IDs. Every unit needs one!
|
|
||||||
-- @param #boolean EngineOn If true, aircraft are spawned hot.
|
|
||||||
function TEMPLATE.SetAirbase(Template, AirBase, ParkingSpots, EngineOn)
|
|
||||||
|
|
||||||
-- Airbase ID.
|
|
||||||
local AirbaseID=AirBase:GetID()
|
|
||||||
|
|
||||||
-- Spawn point.
|
|
||||||
local point=Template.route.points[1]
|
|
||||||
|
|
||||||
-- Set ID.
|
|
||||||
if AirBase:IsAirdrome() then
|
|
||||||
point.airdromeId=AirbaseID
|
|
||||||
else
|
|
||||||
point.helipadId=AirbaseID
|
|
||||||
point.linkUnit=AirbaseID
|
|
||||||
end
|
|
||||||
|
|
||||||
if EngineOn then
|
|
||||||
point.action=COORDINATE.WaypointAction.FromParkingAreaHot
|
|
||||||
point.type=COORDINATE.WaypointType.TakeOffParkingHot
|
|
||||||
else
|
|
||||||
point.action=COORDINATE.WaypointAction.FromParkingArea
|
|
||||||
point.type=COORDINATE.WaypointType.TakeOffParking
|
|
||||||
end
|
|
||||||
|
|
||||||
for i,unit in ipairs(Template.units) do
|
|
||||||
unit.parking_id=ParkingSpots[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add a waypoint.
|
|
||||||
-- @param #table Template The template to be modified.
|
|
||||||
-- @param #table Waypoint Waypoint table.
|
|
||||||
function TEMPLATE.AddWaypoint(Template, Waypoint)
|
|
||||||
|
|
||||||
table.insert(Template.route.points, Waypoint)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Generic Ground Template
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
TEMPLATE.GenericGround=
|
|
||||||
{
|
|
||||||
["visible"] = false,
|
|
||||||
["tasks"] = {}, -- end of ["tasks"]
|
|
||||||
["uncontrollable"] = false,
|
|
||||||
["task"] = "Ground Nothing",
|
|
||||||
["route"] =
|
|
||||||
{
|
|
||||||
["spans"] = {}, -- end of ["spans"]
|
|
||||||
["points"] =
|
|
||||||
{
|
|
||||||
[1] =
|
|
||||||
{
|
|
||||||
["alt"] = 0,
|
|
||||||
["type"] = "Turning Point",
|
|
||||||
["ETA"] = 0,
|
|
||||||
["alt_type"] = "BARO",
|
|
||||||
["formation_template"] = "",
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["ETA_locked"] = true,
|
|
||||||
["speed"] = 0,
|
|
||||||
["action"] = "Off Road",
|
|
||||||
["task"] =
|
|
||||||
{
|
|
||||||
["id"] = "ComboTask",
|
|
||||||
["params"] =
|
|
||||||
{
|
|
||||||
["tasks"] =
|
|
||||||
{
|
|
||||||
}, -- end of ["tasks"]
|
|
||||||
}, -- end of ["params"]
|
|
||||||
}, -- end of ["task"]
|
|
||||||
["speed_locked"] = true,
|
|
||||||
}, -- end of [1]
|
|
||||||
}, -- end of ["points"]
|
|
||||||
}, -- end of ["route"]
|
|
||||||
["groupId"] = nil,
|
|
||||||
["hidden"] = false,
|
|
||||||
["units"] =
|
|
||||||
{
|
|
||||||
[1] =
|
|
||||||
{
|
|
||||||
["transportable"] =
|
|
||||||
{
|
|
||||||
["randomTransportable"] = false,
|
|
||||||
}, -- end of ["transportable"]
|
|
||||||
["skill"] = "Average",
|
|
||||||
["type"] = "Infantry AK",
|
|
||||||
["unitId"] = nil,
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["name"] = "Infantry AK-47 Rus",
|
|
||||||
["heading"] = 0,
|
|
||||||
["playerCanDrive"] = false,
|
|
||||||
}, -- end of [1]
|
|
||||||
}, -- end of ["units"]
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["name"] = "Infantry AK-47 Rus",
|
|
||||||
["start_time"] = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Generic Ship Template
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
TEMPLATE.GenericNaval=
|
|
||||||
{
|
|
||||||
["visible"] = false,
|
|
||||||
["tasks"] = {}, -- end of ["tasks"]
|
|
||||||
["uncontrollable"] = false,
|
|
||||||
["route"] =
|
|
||||||
{
|
|
||||||
["points"] =
|
|
||||||
{
|
|
||||||
[1] =
|
|
||||||
{
|
|
||||||
["alt"] = 0,
|
|
||||||
["type"] = "Turning Point",
|
|
||||||
["ETA"] = 0,
|
|
||||||
["alt_type"] = "BARO",
|
|
||||||
["formation_template"] = "",
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["ETA_locked"] = true,
|
|
||||||
["speed"] = 0,
|
|
||||||
["action"] = "Turning Point",
|
|
||||||
["task"] =
|
|
||||||
{
|
|
||||||
["id"] = "ComboTask",
|
|
||||||
["params"] =
|
|
||||||
{
|
|
||||||
["tasks"] =
|
|
||||||
{
|
|
||||||
}, -- end of ["tasks"]
|
|
||||||
}, -- end of ["params"]
|
|
||||||
}, -- end of ["task"]
|
|
||||||
["speed_locked"] = true,
|
|
||||||
}, -- end of [1]
|
|
||||||
}, -- end of ["points"]
|
|
||||||
}, -- end of ["route"]
|
|
||||||
["groupId"] = nil,
|
|
||||||
["hidden"] = false,
|
|
||||||
["units"] =
|
|
||||||
{
|
|
||||||
[1] =
|
|
||||||
{
|
|
||||||
["transportable"] =
|
|
||||||
{
|
|
||||||
["randomTransportable"] = false,
|
|
||||||
}, -- end of ["transportable"]
|
|
||||||
["skill"] = "Average",
|
|
||||||
["type"] = "TICONDEROG",
|
|
||||||
["unitId"] = nil,
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["name"] = "Naval-1-1",
|
|
||||||
["heading"] = 0,
|
|
||||||
["modulation"] = 0,
|
|
||||||
["frequency"] = 127500000,
|
|
||||||
}, -- end of [1]
|
|
||||||
}, -- end of ["units"]
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["name"] = "Naval-1",
|
|
||||||
["start_time"] = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Generic Aircraft Template
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
TEMPLATE.GenericAircraft=
|
|
||||||
{
|
|
||||||
["groupId"] = nil,
|
|
||||||
["name"] = "Rotary-1",
|
|
||||||
["uncontrolled"] = false,
|
|
||||||
["hidden"] = false,
|
|
||||||
["task"] = "Nothing",
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["start_time"] = 0,
|
|
||||||
["communication"] = true,
|
|
||||||
["radioSet"] = false,
|
|
||||||
["frequency"] = 127.5,
|
|
||||||
["modulation"] = 0,
|
|
||||||
["taskSelected"] = true,
|
|
||||||
["tasks"] = {}, -- end of ["tasks"]
|
|
||||||
["route"] =
|
|
||||||
{
|
|
||||||
["points"] =
|
|
||||||
{
|
|
||||||
[1] =
|
|
||||||
{
|
|
||||||
["y"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["alt"] = 1000,
|
|
||||||
["alt_type"] = "BARO",
|
|
||||||
["action"] = "Turning Point",
|
|
||||||
["type"] = "Turning Point",
|
|
||||||
["airdromeId"] = nil,
|
|
||||||
["task"] =
|
|
||||||
{
|
|
||||||
["id"] = "ComboTask",
|
|
||||||
["params"] =
|
|
||||||
{
|
|
||||||
["tasks"] = {}, -- end of ["tasks"]
|
|
||||||
}, -- end of ["params"]
|
|
||||||
}, -- end of ["task"]
|
|
||||||
["ETA"] = 0,
|
|
||||||
["ETA_locked"] = true,
|
|
||||||
["speed"] = 100,
|
|
||||||
["speed_locked"] = true,
|
|
||||||
["formation_template"] = "",
|
|
||||||
}, -- end of [1]
|
|
||||||
}, -- end of ["points"]
|
|
||||||
}, -- end of ["route"]
|
|
||||||
["units"] =
|
|
||||||
{
|
|
||||||
[1] =
|
|
||||||
{
|
|
||||||
["name"] = "Rotary-1-1",
|
|
||||||
["unitId"] = nil,
|
|
||||||
["type"] = "AH-1W",
|
|
||||||
["onboard_num"] = "050",
|
|
||||||
["livery_id"] = "USA X Black",
|
|
||||||
["skill"] = "High",
|
|
||||||
["ropeLength"] = 15,
|
|
||||||
["speed"] = 0,
|
|
||||||
["x"] = 0,
|
|
||||||
["y"] = 0,
|
|
||||||
["alt"] = 10,
|
|
||||||
["alt_type"] = "BARO",
|
|
||||||
["heading"] = 0,
|
|
||||||
["psi"] = 0,
|
|
||||||
["parking"] = nil,
|
|
||||||
["parking_id"] = nil,
|
|
||||||
["payload"] =
|
|
||||||
{
|
|
||||||
["pylons"] = {}, -- end of ["pylons"]
|
|
||||||
["fuel"] = "1250.0",
|
|
||||||
["flare"] = 30,
|
|
||||||
["chaff"] = 30,
|
|
||||||
["gun"] = 100,
|
|
||||||
}, -- end of ["payload"]
|
|
||||||
["callsign"] =
|
|
||||||
{
|
|
||||||
[1] = 2,
|
|
||||||
[2] = 1,
|
|
||||||
[3] = 1,
|
|
||||||
["name"] = "Springfield11",
|
|
||||||
}, -- end of ["callsign"]
|
|
||||||
}, -- end of [1]
|
|
||||||
}, -- end of ["units"]
|
|
||||||
}
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -12,27 +12,35 @@
|
|||||||
-- @module Utilities.Utils
|
-- @module Utilities.Utils
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
---
|
--- Smoke color enum `trigger.smokeColor`.
|
||||||
-- @type SMOKECOLOR
|
-- @type SMOKECOLOR
|
||||||
-- @field Green
|
-- @field #number Green Green smoke (0)
|
||||||
-- @field Red
|
-- @field #number Red Red smoke (1)
|
||||||
-- @field White
|
-- @field #number White White smoke (2)
|
||||||
-- @field Orange
|
-- @field #number Orange Orange smoke (3)
|
||||||
-- @field Blue
|
-- @field #number Blue Blue smoke (4)
|
||||||
|
|
||||||
SMOKECOLOR = trigger.smokeColor -- #SMOKECOLOR
|
SMOKECOLOR = trigger.smokeColor -- #SMOKECOLOR
|
||||||
|
|
||||||
---
|
--- Flare colur enum `trigger.flareColor`.
|
||||||
-- @type FLARECOLOR
|
-- @type FLARECOLOR
|
||||||
-- @field Green
|
-- @field #number Green (0)
|
||||||
-- @field Red
|
-- @field #number Red Red flare (1)
|
||||||
-- @field White
|
-- @field #number White White flare (2)
|
||||||
-- @field Yellow
|
-- @field #number Yellow Yellow flare (3)
|
||||||
|
|
||||||
FLARECOLOR = trigger.flareColor -- #FLARECOLOR
|
FLARECOLOR = trigger.flareColor -- #FLARECOLOR
|
||||||
|
|
||||||
--- Big smoke preset enum.
|
--- Big smoke preset enum.
|
||||||
-- @type BIGSMOKEPRESET
|
-- @type BIGSMOKEPRESET
|
||||||
|
-- @field #number SmallSmokeAndFire Small moke and fire (1)
|
||||||
|
-- @field #number MediumSmokeAndFire Medium smoke and fire (2)
|
||||||
|
-- @field #number LargeSmokeAndFire Large smoke and fire (3)
|
||||||
|
-- @field #number HugeSmokeAndFire Huge smoke and fire (4)
|
||||||
|
-- @field #number SmallSmoke Small smoke (5)
|
||||||
|
-- @field #number MediumSmoke Medium smoke (6)
|
||||||
|
-- @field #number LargeSmoke Large smoke (7)
|
||||||
|
-- @field #number HugeSmoke Huge smoke (8)
|
||||||
BIGSMOKEPRESET = {
|
BIGSMOKEPRESET = {
|
||||||
SmallSmokeAndFire=1,
|
SmallSmokeAndFire=1,
|
||||||
MediumSmokeAndFire=2,
|
MediumSmokeAndFire=2,
|
||||||
@@ -58,6 +66,7 @@ BIGSMOKEPRESET = {
|
|||||||
-- @field #string Kola Kola map.
|
-- @field #string Kola Kola map.
|
||||||
-- @field #string Afghanistan Afghanistan map
|
-- @field #string Afghanistan Afghanistan map
|
||||||
-- @field #string Iraq Iraq map
|
-- @field #string Iraq Iraq map
|
||||||
|
-- @field #string GermanyCW Germany Cold War map
|
||||||
DCSMAP = {
|
DCSMAP = {
|
||||||
Caucasus="Caucasus",
|
Caucasus="Caucasus",
|
||||||
NTTR="Nevada",
|
NTTR="Nevada",
|
||||||
@@ -70,7 +79,8 @@ DCSMAP = {
|
|||||||
Sinai="SinaiMap",
|
Sinai="SinaiMap",
|
||||||
Kola="Kola",
|
Kola="Kola",
|
||||||
Afghanistan="Afghanistan",
|
Afghanistan="Afghanistan",
|
||||||
Iraq="Iraq"
|
Iraq="Iraq",
|
||||||
|
GermanyCW="GermanyCW",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -349,7 +359,7 @@ end
|
|||||||
-- @return #string Table as a string.
|
-- @return #string Table as a string.
|
||||||
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
||||||
|
|
||||||
lookup_table = {}
|
local lookup_table = {}
|
||||||
|
|
||||||
local function _Serialize( tbl )
|
local function _Serialize( tbl )
|
||||||
|
|
||||||
@@ -488,7 +498,7 @@ end
|
|||||||
|
|
||||||
--- Counts the number of elements in a table.
|
--- Counts the number of elements in a table.
|
||||||
-- @param #table T Table to count
|
-- @param #table T Table to count
|
||||||
-- @return #int Number of elements in the table
|
-- @return #number Number of elements in the table
|
||||||
function UTILS.TableLength(T)
|
function UTILS.TableLength(T)
|
||||||
local count = 0
|
local count = 0
|
||||||
for _ in pairs(T or {}) do count = count + 1 end
|
for _ in pairs(T or {}) do count = count + 1 end
|
||||||
@@ -514,7 +524,7 @@ function UTILS.PrintTableToLog(table, indent, noprint)
|
|||||||
env.info(string.rep(" ", indent) .. tostring(k) .. " = {")
|
env.info(string.rep(" ", indent) .. tostring(k) .. " = {")
|
||||||
end
|
end
|
||||||
text = text ..string.rep(" ", indent) .. tostring(k) .. " = {\n"
|
text = text ..string.rep(" ", indent) .. tostring(k) .. " = {\n"
|
||||||
text = text .. tostring(UTILS.PrintTableToLog(v, indent + 1)).."\n"
|
text = text .. tostring(UTILS.PrintTableToLog(v, indent + 1), noprint).."\n"
|
||||||
if not noprint then
|
if not noprint then
|
||||||
env.info(string.rep(" ", indent) .. "},")
|
env.info(string.rep(" ", indent) .. "},")
|
||||||
end
|
end
|
||||||
@@ -1759,7 +1769,9 @@ end
|
|||||||
-- * Sinai +4.8 (East)
|
-- * Sinai +4.8 (East)
|
||||||
-- * Kola +15 (East) - note there is a lot of deviation across the map (-1° to +24°), as we are close to the North pole
|
-- * Kola +15 (East) - note there is a lot of deviation across the map (-1° to +24°), as we are close to the North pole
|
||||||
-- * Afghanistan +3 (East) - actually +3.6 (NW) to +2.3 (SE)
|
-- * Afghanistan +3 (East) - actually +3.6 (NW) to +2.3 (SE)
|
||||||
-- @param #string map (Optional) Map for which the declination is returned. Default is from env.mission.theatre
|
-- * Iraq +4.4 (East)
|
||||||
|
-- * Germany Cold War +0.1 (East) - near Fulda
|
||||||
|
-- @param #string map (Optional) Map for which the declination is returned. Default is from `env.mission.theatre`.
|
||||||
-- @return #number Declination in degrees.
|
-- @return #number Declination in degrees.
|
||||||
function UTILS.GetMagneticDeclination(map)
|
function UTILS.GetMagneticDeclination(map)
|
||||||
|
|
||||||
@@ -1791,6 +1803,8 @@ function UTILS.GetMagneticDeclination(map)
|
|||||||
declination=3
|
declination=3
|
||||||
elseif map==DCSMAP.Iraq then
|
elseif map==DCSMAP.Iraq then
|
||||||
declination=4.4
|
declination=4.4
|
||||||
|
elseif map==DCSMAP.GermanyCW then
|
||||||
|
declination=0.1
|
||||||
else
|
else
|
||||||
declination=0
|
declination=0
|
||||||
end
|
end
|
||||||
@@ -1899,6 +1913,13 @@ end
|
|||||||
function UTILS.GetReportingName(Typename)
|
function UTILS.GetReportingName(Typename)
|
||||||
|
|
||||||
local typename = string.lower(Typename)
|
local typename = string.lower(Typename)
|
||||||
|
|
||||||
|
-- special cases - Shark and Manstay have "A-50" in the name
|
||||||
|
if string.find(typename,"ka-50",1,true) then
|
||||||
|
return "Shark"
|
||||||
|
elseif string.find(typename,"a-50",1,true) then
|
||||||
|
return "Mainstay"
|
||||||
|
end
|
||||||
|
|
||||||
for name, value in pairs(ENUMS.ReportingName.NATO) do
|
for name, value in pairs(ENUMS.ReportingName.NATO) do
|
||||||
local svalue = string.lower(value)
|
local svalue = string.lower(value)
|
||||||
@@ -2024,6 +2045,10 @@ function UTILS.GMTToLocalTimeDifference()
|
|||||||
return 3 -- Currently map is +2 but should be +3 (DCS bug?)
|
return 3 -- Currently map is +2 but should be +3 (DCS bug?)
|
||||||
elseif theatre==DCSMAP.Afghanistan then
|
elseif theatre==DCSMAP.Afghanistan then
|
||||||
return 4.5 -- UTC +4:30
|
return 4.5 -- UTC +4:30
|
||||||
|
elseif theatre==DCSMAP.Iraq then
|
||||||
|
return 3.0 -- UTC +3
|
||||||
|
elseif theatre==DCSMAP.GermanyCW then
|
||||||
|
return 1.0 -- UTC +1 Central European Time (not summer time)
|
||||||
else
|
else
|
||||||
BASE:E(string.format("ERROR: Unknown Map %s in UTILS.GMTToLocal function. Returning 0", tostring(theatre)))
|
BASE:E(string.format("ERROR: Unknown Map %s in UTILS.GMTToLocal function. Returning 0", tostring(theatre)))
|
||||||
return 0
|
return 0
|
||||||
@@ -2127,9 +2152,9 @@ function UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, Rising, Tlocal)
|
|||||||
local cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))
|
local cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))
|
||||||
|
|
||||||
if rising and cosH > 1 then
|
if rising and cosH > 1 then
|
||||||
return "N/S" -- The sun never rises on this location on the specified date
|
return "N/R" -- The sun never rises on this location on the specified date
|
||||||
elseif cosH < -1 then
|
elseif cosH < -1 then
|
||||||
return "N/R" -- The sun never sets on this location on the specified date
|
return "N/S" -- The sun never sets on this location on the specified date
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Finish calculating H and convert into hours
|
-- Finish calculating H and convert into hours
|
||||||
@@ -2329,8 +2354,12 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
BASE:T(unit_name .. " rear cargo door is open")
|
BASE:T(unit_name .. " rear cargo door is open")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
-- ground
|
||||||
|
local UnitDescriptor = unit:getDesc()
|
||||||
|
local IsGroundResult = (UnitDescriptor.category == Unit.Category.GROUND_UNIT)
|
||||||
|
|
||||||
|
return IsGroundResult
|
||||||
|
|
||||||
end -- nil
|
end -- nil
|
||||||
|
|
||||||
@@ -4204,3 +4233,198 @@ function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,
|
|||||||
|
|
||||||
return ReturnObjects, ADFName
|
return ReturnObjects, ADFName
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Converts a Vec2 to a Vec3.
|
||||||
|
-- @param vec the 2D vector
|
||||||
|
-- @param y optional new y axis (altitude) value. If omitted it's 0.
|
||||||
|
function UTILS.Vec2toVec3(vec,y)
|
||||||
|
if not vec.z then
|
||||||
|
if vec.alt and not y then
|
||||||
|
y = vec.alt
|
||||||
|
elseif not y then
|
||||||
|
y = 0
|
||||||
|
end
|
||||||
|
return {x = vec.x, y = y, z = vec.y}
|
||||||
|
else
|
||||||
|
return {x = vec.x, y = vec.y, z = vec.z} -- it was already Vec3, actually.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the correction needed for true north in radians
|
||||||
|
-- @param gPoint The map point vec2 or vec3
|
||||||
|
-- @return number correction
|
||||||
|
function UTILS.GetNorthCorrection(gPoint)
|
||||||
|
local point = UTILS.DeepCopy(gPoint)
|
||||||
|
if not point.z then --Vec2; convert to Vec3
|
||||||
|
point.z = point.y
|
||||||
|
point.y = 0
|
||||||
|
end
|
||||||
|
local lat, lon = coord.LOtoLL(point)
|
||||||
|
local north_posit = coord.LLtoLO(lat + 1, lon)
|
||||||
|
return math.atan2(north_posit.z - point.z, north_posit.x - point.x)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Convert time in seconds to a DHMS table `{d = days, h = hours, m = minutes, s = seconds}`
|
||||||
|
-- @param timeInSec Time in Seconds
|
||||||
|
-- @return #table Table with DHMS data
|
||||||
|
function UTILS.GetDHMS(timeInSec)
|
||||||
|
if timeInSec and type(timeInSec) == 'number' then
|
||||||
|
local tbl = {d = 0, h = 0, m = 0, s = 0}
|
||||||
|
if timeInSec > 86400 then
|
||||||
|
while timeInSec > 86400 do
|
||||||
|
tbl.d = tbl.d + 1
|
||||||
|
timeInSec = timeInSec - 86400
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if timeInSec > 3600 then
|
||||||
|
while timeInSec > 3600 do
|
||||||
|
tbl.h = tbl.h + 1
|
||||||
|
timeInSec = timeInSec - 3600
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if timeInSec > 60 then
|
||||||
|
while timeInSec > 60 do
|
||||||
|
tbl.m = tbl.m + 1
|
||||||
|
timeInSec = timeInSec - 60
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tbl.s = timeInSec
|
||||||
|
return tbl
|
||||||
|
else
|
||||||
|
BASE:E("No number handed!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns heading-error corrected direction in radians.
|
||||||
|
-- True-north corrected direction from point along vector vec.
|
||||||
|
-- @param vec Vec3 Starting point
|
||||||
|
-- @param point Vec2 Direction
|
||||||
|
-- @return direction corrected direction from point.
|
||||||
|
function UTILS.GetDirectionRadians(vec, point)
|
||||||
|
local dir = math.atan2(vec.z, vec.x)
|
||||||
|
if point then
|
||||||
|
dir = dir + UTILS.GetNorthCorrection(point)
|
||||||
|
end
|
||||||
|
if dir < 0 then
|
||||||
|
dir = dir + 2 * math.pi -- put dir in range of 0 to 2*pi
|
||||||
|
end
|
||||||
|
return dir
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Raycasting a point in polygon. Code from http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
|
||||||
|
-- @param point Vec2 or Vec3 to test
|
||||||
|
-- @param #table poly Polygon Table of Vec2/3 point forming the Polygon
|
||||||
|
-- @param #number maxalt Altitude limit (optional)
|
||||||
|
-- @param #boolean outcome
|
||||||
|
function UTILS.IsPointInPolygon(point, poly, maxalt)
|
||||||
|
point = UTILS.Vec2toVec3(point)
|
||||||
|
local px = point.x
|
||||||
|
local pz = point.z
|
||||||
|
local cn = 0
|
||||||
|
local newpoly = UTILS.DeepCopy(poly)
|
||||||
|
|
||||||
|
if not maxalt or (point.y <= maxalt) then
|
||||||
|
local polysize = #newpoly
|
||||||
|
newpoly[#newpoly + 1] = newpoly[1]
|
||||||
|
|
||||||
|
newpoly[1] = UTILS.Vec2toVec3(newpoly[1])
|
||||||
|
|
||||||
|
for k = 1, polysize do
|
||||||
|
newpoly[k+1] = UTILS.Vec2toVec3(newpoly[k+1])
|
||||||
|
if ((newpoly[k].z <= pz) and (newpoly[k+1].z > pz)) or ((newpoly[k].z > pz) and (newpoly[k+1].z <= pz)) then
|
||||||
|
local vt = (pz - newpoly[k].z) / (newpoly[k+1].z - newpoly[k].z)
|
||||||
|
if (px < newpoly[k].x + vt*(newpoly[k+1].x - newpoly[k].x)) then
|
||||||
|
cn = cn + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return cn%2 == 1
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Vector scalar multiplication.
|
||||||
|
-- @param vec Vec3 vector to multiply
|
||||||
|
-- @param #number mult scalar multiplicator
|
||||||
|
-- @return Vec3 new vector multiplied with the given scalar
|
||||||
|
function UTILS.ScalarMult(vec, mult)
|
||||||
|
return {x = vec.x*mult, y = vec.y*mult, z = vec.z*mult}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Utilities weather class for fog mainly.
|
||||||
|
-- @type UTILS.Weather
|
||||||
|
UTILS.Weather = {}
|
||||||
|
|
||||||
|
--- Returns the current fog thickness in meters. Returns zero if fog is not present.
|
||||||
|
function UTILS.Weather.GetFogThickness()
|
||||||
|
return world.weather.getFogThickness()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the fog to the desired thickness in meters at sea level.
|
||||||
|
-- @param #number Thickness Thickness in meters.
|
||||||
|
-- Any fog animation will be discarded.
|
||||||
|
-- Valid range : 100 to 5000 meters
|
||||||
|
function UTILS.Weather.SetFogThickness(Thickness)
|
||||||
|
local value = Thickness
|
||||||
|
if value < 100 then value = 100
|
||||||
|
elseif value > 5000 then value = 5000 end
|
||||||
|
return world.weather.setFogThickness(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Removes the fog.
|
||||||
|
function UTILS.Weather.RemoveFog()
|
||||||
|
return world.weather.setFogThickness(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets the maximum visibility distance of the current fog setting.
|
||||||
|
-- Returns 0 if no fog is present.
|
||||||
|
function UTILS.Weather.GetFogVisibilityDistanceMax()
|
||||||
|
return world.weather.getFogVisibilityDistance()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the maximum visibility at sea level in meters.
|
||||||
|
-- @param #number Thickness Thickness in meters.
|
||||||
|
-- Limit: 100 to 100000
|
||||||
|
function UTILS.Weather.SetFogVisibilityDistance(Thickness)
|
||||||
|
local value = Thickness
|
||||||
|
if value < 100 then value = 100
|
||||||
|
elseif value > 100000 then value = 100000 end
|
||||||
|
return world.weather.setFogVisibilityDistance(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Uses data from the passed table to change the fog visibility and thickness over a desired timeframe. This allows for a gradual increase/decrease of fog values rather than abruptly applying the values.
|
||||||
|
-- Animation Key Format: {time, visibility, thickness}
|
||||||
|
-- @param #table AnimationKeys Table of AnimationKey tables
|
||||||
|
-- @usage
|
||||||
|
-- Time: in seconds 0 to infinity
|
||||||
|
-- Time is relative to when the function was called. Time value for each key must be larger than the previous key. If time is set to 0 then the fog will be applied to the corresponding visibility and thickness values at that key. Any time value greater than 0 will result in the current fog being inherited and changed to the first key.
|
||||||
|
-- Visibility: in meters 100 to 100000
|
||||||
|
-- Thickness: in meters 100 to 5000
|
||||||
|
-- The speed at which the visibility and thickness changes is based on the time between keys and the values that visibility and thickness are being set to.
|
||||||
|
--
|
||||||
|
-- When the function is passed an empty table {} or nil the fog animation will be discarded and whatever the current thickness and visibility are set to will remain.
|
||||||
|
--
|
||||||
|
-- The following will set the fog in the mission to disappear in 1 minute.
|
||||||
|
--
|
||||||
|
-- UTILS.Weather.SetFogAnimation({ {60, 0, 0} })
|
||||||
|
--
|
||||||
|
-- The following will take 1 hour to get to the first fog setting, it will maintain that fog setting for another hour, then lightly removes the fog over the 2nd and 3rd hour, the completely removes the fog after 3 hours and 3 minutes from when the function was called.
|
||||||
|
--
|
||||||
|
-- UTILS.Weather.SetFogAnimation({
|
||||||
|
-- {3600, 10000, 3000}, -- one hour to get to that fog setting
|
||||||
|
-- {7200, 10000, 3000}, -- will maintain for 2 hours
|
||||||
|
-- {10800, 20000, 2000}, -- at 3 hours visibility will have been increased while thickness decreases slightly
|
||||||
|
-- {12600, 0, 0}, -- at 3:30 after the function was called the fog will be completely removed.
|
||||||
|
-- })
|
||||||
|
--
|
||||||
|
function UTILS.Weather.SetFogAnimation(AnimationKeys)
|
||||||
|
return world.weather.setFogAnimation(AnimationKeys)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- The fog animation will be discarded and whatever the current thickness and visibility are set to will remain
|
||||||
|
function UTILS.Weather.StopFogAnimation()
|
||||||
|
return world.weather.setFogAnimation({})
|
||||||
|
end
|
||||||
|
|||||||
@@ -449,7 +449,6 @@ AIRBASE.TheChannel = {
|
|||||||
-- * AIRBASE.Syria.Al_Dumayr
|
-- * AIRBASE.Syria.Al_Dumayr
|
||||||
-- * AIRBASE.Syria.Al_Qusayr
|
-- * AIRBASE.Syria.Al_Qusayr
|
||||||
-- * AIRBASE.Syria.Aleppo
|
-- * AIRBASE.Syria.Aleppo
|
||||||
-- * AIRBASE.Syria.Amman
|
|
||||||
-- * AIRBASE.Syria.An_Nasiriyah
|
-- * AIRBASE.Syria.An_Nasiriyah
|
||||||
-- * AIRBASE.Syria.At_Tanf
|
-- * AIRBASE.Syria.At_Tanf
|
||||||
-- * AIRBASE.Syria.Bassel_Al_Assad
|
-- * AIRBASE.Syria.Bassel_Al_Assad
|
||||||
@@ -511,8 +510,9 @@ AIRBASE.TheChannel = {
|
|||||||
-- * AIRBASE.Syria.Wujah_Al_Hajar
|
-- * AIRBASE.Syria.Wujah_Al_Hajar
|
||||||
-- * AIRBASE.Syria.Ben_Gurion
|
-- * AIRBASE.Syria.Ben_Gurion
|
||||||
-- * AIRBASE.Syria.Hatzor
|
-- * AIRBASE.Syria.Hatzor
|
||||||
-- * AIRBASE.Syria.Palmashim
|
-- * AIRBASE.Syria.Palmachim
|
||||||
-- * AIRBASE.Syria.Tel_Nof
|
-- * AIRBASE.Syria.Tel_Nof
|
||||||
|
-- * AIRBASE.Syria.Marka
|
||||||
--
|
--
|
||||||
--@field Syria
|
--@field Syria
|
||||||
AIRBASE.Syria={
|
AIRBASE.Syria={
|
||||||
@@ -522,7 +522,6 @@ AIRBASE.Syria={
|
|||||||
["Al_Dumayr"] = "Al-Dumayr",
|
["Al_Dumayr"] = "Al-Dumayr",
|
||||||
["Al_Qusayr"] = "Al Qusayr",
|
["Al_Qusayr"] = "Al Qusayr",
|
||||||
["Aleppo"] = "Aleppo",
|
["Aleppo"] = "Aleppo",
|
||||||
["Amman"] = "Amman",
|
|
||||||
["An_Nasiriyah"] = "An Nasiriyah",
|
["An_Nasiriyah"] = "An Nasiriyah",
|
||||||
["At_Tanf"] = "At Tanf",
|
["At_Tanf"] = "At Tanf",
|
||||||
["Bassel_Al_Assad"] = "Bassel Al-Assad",
|
["Bassel_Al_Assad"] = "Bassel Al-Assad",
|
||||||
@@ -554,6 +553,7 @@ AIRBASE.Syria={
|
|||||||
["Kuweires"] = "Kuweires",
|
["Kuweires"] = "Kuweires",
|
||||||
["Lakatamia"] = "Lakatamia",
|
["Lakatamia"] = "Lakatamia",
|
||||||
["Larnaca"] = "Larnaca",
|
["Larnaca"] = "Larnaca",
|
||||||
|
["Marka"] = "Marka",
|
||||||
["Marj_Ruhayyil"] = "Marj Ruhayyil",
|
["Marj_Ruhayyil"] = "Marj Ruhayyil",
|
||||||
["Marj_as_Sultan_North"] = "Marj as Sultan North",
|
["Marj_as_Sultan_North"] = "Marj as Sultan North",
|
||||||
["Marj_as_Sultan_South"] = "Marj as Sultan South",
|
["Marj_as_Sultan_South"] = "Marj as Sultan South",
|
||||||
@@ -584,7 +584,7 @@ AIRBASE.Syria={
|
|||||||
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
||||||
["Ben_Gurion"] = "Ben Gurion",
|
["Ben_Gurion"] = "Ben Gurion",
|
||||||
["Hatzor"] = "Hatzor",
|
["Hatzor"] = "Hatzor",
|
||||||
["Palmashim"] = "Palmashim",
|
["Palmachim"] = "Palmachim",
|
||||||
["Tel_Nof"] = "Tel Nof",
|
["Tel_Nof"] = "Tel Nof",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ AIRBASE.SouthAtlantic={
|
|||||||
-- * AIRBASE.Sinai.Bilbeis_Air_Base
|
-- * AIRBASE.Sinai.Bilbeis_Air_Base
|
||||||
-- * AIRBASE.Sinai.Bir_Hasanah
|
-- * AIRBASE.Sinai.Bir_Hasanah
|
||||||
-- * AIRBASE.Sinai.Birma_Air_Base
|
-- * AIRBASE.Sinai.Birma_Air_Base
|
||||||
-- * AIRBASE.Sinai.Borj_El_Arab_International_Airport
|
-- * AIRBASE.Sinai.Borg_El_Arab_International_Airport
|
||||||
-- * AIRBASE.Sinai.Cairo_International_Airport
|
-- * AIRBASE.Sinai.Cairo_International_Airport
|
||||||
-- * AIRBASE.Sinai.Cairo_West
|
-- * AIRBASE.Sinai.Cairo_West
|
||||||
-- * AIRBASE.Sinai.Difarsuwar_Airfield
|
-- * AIRBASE.Sinai.Difarsuwar_Airfield
|
||||||
@@ -737,7 +737,7 @@ AIRBASE.Sinai = {
|
|||||||
["Bilbeis_Air_Base"] = "Bilbeis Air Base",
|
["Bilbeis_Air_Base"] = "Bilbeis Air Base",
|
||||||
["Bir_Hasanah"] = "Bir Hasanah",
|
["Bir_Hasanah"] = "Bir Hasanah",
|
||||||
["Birma_Air_Base"] = "Birma Air Base",
|
["Birma_Air_Base"] = "Birma Air Base",
|
||||||
["Borj_El_Arab_International_Airport"] = "Borj El Arab International Airport",
|
["Borg_El_Arab_International_Airport"] = "Borg El Arab International Airport",
|
||||||
["Cairo_International_Airport"] = "Cairo International Airport",
|
["Cairo_International_Airport"] = "Cairo International Airport",
|
||||||
["Cairo_West"] = "Cairo West",
|
["Cairo_West"] = "Cairo West",
|
||||||
["Difarsuwar_Airfield"] = "Difarsuwar Airfield",
|
["Difarsuwar_Airfield"] = "Difarsuwar Airfield",
|
||||||
@@ -790,7 +790,14 @@ AIRBASE.Sinai = {
|
|||||||
-- * AIRBASE.Kola.Vidsel
|
-- * AIRBASE.Kola.Vidsel
|
||||||
-- * AIRBASE.Kola.Vuojarvi
|
-- * AIRBASE.Kola.Vuojarvi
|
||||||
-- * AIRBASE.Kola.Andoya
|
-- * AIRBASE.Kola.Andoya
|
||||||
-- * AIRBASE.Kola.Alakourtti
|
-- * AIRBASE.Kola.Alakurtti
|
||||||
|
-- * AIRBASE.Kola.Kittila
|
||||||
|
-- * AIRBASE.Kola.Bardufoss
|
||||||
|
-- * AIRBASE.Kola.Alta
|
||||||
|
-- * AIRBASE.Kola.Sodankyla
|
||||||
|
-- * AIRBASE.Kola.Enontekio
|
||||||
|
-- * AIRBASE.Kola.Evenes
|
||||||
|
-- * AIRBASE.Kola.Hosio
|
||||||
--
|
--
|
||||||
-- @field Kola
|
-- @field Kola
|
||||||
AIRBASE.Kola = {
|
AIRBASE.Kola = {
|
||||||
@@ -813,61 +820,87 @@ AIRBASE.Kola = {
|
|||||||
["Vidsel"] = "Vidsel",
|
["Vidsel"] = "Vidsel",
|
||||||
["Vuojarvi"] = "Vuojarvi",
|
["Vuojarvi"] = "Vuojarvi",
|
||||||
["Andoya"] = "Andoya",
|
["Andoya"] = "Andoya",
|
||||||
["Alakourtti"] = "Alakourtti",
|
["Alakurtti"] = "Alakurtti",
|
||||||
|
["Kittila"] = "Kittila",
|
||||||
|
["Bardufoss"] = "Bardufoss",
|
||||||
|
["Alta"] = "Alta",
|
||||||
|
["Sodankyla"] = "Sodankyla",
|
||||||
|
["Enontekio"] = "Enontekio",
|
||||||
|
["Evenes"] = "Evenes",
|
||||||
|
["Hosio"] = "Hosio",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Afghanistan map
|
--- Airbases of the Afghanistan map
|
||||||
--
|
--
|
||||||
-- * AIRBASE.Afghanistan.Bost
|
-- * AIRBASE.Afghanistan.Bost
|
||||||
|
-- * AIRBASE.Afghanistan.Bagram
|
||||||
|
-- * AIRBASE.Afghanistan.Bamyan
|
||||||
-- * AIRBASE.Afghanistan.Camp_Bastion
|
-- * AIRBASE.Afghanistan.Camp_Bastion
|
||||||
-- * AIRBASE.Afghanistan.Camp_Bastion_Heliport
|
-- * AIRBASE.Afghanistan.Camp_Bastion_Heliport
|
||||||
-- * AIRBASE.Afghanistan.Chaghcharan
|
-- * AIRBASE.Afghanistan.Chaghcharan
|
||||||
-- * AIRBASE.Afghanistan.Dwyer
|
-- * AIRBASE.Afghanistan.Dwyer
|
||||||
-- * AIRBASE.Afghanistan.Farah
|
-- * AIRBASE.Afghanistan.Farah
|
||||||
-- * AIRBASE.Afghanistan.Herat
|
-- * AIRBASE.Afghanistan.Herat
|
||||||
|
-- * AIRBASE.Afghanistan.Gardez
|
||||||
|
-- * AIRBASE.Afghanistan.Ghazni_Heliport
|
||||||
|
-- * AIRBASE.Afghanistan.Jalalabad
|
||||||
|
-- * AIRBASE.Afghanistan.Kabul
|
||||||
-- * AIRBASE.Afghanistan.Kandahar
|
-- * AIRBASE.Afghanistan.Kandahar
|
||||||
-- * AIRBASE.Afghanistan.Kandahar_Heliport
|
-- * AIRBASE.Afghanistan.Kandahar_Heliport
|
||||||
|
-- * AIRBASE.Afghanistan.Khost
|
||||||
|
-- * AIRBASE.Afghanistan.Khost_Heliport
|
||||||
-- * AIRBASE.Afghanistan.Maymana_Zahiraddin_Faryabi
|
-- * AIRBASE.Afghanistan.Maymana_Zahiraddin_Faryabi
|
||||||
-- * AIRBASE.Afghanistan.Nimroz
|
-- * AIRBASE.Afghanistan.Nimroz
|
||||||
-- * AIRBASE.Afghanistan.Qala_i_Naw
|
-- * AIRBASE.Afghanistan.Qala_i_Naw
|
||||||
-- * AIRBASE.Afghanistan.Shindand
|
-- * AIRBASE.Afghanistan.Shindand
|
||||||
-- * AIRBASE.Afghanistan.Shindand_Heliport
|
-- * AIRBASE.Afghanistan.Shindand_Heliport
|
||||||
-- * AIRBASE.Afghanistan.Tarinkot
|
-- * AIRBASE.Afghanistan.Tarinkot
|
||||||
|
-- * AIRBASE.Afghanistan.Urgoon_Heliport
|
||||||
--
|
--
|
||||||
-- @field Afghanistan
|
-- @field Afghanistan
|
||||||
AIRBASE.Afghanistan = {
|
AIRBASE.Afghanistan = {
|
||||||
|
["Bagram"] = "Bagram",
|
||||||
|
["Bamyan"] = "Bamyan",
|
||||||
["Bost"] = "Bost",
|
["Bost"] = "Bost",
|
||||||
["Camp_Bastion"] = "Camp Bastion",
|
["Camp_Bastion"] = "Camp Bastion",
|
||||||
["Camp_Bastion_Heliport"] = "Camp Bastion Heliport",
|
["Camp_Bastion_Heliport"] = "Camp Bastion Heliport",
|
||||||
["Chaghcharan"] = "Chaghcharan",
|
["Chaghcharan"] = "Chaghcharan",
|
||||||
["Dwyer"] = "Dwyer",
|
["Dwyer"] = "Dwyer",
|
||||||
["Farah"] = "Farah",
|
["Farah"] = "Farah",
|
||||||
|
["Gardez"] = "Gardez",
|
||||||
|
["Ghazni_Heliport"] = "Ghazni Heliport",
|
||||||
["Herat"] = "Herat",
|
["Herat"] = "Herat",
|
||||||
|
["Jalalabad"] = "Jalalabad",
|
||||||
|
["Kabul"] = "Kabul",
|
||||||
["Kandahar"] = "Kandahar",
|
["Kandahar"] = "Kandahar",
|
||||||
["Kandahar_Heliport"] = "Kandahar Heliport",
|
["Kandahar_Heliport"] = "Kandahar Heliport",
|
||||||
|
["Khost"] = "Khost",
|
||||||
|
["Khost_Heliport"] = "Khost Heliport",
|
||||||
["Maymana_Zahiraddin_Faryabi"] = "Maymana Zahiraddin Faryabi",
|
["Maymana_Zahiraddin_Faryabi"] = "Maymana Zahiraddin Faryabi",
|
||||||
["Nimroz"] = "Nimroz",
|
["Nimroz"] = "Nimroz",
|
||||||
["Qala_i_Naw"] = "Qala i Naw",
|
["Qala_i_Naw"] = "Qala i Naw",
|
||||||
|
["Sharana"] = "Sharana",
|
||||||
["Shindand"] = "Shindand",
|
["Shindand"] = "Shindand",
|
||||||
["Shindand_Heliport"] = "Shindand Heliport",
|
["Shindand_Heliport"] = "Shindand Heliport",
|
||||||
["Tarinkot"] = "Tarinkot",
|
["Tarinkot"] = "Tarinkot",
|
||||||
|
["Urgoon_Heliport"] = "Urgoon Heliport",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Iraq map
|
--- Airbases of the Iraq map
|
||||||
--
|
--
|
||||||
-- * `AIRBASE.Iraq.Baghdad_International_Airport` Baghdad International Airport
|
-- * AIRBASE.Iraq.Baghdad_International_Airport
|
||||||
-- * `AIRBASE.Iraq.Sulaimaniyah_International_Airport` Sulaimaniyah International Airport
|
-- * AIRBASE.Iraq.Sulaimaniyah_International_Airport
|
||||||
-- * `AIRBASE.Iraq.Al_Sahra_Airport` Al-Sahra Airport
|
-- * AIRBASE.Iraq.Al_Sahra_Airport
|
||||||
-- * `AIRBASE.Iraq.Erbil_International_Airport` Erbil International Airport
|
-- * AIRBASE.Iraq.Erbil_International_Airpor
|
||||||
-- * `AIRBASE.Iraq.Al_Taji_Airport` Al-Taji Airport
|
-- * AIRBASE.Iraq.Al_Taji_Airport
|
||||||
-- * `AIRBASE.Iraq.Al_Asad_Airbase` Al-Asad Airbase
|
-- * AIRBASE.Iraq.Al_Asad_Airbase
|
||||||
-- * `AIRBASE.Iraq.Al_Salam_Airbase` Al-Salam Airbase
|
-- * AIRBASE.Iraq.Al_Salam_Airbase
|
||||||
-- * `AIRBASE.Iraq.Balad_Airbase` Balad Airbase
|
-- * AIRBASE.Iraq.Balad_Airbase
|
||||||
-- * `AIRBASE.Iraq.Kirkuk_International_Airport` Kirkuk International Airport
|
-- * AIRBASE.Iraq.Kirkuk_International_Airport
|
||||||
-- * `AIRBASE.Iraq.Bashur_Airport` Bashur Airport
|
-- * AIRBASE.Iraq.Bashur_Airport
|
||||||
-- * `AIRBASE.Iraq.Al_Taquddum_Airport` Al-Taquddum Airport
|
-- * AIRBASE.Iraq.Al_Taquddum_Airport
|
||||||
-- * `AIRBASE.Iraq.Qayyarah_Airfield_West` Qayyarah Airfield West
|
-- * AIRBASE.Iraq.Qayyarah_Airfield_West
|
||||||
-- * `AIRBASE.Iraq.K1_Base` K1 Base
|
-- * AIRBASE.Iraq.K1_Base
|
||||||
--
|
--
|
||||||
-- @field Iraq
|
-- @field Iraq
|
||||||
AIRBASE.Iraq = {
|
AIRBASE.Iraq = {
|
||||||
@@ -886,6 +919,416 @@ AIRBASE.Iraq = {
|
|||||||
["K1_Base"] = "K1 Base",
|
["K1_Base"] = "K1 Base",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Airbases of the Germany Cold War map
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Frankfurt
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Frankfurt
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Koblenz
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Luebeck
|
||||||
|
-- * AIRBASE.GermanyCW.Allstedt
|
||||||
|
-- * AIRBASE.GermanyCW.Altes_Lager
|
||||||
|
-- * AIRBASE.GermanyCW.Bad_Duerkheim
|
||||||
|
-- * AIRBASE.GermanyCW.Barth
|
||||||
|
-- * AIRBASE.GermanyCW.Bienenfarm
|
||||||
|
-- * AIRBASE.GermanyCW.Bindersleben
|
||||||
|
-- * AIRBASE.GermanyCW.Bitburg
|
||||||
|
-- * AIRBASE.GermanyCW.Braunschweig
|
||||||
|
-- * AIRBASE.GermanyCW.Bremen
|
||||||
|
-- * AIRBASE.GermanyCW.Briest
|
||||||
|
-- * AIRBASE.GermanyCW.Buechel
|
||||||
|
-- * AIRBASE.GermanyCW.Bueckeburg
|
||||||
|
-- * AIRBASE.GermanyCW.Celle
|
||||||
|
-- * AIRBASE.GermanyCW.Cochstedt
|
||||||
|
-- * AIRBASE.GermanyCW.Damgarten
|
||||||
|
-- * AIRBASE.GermanyCW.Dedelow
|
||||||
|
-- * AIRBASE.GermanyCW.Dessau
|
||||||
|
-- * AIRBASE.GermanyCW.Fassberg
|
||||||
|
-- * AIRBASE.GermanyCW.Finow
|
||||||
|
-- * AIRBASE.GermanyCW.Frankfurt
|
||||||
|
-- * AIRBASE.GermanyCW.Fritzlar
|
||||||
|
-- * AIRBASE.GermanyCW.Fulda
|
||||||
|
-- * AIRBASE.GermanyCW.Gardelegen
|
||||||
|
-- * AIRBASE.GermanyCW.Garz
|
||||||
|
-- * AIRBASE.GermanyCW.Gatow
|
||||||
|
-- * AIRBASE.GermanyCW.Gelnhausen
|
||||||
|
-- * AIRBASE.GermanyCW.Giebelstadt
|
||||||
|
-- * AIRBASE.GermanyCW.Glindbruchkippe
|
||||||
|
-- * AIRBASE.GermanyCW.Gross_Mohrdorf
|
||||||
|
-- * AIRBASE.GermanyCW.Grosse_Wiese
|
||||||
|
-- * AIRBASE.GermanyCW.Guetersloh
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_01
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_03
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_04
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_05
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_06
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_07
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_08
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_09
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_10
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_11
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_12
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_13
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_14
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_15
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_16
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_17
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_18
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_19
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_20
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_21
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_23
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_25
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_27
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_30
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_31
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_32
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_34
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_38
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_39
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_40
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_41
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_42
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_43
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_44
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_45
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_46
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_47
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_48
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_49
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_50
|
||||||
|
-- * AIRBASE.GermanyCW.H_FRG_51
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_01
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_03
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_04
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_05
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_06
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_07
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_08
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_09
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_10
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_11
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_12
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_13
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_14
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_15
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_16
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_17
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_18
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_19
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_21
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_22
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_24
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_25
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_26
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_30
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_31
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_32
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_33
|
||||||
|
-- * AIRBASE.GermanyCW.H_GDR_34
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_01
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_04
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_06
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_11
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_12
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_13
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_14
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_15
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_16
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_17
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_21
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_24
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_26
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_27
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_29
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_01
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_03
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_08
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_09
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_10
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_11
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_12
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_13
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_14
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_GDR_16
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_FRG_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_01
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_03
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_04
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_05
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_06
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_07
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_08
|
||||||
|
-- * AIRBASE.GermanyCW.H_Radar_GDR_09
|
||||||
|
-- * AIRBASE.GermanyCW.Hahn
|
||||||
|
-- * AIRBASE.GermanyCW.Haina
|
||||||
|
-- * AIRBASE.GermanyCW.Hamburg
|
||||||
|
-- * AIRBASE.GermanyCW.Hamburg_Finkenwerder
|
||||||
|
-- * AIRBASE.GermanyCW.Hannover
|
||||||
|
-- * AIRBASE.GermanyCW.Hasselfelde
|
||||||
|
-- * AIRBASE.GermanyCW.Herrenteich
|
||||||
|
-- * AIRBASE.GermanyCW.Hildesheim
|
||||||
|
-- * AIRBASE.GermanyCW.Hockenheim
|
||||||
|
-- * AIRBASE.GermanyCW.Holzdorf
|
||||||
|
-- * AIRBASE.GermanyCW.Kammermark
|
||||||
|
-- * AIRBASE.GermanyCW.Koethen
|
||||||
|
-- * AIRBASE.GermanyCW.Laage
|
||||||
|
-- * AIRBASE.GermanyCW.Langenselbold
|
||||||
|
-- * AIRBASE.GermanyCW.Laerz
|
||||||
|
-- * AIRBASE.GermanyCW.Leipzig_Halle
|
||||||
|
-- * AIRBASE.GermanyCW.Leipzig_Mockau
|
||||||
|
-- * AIRBASE.GermanyCW.Luebeck
|
||||||
|
-- * AIRBASE.GermanyCW.Lueneburg
|
||||||
|
-- * AIRBASE.GermanyCW.Mahlwinkel
|
||||||
|
-- * AIRBASE.GermanyCW.Mendig
|
||||||
|
-- * AIRBASE.GermanyCW.Merseburg
|
||||||
|
-- * AIRBASE.GermanyCW.Neubrandenburg
|
||||||
|
-- * AIRBASE.GermanyCW.Neuruppin
|
||||||
|
-- * AIRBASE.GermanyCW.Northeim
|
||||||
|
-- * AIRBASE.GermanyCW.Ober_Moerlen
|
||||||
|
-- * AIRBASE.GermanyCW.Obermehler_Schlotheim
|
||||||
|
-- * AIRBASE.GermanyCW.Parchim
|
||||||
|
-- * AIRBASE.GermanyCW.Peenemuende
|
||||||
|
-- * AIRBASE.GermanyCW.Pferdsfeld
|
||||||
|
-- * AIRBASE.GermanyCW.Pinnow
|
||||||
|
-- * AIRBASE.GermanyCW.Pottschutthoehe
|
||||||
|
-- * AIRBASE.GermanyCW.Ramstein
|
||||||
|
-- * AIRBASE.GermanyCW.Rinteln
|
||||||
|
-- * AIRBASE.GermanyCW.Schoenefeld
|
||||||
|
-- * AIRBASE.GermanyCW.Schweinfurt
|
||||||
|
-- * AIRBASE.GermanyCW.Sembach
|
||||||
|
-- * AIRBASE.GermanyCW.Spangdahlem
|
||||||
|
-- * AIRBASE.GermanyCW.Sperenberg
|
||||||
|
-- * AIRBASE.GermanyCW.Stendal
|
||||||
|
-- * AIRBASE.GermanyCW.Tegel
|
||||||
|
-- * AIRBASE.GermanyCW.Tempelhof
|
||||||
|
-- * AIRBASE.GermanyCW.Templin
|
||||||
|
-- * AIRBASE.GermanyCW.Tutow
|
||||||
|
-- * AIRBASE.GermanyCW.Uelzen
|
||||||
|
-- * AIRBASE.GermanyCW.Uetersen
|
||||||
|
-- * AIRBASE.GermanyCW.Ummern
|
||||||
|
-- * AIRBASE.GermanyCW.Verden_Scharnhorst
|
||||||
|
-- * AIRBASE.GermanyCW.Walldorf
|
||||||
|
-- * AIRBASE.GermanyCW.Waren_Vielist
|
||||||
|
-- * AIRBASE.GermanyCW.Werneuchen
|
||||||
|
-- * AIRBASE.GermanyCW.Weser_Wuemme
|
||||||
|
-- * AIRBASE.GermanyCW.Wiesbaden
|
||||||
|
-- * AIRBASE.GermanyCW.Wismar
|
||||||
|
-- * AIRBASE.GermanyCW.Wittstock
|
||||||
|
-- * AIRBASE.GermanyCW.Worms
|
||||||
|
-- * AIRBASE.GermanyCW.Wunstorf
|
||||||
|
-- * AIRBASE.GermanyCW.Zerbst
|
||||||
|
-- * AIRBASE.GermanyCW.Zweibruecken
|
||||||
|
--
|
||||||
|
-- @field GermanyCW
|
||||||
|
AIRBASE.GermanyCW = {
|
||||||
|
["Airracing_Frankfurt"] = "Airracing Frankfurt",
|
||||||
|
["Airracing_Koblenz"] = "Airracing Koblenz",
|
||||||
|
["Airracing_Luebeck"] = "Airracing Lubeck",
|
||||||
|
["Allstedt"] = "Allstedt",
|
||||||
|
["Altes_Lager"] = "Altes Lager",
|
||||||
|
["Bad_Duerkheim"] = "Bad Durkheim",
|
||||||
|
["Barth"] = "Barth",
|
||||||
|
["Bienenfarm"] = "Bienenfarm",
|
||||||
|
["Bindersleben"] = "Bindersleben",
|
||||||
|
["Bitburg"] = "Bitburg",
|
||||||
|
["Braunschweig"] = "Braunschweig",
|
||||||
|
["Bremen"] = "Bremen",
|
||||||
|
["Briest"] = "Briest",
|
||||||
|
["Buechel"] = "Buchel",
|
||||||
|
["Bueckeburg"] = "Buckeburg",
|
||||||
|
["Celle"] = "Celle",
|
||||||
|
["Cochstedt"] = "Cochstedt",
|
||||||
|
["Damgarten"] = "Damgarten",
|
||||||
|
["Dedelow"] = "Dedelow",
|
||||||
|
["Dessau"] = "Dessau",
|
||||||
|
["Fassberg"] = "Fassberg",
|
||||||
|
["Finow"] = "Finow",
|
||||||
|
["Frankfurt"] = "Frankfurt",
|
||||||
|
["Fritzlar"] = "Fritzlar",
|
||||||
|
["Fulda"] = "Fulda",
|
||||||
|
["Gardelegen"] = "Gardelegen",
|
||||||
|
["Garz"] = "Garz",
|
||||||
|
["Gatow"] = "Gatow",
|
||||||
|
["Gelnhausen"] = "Gelnhausen",
|
||||||
|
["Giebelstadt"] = "Giebelstadt",
|
||||||
|
["Glindbruchkippe"] = "Glindbruchkippe ",
|
||||||
|
["Gross_Mohrdorf"] = "Gross Mohrdorf",
|
||||||
|
["Grosse_Wiese"] = "Grosse Wiese",
|
||||||
|
["Guetersloh"] = "Gutersloh",
|
||||||
|
["H_FRG_01"] = "H FRG 01",
|
||||||
|
["H_FRG_02"] = "H FRG 02",
|
||||||
|
["H_FRG_03"] = "H FRG 03",
|
||||||
|
["H_FRG_04"] = "H FRG 04",
|
||||||
|
["H_FRG_05"] = "H FRG 05",
|
||||||
|
["H_FRG_06"] = "H FRG 06",
|
||||||
|
["H_FRG_07"] = "H FRG 07",
|
||||||
|
["H_FRG_08"] = "H FRG 08",
|
||||||
|
["H_FRG_09"] = "H FRG 09",
|
||||||
|
["H_FRG_10"] = "H FRG 10",
|
||||||
|
["H_FRG_11"] = "H FRG 11",
|
||||||
|
["H_FRG_12"] = "H FRG 12",
|
||||||
|
["H_FRG_13"] = "H FRG 13",
|
||||||
|
["H_FRG_14"] = "H FRG 14",
|
||||||
|
["H_FRG_15"] = "H FRG 15",
|
||||||
|
["H_FRG_16"] = "H FRG 16",
|
||||||
|
["H_FRG_17"] = "H FRG 17",
|
||||||
|
["H_FRG_18"] = "H FRG 18",
|
||||||
|
["H_FRG_19"] = "H FRG 19",
|
||||||
|
["H_FRG_20"] = "H FRG 20",
|
||||||
|
["H_FRG_21"] = "H FRG 21",
|
||||||
|
["H_FRG_23"] = "H FRG 23",
|
||||||
|
["H_FRG_25"] = "H FRG 25",
|
||||||
|
["H_FRG_27"] = "H FRG 27",
|
||||||
|
["H_FRG_30"] = "H FRG 30",
|
||||||
|
["H_FRG_31"] = "H FRG 31",
|
||||||
|
["H_FRG_32"] = "H FRG 32",
|
||||||
|
["H_FRG_34"] = "H FRG 34",
|
||||||
|
["H_FRG_38"] = "H FRG 38",
|
||||||
|
["H_FRG_39"] = "H FRG 39",
|
||||||
|
["H_FRG_40"] = "H FRG 40",
|
||||||
|
["H_FRG_41"] = "H FRG 41",
|
||||||
|
["H_FRG_42"] = "H FRG 42",
|
||||||
|
["H_FRG_43"] = "H FRG 43",
|
||||||
|
["H_FRG_44"] = "H FRG 44",
|
||||||
|
["H_FRG_45"] = "H FRG 45",
|
||||||
|
["H_FRG_46"] = "H FRG 46",
|
||||||
|
["H_FRG_47"] = "H FRG 47",
|
||||||
|
["H_FRG_48"] = "H FRG 48",
|
||||||
|
["H_FRG_49"] = "H FRG 49",
|
||||||
|
["H_FRG_50"] = "H FRG 50",
|
||||||
|
["H_FRG_51"] = "H FRG 51",
|
||||||
|
["H_GDR_01"] = "H GDR 01",
|
||||||
|
["H_GDR_02"] = "H GDR 02",
|
||||||
|
["H_GDR_03"] = "H GDR 03",
|
||||||
|
["H_GDR_04"] = "H GDR 04",
|
||||||
|
["H_GDR_05"] = "H GDR 05",
|
||||||
|
["H_GDR_06"] = "H GDR 06",
|
||||||
|
["H_GDR_07"] = "H GDR 07",
|
||||||
|
["H_GDR_08"] = "H GDR 08",
|
||||||
|
["H_GDR_09"] = "H GDR 09",
|
||||||
|
["H_GDR_10"] = "H GDR 10",
|
||||||
|
["H_GDR_11"] = "H GDR 11",
|
||||||
|
["H_GDR_12"] = "H GDR 12",
|
||||||
|
["H_GDR_13"] = "H GDR 13",
|
||||||
|
["H_GDR_14"] = "H GDR 14",
|
||||||
|
["H_GDR_15"] = "H GDR 15",
|
||||||
|
["H_GDR_16"] = "H GDR 16",
|
||||||
|
["H_GDR_17"] = "H GDR 17",
|
||||||
|
["H_GDR_18"] = "H GDR 18",
|
||||||
|
["H_GDR_19"] = "H GDR 19",
|
||||||
|
["H_GDR_21"] = "H GDR 21",
|
||||||
|
["H_GDR_22"] = "H GDR 22",
|
||||||
|
["H_GDR_24"] = "H GDR 24",
|
||||||
|
["H_GDR_25"] = "H GDR 25",
|
||||||
|
["H_GDR_26"] = "H GDR 26",
|
||||||
|
["H_GDR_30"] = "H GDR 30",
|
||||||
|
["H_GDR_31"] = "H GDR 31",
|
||||||
|
["H_GDR_32"] = "H GDR 32",
|
||||||
|
["H_GDR_33"] = "H GDR 33",
|
||||||
|
["H_GDR_34"] = "H GDR 34",
|
||||||
|
["H_Med_FRG_01"] = "H Med FRG 01",
|
||||||
|
["H_Med_FRG_02"] = "H Med FRG 02",
|
||||||
|
["H_Med_FRG_04"] = "H Med FRG 04",
|
||||||
|
["H_Med_FRG_06"] = "H Med FRG 06",
|
||||||
|
["H_Med_FRG_11"] = "H Med FRG 11",
|
||||||
|
["H_Med_FRG_12"] = "H Med FRG 12",
|
||||||
|
["H_Med_FRG_13"] = "H Med FRG 13",
|
||||||
|
["H_Med_FRG_14"] = "H Med FRG 14",
|
||||||
|
["H_Med_FRG_15"] = "H Med FRG 15",
|
||||||
|
["H_Med_FRG_16"] = "H Med FRG 16",
|
||||||
|
["H_Med_FRG_17"] = "H Med FRG 17",
|
||||||
|
["H_Med_FRG_21"] = "H Med FRG 21",
|
||||||
|
["H_Med_FRG_24"] = "H Med FRG 24",
|
||||||
|
["H_Med_FRG_26"] = "H Med FRG 26",
|
||||||
|
["H_Med_FRG_27"] = "H Med FRG 27",
|
||||||
|
["H_Med_FRG_29"] = "H Med FRG 29",
|
||||||
|
["H_Med_GDR_01"] = "H Med GDR 01",
|
||||||
|
["H_Med_GDR_02"] = "H Med GDR 02",
|
||||||
|
["H_Med_GDR_03"] = "H Med GDR 03",
|
||||||
|
["H_Med_GDR_08"] = "H Med GDR 08",
|
||||||
|
["H_Med_GDR_09"] = "H Med GDR 09",
|
||||||
|
["H_Med_GDR_10"] = "H Med GDR 10",
|
||||||
|
["H_Med_GDR_11"] = "H Med GDR 11",
|
||||||
|
["H_Med_GDR_12"] = "H Med GDR 12",
|
||||||
|
["H_Med_GDR_13"] = "H Med GDR 13",
|
||||||
|
["H_Med_GDR_14"] = "H Med GDR 14",
|
||||||
|
["H_Med_GDR_16"] = "H Med GDR 16",
|
||||||
|
["H_Radar_FRG_02"] = "H Radar FRG 02",
|
||||||
|
["H_Radar_GDR_01"] = "H Radar GDR 01",
|
||||||
|
["H_Radar_GDR_02"] = "H Radar GDR 02",
|
||||||
|
["H_Radar_GDR_03"] = "H Radar GDR 03",
|
||||||
|
["H_Radar_GDR_04"] = "H Radar GDR 04",
|
||||||
|
["H_Radar_GDR_05"] = "H Radar GDR 05",
|
||||||
|
["H_Radar_GDR_06"] = "H Radar GDR 06",
|
||||||
|
["H_Radar_GDR_07"] = "H Radar GDR 07",
|
||||||
|
["H_Radar_GDR_08"] = "H Radar GDR 08",
|
||||||
|
["H_Radar_GDR_09"] = "H Radar GDR 09",
|
||||||
|
["Hahn"] = "Hahn",
|
||||||
|
["Haina"] = "Haina",
|
||||||
|
["Hamburg"] = "Hamburg",
|
||||||
|
["Hamburg_Finkenwerder"] = "Hamburg Finkenwerder",
|
||||||
|
["Hannover"] = "Hannover",
|
||||||
|
["Hasselfelde"] = "Hasselfelde",
|
||||||
|
["Herrenteich"] = "Herrenteich",
|
||||||
|
["Hildesheim"] = "Hildesheim",
|
||||||
|
["Hockenheim"] = "Hockenheim",
|
||||||
|
["Holzdorf"] = "Holzdorf",
|
||||||
|
["Kammermark"] = "Kammermark",
|
||||||
|
["Koethen"] = "Kothen",
|
||||||
|
["Laage"] = "Laage",
|
||||||
|
["Langenselbold"] = "Langenselbold",
|
||||||
|
["Laerz"] = "Larz",
|
||||||
|
["Leipzig_Halle"] = "Leipzig Halle",
|
||||||
|
["Leipzig_Mockau"] = "Leipzig Mockau",
|
||||||
|
["Luebeck"] = "Lubeck",
|
||||||
|
["Lueneburg"] = "Luneburg",
|
||||||
|
["Mahlwinkel"] = "Mahlwinkel",
|
||||||
|
["Mendig"] = "Mendig",
|
||||||
|
["Merseburg"] = "Merseburg",
|
||||||
|
["Neubrandenburg"] = "Neubrandenburg",
|
||||||
|
["Neuruppin"] = "Neuruppin",
|
||||||
|
["Northeim"] = "Northeim",
|
||||||
|
["Ober_Moerlen"] = "Ober-Morlen",
|
||||||
|
["Obermehler_Schlotheim"] = "Obermehler Schlotheim",
|
||||||
|
["Parchim"] = "Parchim",
|
||||||
|
["Peenemuende"] = "Peenemunde",
|
||||||
|
["Pferdsfeld"] = "Pferdsfeld",
|
||||||
|
["Pinnow"] = "Pinnow",
|
||||||
|
["Pottschutthoehe"] = "Pottschutthohe",
|
||||||
|
["Ramstein"] = "Ramstein",
|
||||||
|
["Rinteln"] = "Rinteln",
|
||||||
|
["Schoenefeld"] = "Schonefeld",
|
||||||
|
["Schweinfurt"] = "Schweinfurt",
|
||||||
|
["Sembach"] = "Sembach",
|
||||||
|
["Spangdahlem"] = "Spangdahlem",
|
||||||
|
["Sperenberg"] = "Sperenberg",
|
||||||
|
["Stendal"] = "Stendal",
|
||||||
|
["Tegel"] = "Tegel",
|
||||||
|
["Tempelhof"] = "Tempelhof",
|
||||||
|
["Templin"] = "Templin",
|
||||||
|
["Tutow"] = "Tutow",
|
||||||
|
["Uelzen"] = "Uelzen",
|
||||||
|
["Uetersen"] = "Uetersen",
|
||||||
|
["Ummern"] = "Ummern",
|
||||||
|
["Verden_Scharnhorst"] = "Verden-Scharnhorst",
|
||||||
|
["Walldorf"] = "Walldorf",
|
||||||
|
["Waren_Vielist"] = "Waren Vielist",
|
||||||
|
["Werneuchen"] = "Werneuchen",
|
||||||
|
["Weser_Wuemme"] = "Weser Wumme",
|
||||||
|
["Wiesbaden"] = "Wiesbaden",
|
||||||
|
["Wismar"] = "Wismar",
|
||||||
|
["Wittstock"] = "Wittstock",
|
||||||
|
["Worms"] = "Worms",
|
||||||
|
["Wunstorf"] = "Wunstorf",
|
||||||
|
["Zerbst"] = "Zerbst",
|
||||||
|
["Zweibruecken"] = "Zweibrucken",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
||||||
-- @type AIRBASE.ParkingSpot
|
-- @type AIRBASE.ParkingSpot
|
||||||
-- @field Core.Point#COORDINATE Coordinate Coordinate of the parking spot.
|
-- @field Core.Point#COORDINATE Coordinate Coordinate of the parking spot.
|
||||||
@@ -922,11 +1365,12 @@ AIRBASE.Iraq = {
|
|||||||
-- @field #number HelicopterOnly 40: Special spots for Helicopers.
|
-- @field #number HelicopterOnly 40: Special spots for Helicopers.
|
||||||
-- @field #number Shelter 68: Hardened Air Shelter. Currently only on Caucaus map.
|
-- @field #number Shelter 68: Hardened Air Shelter. Currently only on Caucaus map.
|
||||||
-- @field #number OpenMed 72: Open/Shelter air airplane only.
|
-- @field #number OpenMed 72: Open/Shelter air airplane only.
|
||||||
|
-- @field #number SmallSizeFigher 100: Tight spots for smaller type fixed wing aircraft, like the F-16. Example of these spots: 04, 05, 06 on Muwaffaq_Salti. A Viper sized plane can spawn here, but an A-10 or Strike Eagle can't
|
||||||
-- @field #number OpenBig 104: Open air spawn points. Generally larger but does not guarantee large aircraft are capable of spawning there.
|
-- @field #number OpenBig 104: Open air spawn points. Generally larger but does not guarantee large aircraft are capable of spawning there.
|
||||||
-- @field #number OpenMedOrBig 176: Combines OpenMed and OpenBig spots.
|
-- @field #number OpenMedOrBig 176: Combines OpenMed and OpenBig spots.
|
||||||
-- @field #number HelicopterUsable 216: Combines HelicopterOnly, OpenMed and OpenBig.
|
-- @field #number HelicopterUsable 216: Combines HelicopterOnly, OpenMed and OpenBig.
|
||||||
-- @field #number FighterAircraft 244: Combines Shelter. OpenMed and OpenBig spots. So effectively all spots usable by fixed wing aircraft.
|
-- @field #number FighterAircraft 244: Combines Shelter, OpenMed and OpenBig spots. So effectively all spots usable by fixed wing aircraft.
|
||||||
-- @field #number SmallSizeFigher 100: Tight spots for smaller type fixed wing aircraft, like the F-16. Example of these spots: 04, 05, 06 on Muwaffaq_Salti. A Viper sized plane can spawn here, but an A-10 or Strike Eagle can't
|
-- @field #number FighterAircraftSmall 344: Combines Shelter, SmallsizeFighter, OpenMed and OpenBig spots. So effectively all spots usable by small fixed wing aircraft.
|
||||||
AIRBASE.TerminalType = {
|
AIRBASE.TerminalType = {
|
||||||
Runway=16,
|
Runway=16,
|
||||||
HelicopterOnly=40,
|
HelicopterOnly=40,
|
||||||
@@ -937,6 +1381,7 @@ AIRBASE.TerminalType = {
|
|||||||
OpenMedOrBig=176,
|
OpenMedOrBig=176,
|
||||||
HelicopterUsable=216,
|
HelicopterUsable=216,
|
||||||
FighterAircraft=244,
|
FighterAircraft=244,
|
||||||
|
FighterAircraftSmall=344,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Status of a parking spot.
|
--- Status of a parking spot.
|
||||||
@@ -988,7 +1433,7 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
--self:I({airbase=AirbaseName, descriptors=self.descriptors})
|
--self:I({airbase=AirbaseName, descriptors=self.descriptors})
|
||||||
|
|
||||||
-- Category.
|
-- Category.
|
||||||
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
||||||
|
|
||||||
@@ -1003,6 +1448,7 @@ if self.category==Airbase.Category.AIRDROME then
|
|||||||
self.isAirdrome=true
|
self.isAirdrome=true
|
||||||
elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then
|
elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then
|
||||||
self.isHelipad=true
|
self.isHelipad=true
|
||||||
|
self.category=Airbase.Category.HELIPAD
|
||||||
elseif self.category==Airbase.Category.SHIP then
|
elseif self.category==Airbase.Category.SHIP then
|
||||||
self.isShip=true
|
self.isShip=true
|
||||||
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
||||||
@@ -1018,21 +1464,35 @@ end
|
|||||||
|
|
||||||
-- Init Runways.
|
-- Init Runways.
|
||||||
self:_InitRunways()
|
self:_InitRunways()
|
||||||
|
|
||||||
|
-- Number of runways
|
||||||
|
local Nrunways=#self.runways
|
||||||
|
|
||||||
-- Set the active runways based on wind direction.
|
-- Set the active runways based on wind direction.
|
||||||
if self.isAirdrome then
|
if Nrunways>0 then
|
||||||
self:SetActiveRunway()
|
self:SetActiveRunway()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Init parking spots.
|
-- Init parking spots.
|
||||||
self:_InitParkingSpots()
|
self:_InitParkingSpots()
|
||||||
|
|
||||||
|
-- Some heliports identify as airdromes in the airbase category. This is buggy in the descriptors category but also in the getCategory() and getCategoryEx() functions.
|
||||||
|
-- Well, thinking about it, this is actually not that "buggy" since these are really helicopter airdromes, which do not have an automatic parking spot routine.
|
||||||
|
-- I am still changing the category but marking it as airdrome and heliport at the same time via isAirdrome=true and isHelipad=true (important in SPAWN.SpawnAtAirbase).
|
||||||
|
-- The main reason for changing the category is to be able to filter airdromes from helipads, e.g. in SET_AIRBASE.
|
||||||
|
if self.category==Airbase.Category.AIRDROME and (Nrunways==0 or self.NparkingTotal==self.NparkingTerminal[AIRBASE.TerminalType.HelicopterOnly]) then
|
||||||
|
--self:E(string.format("WARNING: %s identifies as airdrome (category=0) but has no runways or just helo parking ==> will change to helipad (category=1)", self.AirbaseName))
|
||||||
|
self.category=Airbase.Category.HELIPAD
|
||||||
|
self.isAirdrome=true
|
||||||
|
self.isHelipad=true
|
||||||
|
end
|
||||||
|
|
||||||
-- Get 2D position vector.
|
-- Get 2D position vector.
|
||||||
local vec2=self:GetVec2()
|
local vec2=self:GetVec2()
|
||||||
|
|
||||||
-- Init coordinate.
|
-- Init coordinate.
|
||||||
self:GetCoordinate()
|
self:GetCoordinate()
|
||||||
|
|
||||||
-- Storage.
|
-- Storage.
|
||||||
self.storage=_DATABASE:AddStorage(AirbaseName)
|
self.storage=_DATABASE:AddStorage(AirbaseName)
|
||||||
|
|
||||||
@@ -1055,6 +1515,46 @@ end
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the category of this airbase. This is only a debug function because DCS 2.9 incorrectly returns heliports as airdromes.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
function AIRBASE:_GetCategory()
|
||||||
|
|
||||||
|
local name=self.AirbaseName
|
||||||
|
|
||||||
|
local static=StaticObject.getByName(name)
|
||||||
|
local airbase=Airbase.getByName(name)
|
||||||
|
local unit=Unit.getByName(name)
|
||||||
|
|
||||||
|
local text=string.format("\n=====================================================")
|
||||||
|
text=text..string.format("\nAirbase %s:", name)
|
||||||
|
if static then
|
||||||
|
local oc, uc=static:getCategory()
|
||||||
|
local ex=static:getCategoryEx()
|
||||||
|
text=text..string.format("\nSTATIC: oc=%d, uc=%d, ex=%d", oc, uc, ex)
|
||||||
|
--text=text..UTILS.PrintTableToLog(static:getDesc(), nil, true)
|
||||||
|
text=text..string.format("\n--------------------------------------------------")
|
||||||
|
end
|
||||||
|
if unit then
|
||||||
|
local oc, uc=unit:getCategory()
|
||||||
|
local ex=unit:getCategoryEx()
|
||||||
|
text=text..string.format("\nUNIT: oc=%d, uc=%d, ex=%d", oc, uc, ex)
|
||||||
|
--text=text..UTILS.PrintTableToLog(unit:getDesc(), nil, true)
|
||||||
|
text=text..string.format("\n--------------------------------------------------")
|
||||||
|
end
|
||||||
|
if airbase then
|
||||||
|
local oc, uc=airbase:getCategory()
|
||||||
|
local ex=airbase:getCategoryEx()
|
||||||
|
text=text..string.format("\nAIRBASE: oc=%d, uc=%d, ex=%d", oc, uc, ex)
|
||||||
|
text=text..string.format("\n--------------------------------------------------")
|
||||||
|
text=text..UTILS.PrintTableToLog(airbase:getDesc(), nil, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
text=text..string.format("\n=====================================================")
|
||||||
|
|
||||||
|
|
||||||
|
env.info(text)
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Reference methods
|
-- Reference methods
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -1578,7 +2078,7 @@ function AIRBASE:_InitParkingSpots()
|
|||||||
self.NparkingTotal=self.NparkingTotal+1
|
self.NparkingTotal=self.NparkingTotal+1
|
||||||
|
|
||||||
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
||||||
if self._CheckTerminalType(terminalType, park.TerminalType) then
|
if self._CheckTerminalType(park.TerminalType, terminalType) then
|
||||||
self.NparkingTerminal[terminalType]=self.NparkingTerminal[terminalType]+1
|
self.NparkingTerminal[terminalType]=self.NparkingTerminal[terminalType]+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1586,6 +2086,9 @@ function AIRBASE:_InitParkingSpots()
|
|||||||
self.parkingByID[park.TerminalID]=park
|
self.parkingByID[park.TerminalID]=park
|
||||||
table.insert(self.parking, park)
|
table.insert(self.parking, park)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Runways are not included in total number of parking spots
|
||||||
|
self.NparkingTotal=self.NparkingTotal-self.NparkingTerminal[AIRBASE.TerminalType.Runway]
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -2009,9 +2512,13 @@ function AIRBASE._CheckTerminalType(Term_Type, termtype)
|
|||||||
match=true
|
match=true
|
||||||
end
|
end
|
||||||
elseif termtype==AIRBASE.TerminalType.FighterAircraft then
|
elseif termtype==AIRBASE.TerminalType.FighterAircraft then
|
||||||
if Term_Type==AIRBASE.TerminalType.OpenMed or Term_Type==AIRBASE.TerminalType.OpenBig or Term_Type==AIRBASE.TerminalType.Shelter or Term_Type==AIRBASE.TerminalType.SmallSizeFighter then
|
if Term_Type==AIRBASE.TerminalType.OpenMed or Term_Type==AIRBASE.TerminalType.OpenBig or Term_Type==AIRBASE.TerminalType.Shelter then
|
||||||
match=true
|
match=true
|
||||||
end
|
end
|
||||||
|
elseif termtype==AIRBASE.TerminalType.FighterAircraftSmall then
|
||||||
|
if Term_Type==AIRBASE.TerminalType.OpenMed or Term_Type==AIRBASE.TerminalType.OpenBig or Term_Type==AIRBASE.TerminalType.Shelter or Term_Type==AIRBASE.TerminalType.SmallSizeFighter then
|
||||||
|
match=true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return match
|
return match
|
||||||
@@ -2044,7 +2551,7 @@ function AIRBASE:GetRunwayByName(Name)
|
|||||||
|
|
||||||
-- Name including L or R, e.g. "31L".
|
-- Name including L or R, e.g. "31L".
|
||||||
local name=self:GetRunwayName(runway)
|
local name=self:GetRunwayName(runway)
|
||||||
|
self:T("Check Runway Name: "..name)
|
||||||
if name==Name:upper() then
|
if name==Name:upper() then
|
||||||
return runway
|
return runway
|
||||||
end
|
end
|
||||||
@@ -2069,14 +2576,9 @@ function AIRBASE:_InitRunways(IncludeInverse)
|
|||||||
-- Runway table.
|
-- Runway table.
|
||||||
local Runways={}
|
local Runways={}
|
||||||
|
|
||||||
if self:GetAirbaseCategory()~=Airbase.Category.AIRDROME then
|
|
||||||
self.runways={}
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Function to create a runway data table.
|
--- Function to create a runway data table.
|
||||||
local function _createRunway(name, course, width, length, center)
|
local function _createRunway(name, course, width, length, center)
|
||||||
|
self:T("Create Runway: name = "..name)
|
||||||
-- Bearing in rad.
|
-- Bearing in rad.
|
||||||
local bearing=-1*course
|
local bearing=-1*course
|
||||||
|
|
||||||
@@ -2092,6 +2594,7 @@ function AIRBASE:_InitRunways(IncludeInverse)
|
|||||||
runway.name=string.format("%02d", tonumber(namefromheading))
|
runway.name=string.format("%02d", tonumber(namefromheading))
|
||||||
else
|
else
|
||||||
runway.name=string.format("%02d", tonumber(name))
|
runway.name=string.format("%02d", tonumber(name))
|
||||||
|
--self:I("RunwayName: "..runway.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
--runway.name=string.format("%02d", tonumber(name))
|
--runway.name=string.format("%02d", tonumber(name))
|
||||||
@@ -2159,7 +2662,7 @@ function AIRBASE:_InitRunways(IncludeInverse)
|
|||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T2(runways)
|
self:T2(runways)
|
||||||
|
|
||||||
if runways then
|
if runways and #runways>0 then
|
||||||
|
|
||||||
-- Loop over runways.
|
-- Loop over runways.
|
||||||
for _,rwy in pairs(runways) do
|
for _,rwy in pairs(runways) do
|
||||||
@@ -2192,6 +2695,12 @@ function AIRBASE:_InitRunways(IncludeInverse)
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- No runways
|
||||||
|
self.runways={}
|
||||||
|
return {}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2407,7 +2916,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
runway.endpoint=c2
|
runway.endpoint=c2
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
--self:I(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m i=%d j=%d", self:GetName(), runway.idx, runway.heading, runway.length, i, j))
|
self:T(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m i=%d j=%d", self:GetName(), runway.idx, runway.heading, runway.length, i, j))
|
||||||
|
|
||||||
-- Debug mark
|
-- Debug mark
|
||||||
if mark then
|
if mark then
|
||||||
@@ -2534,8 +3043,8 @@ function AIRBASE:GetRunwayIntoWind(PreferLeft)
|
|||||||
|
|
||||||
-- Loop over runways.
|
-- Loop over runways.
|
||||||
local dotmin=nil
|
local dotmin=nil
|
||||||
for i,_runway in pairs(runways) do
|
for i ,_runway in pairs(runways) do
|
||||||
local runway=_runway --#AIRBASE.Runway
|
local runway=_runway --#AIRBASE.Runway
|
||||||
|
|
||||||
if PreferLeft==nil or PreferLeft==runway.isLeft then
|
if PreferLeft==nil or PreferLeft==runway.isLeft then
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user